PDA

View Full Version : QPrinter print QWebView content without any any page break.



Cupidvogel
11th February 2016, 08:49
I have a HTML document which consists of a succession of divs, some of which may contain images. I want to export the document as pdf. For this I am using QPrinter and QWebView combination. It prints fine, but but pages are 'broken` at regular intervals, mostly whenever page is about to exceed A4 size. In contrast, say if I use phantomjs and rasterize.js combo, it prints out the entire HTML in one long single page in the PDF document.

How do I achieve the same in QPrinter as well? I tried adding media queries like page-break-inside: avoid, doesn't work.

anda_skoa
11th February 2016, 09:20
Are you currently using QWebView::print()?

Have you tried just rendering instead? I.e. QWebFrame::render()?

Cheers,
_

Cupidvogel
11th February 2016, 11:15
Not really. I have no use for QPainter. But nevertheless, I have fixed the problem. For anyone having the same problem, here is a solution. Define a script in your HEAD tags in the HTML content with getters for page height and width:



<script LANGUAGE="JavaScript">
function getHeight ()
{
return window.document.body.scrollHeight;
}
function getWidth ()
{
return window.document.body.scrollWidth;
}
</script>


Now in the code where you get the page content from the webview after loadFinished signal has been emitted, try this:



QWebView* view = dynamic_cast<QWebView *>(sender());
QVariant heightVariant = view->page()->mainFrame()->evaluateJavaScript("getHeight()");
QVariant widthVariant = view->page()->mainFrame()->evaluateJavaScript("getWidth()");
QPrinter *printer = new QPrinter();
printer->setOutputFileName("<path to pdf>");
printer->setOutputFormat(QPrinter::PdfFormat);
printer->setOrientation(QPrinter::Portrait);
printer->setPaperSize(QSize(widthVariant.toInt(),heightVari ant.toInt()),QPrinter::Point);
view->page()->mainFrame()->print(printer);


That solves the problem. :)

anda_skoa
11th February 2016, 12:55
Not really. I have no use for QPainter.

Not sure what you mean, you don't use QPainter yourself, but simpy hande it to render().

print() takes a QPrinter, so it knows that this is a paged device and will try to create a new page when the page size is reached.
It also is limited to QPrinter so you can't use QPdfWriter.

render() works on QPainter and doesn't care which paint device that works on, so it can't call "next page" and the paint device doesn't have to be a printer.

Cheers,
_

Cupidvogel
11th February 2016, 16:11
Oh okay, I did not think along those lines. I just saw the parameters include a QPainter object, and here I simply pass a HTML file to the QPrinter, so though it will not suit my needs.

Cupidvogel
11th February 2016, 21:45
While we are on this, is it possible to add table of contents in sidebar where each entry will point to a certain section in the pdf?

And secondly, is it possible to use an image as cover image which displays as thumbnail when the file is rendered on the desktop/Finder, instead of a condensed view of the entire document showing up as thumbnail image? The problem is that my content is extremely long, and like I said, rendered only in a single page, so the thumbnail becomes kind of ugly, like this:

11693

Whereas a nice cover image thumbnail, irrespective of content, would look like this :

11694

mclawest
21st May 2018, 00:51
(...) in the code where you get the page content from the webview after loadFinished signal has been emitted, try this:



QWebView* view = dynamic_cast<QWebView *>(sender());
QVariant heightVariant = view->page()->mainFrame()->evaluateJavaScript("getHeight()");
QVariant widthVariant = view->page()->mainFrame()->evaluateJavaScript("getWidth()");
QPrinter *printer = new QPrinter();
printer->setOutputFileName("<path to pdf>");
printer->setOutputFormat(QPrinter::PdfFormat);
printer->setOrientation(QPrinter::Portrait);
printer->setPaperSize(QSize(widthVariant.toInt(),heightVari ant.toInt()),QPrinter::Point);
view->page()->mainFrame()->print(printer);


That solves the problem. :)

Hey! Could you help me to convert this code to Python? First three lines a bit confusing for me.. All the rest is fine, I know how to do it.. but first three :confused:

UPDATE: well, no need in it, I've got it... But you wasn't fix it, yeah the rows and images are not breaks anymore, but the page is not breakes itself, so it is just a looong page in a height now....