I want to create a PDF document with properly styled HTML. This is what I am trying:
QTextDocument *doc = new QTextDocument();
const char* s1 = "<html><head><style>body { font-family: sans-serif;}.note-atomic { background: rgb(242,242,242); width: 1000px; margin: 5px auto; border: 1px solid grey; border-radius: 8px;padding: 5px;}</style></head><body><div class = 'note-atomic'>Hi</div><img src = '/Users/attitude/Desktop/RnSghvV.png' width='400' height='300' /></body></html>";
doc->setHtml(QString::fromStdString(s1));
QPrinter *printer = new QPrinter();
printer->setOutputFileName("/Users/attitude/Desktop/fool.pdf");
printer->setOutputFormat(QPrinter::PdfFormat);
QPainter *painter = new QPainter();
painter->begin( printer );
doc->drawContents(painter, printer->pageRect().translated( -printer->pageRect().x(), - printer->pageRect().y() ));
doc->print(printer);
const char* s2 = "<html><body><div>Bye</div></body></html>";
doc->setHtml(QString::fromStdString(s2));
printer->newPage();
doc->drawContents(painter, printer->pageRect().translated( -printer->pageRect().x(), - printer->pageRect().y() ));
doc->print(printer);
painter->end();
I expect the PDF to have 2 pages - first one with text Hi, and the next and last one with text Bye. And the first page styled like it appears in a HTML page with the same markup:
However, the first page of the PDF comes up with content completely messed up:
How do I make it look as expected?
The image I am trying in the HTML doc: http://imgur.com/RnSghvV
Platform - Qt 5.3.1, 32 bit. OS X Yosemite.
This is QTextDocument
. It rendered rich text (it is not HTML + CSS).
Available properties and elements you may check on http://doc.qt.io/qt-5/richtext-html-subset.html (for example there is no css property border
for p
or div
).
Also you can see how it looks in Qt Designer, if you put your html code into QTextEdit
.
For rendering HTML you can use QWebView
(http://doc.qt.io/qt-5/qwebframe.html#print)
webview->mainFrame()->print(printer);
QTextDocument
is not a web browser. It won't go fetching networked URLs for you. You need to add a QVariant QTextDocument::loadResource(int type, const QUrl & name)
method to your QObject
(QWidget
is-a QObject
!), and make the QTextDocument
a child of that object. The document instance will the invoke your implementation of loadResource
, where you can leverage the QNetworkAccessManager
to do the fetching.
For this to have any chance of being user-friendly, you cannot block on network requests. This is accomplished by doing the processing twice. First simply take note of what URLs are to be loaded and initiate their fetching, returning an empty QVariant
. Once all network requests are completed successfully and you've stored them in a cache, you can re-run the same code and it'll correctly render the page and won't block for network access.
All of this has to be done asynchronously.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With