PDF creation issue
-
Hi there,
every now and then someone complains about PDF Creation - now I am one of them (maybe not the first time).
This time my issue is twofold:- PDF output is so much different then the html it was created with and
- it differes from PC to PC ...
If someone wants to take a look: https://github.com/Schachigel/QtPdfHtmlTest
But I will have most of the code also here: How I create a pdf and an html file from a given html and a css file:
const QString html =fileToString ("../in.html"); const QString css =fileToString( "../in.css"); QPrinter printer; // set A4 QPageLayout pl =printer.pageLayout (); pl.setPageSize (QPageSize(QPageSize::A4)); printer.setPageLayout (pl); QTextDocument doc; // adjust to printer pagesizse doc.setPageSize (pl.pageSize ().size (QPageSize::Unit::Point)); doc.setDefaultStyleSheet (css); doc.setHtml (html); printer.setOutputFileName ("../out.pdf"); doc.print(&printer); stringToFile (doc.toHtml (), "../out.html");
My sample css and html:
body { width:210mm; height:297mm; font-size: 9pt; font-family: Verdana, Geneva, Tahoma, sans-serif; } .C1 { font-size: 7pt; } .C2 { font-size: 10pt; } .C3 { font-size: 14pt; } .C4 { font-size: 28pt; }
<head> <link rel="stylesheet" href="in.css"> </head> <body> Normal Text <small>Small text</small> <br> <div class="C1">Seven Point is pretty small <br> </div> <div class="C2">Ten Point is close to normal size <br> </div> <div class="C3">Fourteen Point - like headline <br> </div> <div class="C4">HUGE Point size<br></div> </body>
How the original and the created html in a browser look:
How the pdf looks:
Font sizes are quite off - and even more the spacing. As if there was a paragraph everywhere!
Thank you for having a look!
PS: my qt version is 5.15.2 on Windows. I thried this on 2 computers. The outcome differs - which is a problem on its own - but is bad on both. Same symptoms. -
QTextDocument accepts a limited subset of HTML, probably only a well-formed example, converts it to an equivalent internal structure and is not guaranteed to render this precisely the same way as any browser.
The HTML 4 specification says of DIV elements that, "Visual user agents generally place a line break before and after DIV elements, ..." Your markup is specifically inserting a line break, and the DIV (block) element may be triggering another. If you inspect the text document structure you might find extra, empty blocks in the result after import.
The font may vary from machine to machine because of what fonts are available and whether any are subject to aliasing/substitution. Your markup allows the rendering engine to choose an available font matching one of four options and, as on the web, the result may differ by consumer. On a standard Windows 8, 10, or 11 box you should find Verdana or Tahoma, but the fonts themselves have changed between these Windows versions.
HTML is not a page description language. If you want better control then use QTextDocument directly to construct the document. If you want a more browser-like result then use a browser component and render it from there.
-
Thx Chris - that is a great answer and it will take some time to work me through ;)
Your last advice ...
HTML is not a page description language. If you want better control then use QTextDocument directly to construct the document. If you want a more browser-like result then use a browser component and render it from there.
is so true! However - do you know any alternatives? My aim is to create letters in my qt app. They are made from some html templates wihch are "enriched" by some database data (using Mustache). With html templates I can give (limited) freedom to the user, to change the layout. If I do it on the QTextDocument everything is hard coded (or very complicated to implement).
best regards -
There is Qt WebEngine, specifically QWebEnginePage::printToPdf().
This example may help: WebEngine Widgets Html2Pdf Example -
There is Qt WebEngine, specifically QWebEnginePage::printToPdf().
This example may help: WebEngine Widgets Html2Pdf Example -
@JonB good hint - thank you. Fortunately I use MSVC. I guess the WebEnginge is available on Linux and Mac? I will definitly give it a shot - even so I am afraight, that this will be a big junk of additional software to install and memory to use - just for the printing.
But if it solves the other issues. ... hard disks and memory have become cheap ;) -
@JonB good hint - thank you. Fortunately I use MSVC. I guess the WebEnginge is available on Linux and Mac? I will definitly give it a shot - even so I am afraight, that this will be a big junk of additional software to install and memory to use - just for the printing.
But if it solves the other issues. ... hard disks and memory have become cheap ;) -
the example app of WebEngine to create PDFs from HTML has > 230 mb of dependencies (created with WinDeployqt) - hat is heavy! Maybe this is too much to be added to my 40 or so mb application :(
But the results seem to look better then with QTextDocument ...