[PyQt] Paginated PDF rendering

Tim Wakeham tim at tjwakeham.com
Mon Sep 13 03:56:49 BST 2010


Hi all,

I've been attempting to implement a PDF printer based on the code here
http://www.mail-archive.com/pyqt@riverbankcomputing.com/msg18928.html

I need pagination though so I've attempted to move regions to take into
account rendering one page at a time.  This works great for the first page,
but the rest of the pages seem to be offset down the pdf page according to
where the region on the html page is.  I'm unsure how to compensate for
that, any ideas?  code is below.

-- Tim

import sys

from PyQt4 import QtCore
from PyQt4 import QtGui
from PyQt4.QtGui import QRegion
from PyQt4.QtCore import QObject
from PyQt4.QtCore import QUrl
from PyQt4.QtCore import QSizeF, QSize
from PyQt4.QtCore import SIGNAL
from PyQt4.QtGui import QPainter
from PyQt4.QtGui import QPrinter
from PyQt4.QtGui import QImage
from PyQt4 import QtWebKit

class WebKitPDF ( QObject ):

  def __init__ ( self, url, dest ):
    QObject.__init__ ( self )
    self.dest = dest
    self.page = QtWebKit.QWebPage ( self )
    self.mainFrame = self.page.mainFrame()
    self.mainFrame.load ( QUrl ( url ) )

    self.connect ( self.page,
             SIGNAL ( "loadProgress(int)" ),
             self.loadProgress )

    self.connect ( self.page,
             SIGNAL ( "loadFinished(bool)" ),
             self.renderPDF )



  def loadProgress ( self, progress ):
    print "Progress: ", progress


  def renderPDF ( self, status ):
    print "Load finished with status: ", status
    print "Rendering PDF ..."

    contentsSize = self.mainFrame.contentsSize()
    print contentsSize, QSize(contentsSize.width(), 800)
    self.page.setViewportSize ( QSize(600, contentsSize.height() ) )

    pages = contentsSize.height() / 1059
    
    #self.printer = QPrinter ( QPrinter.HighResolution )
    self.printer = QPrinter ( QPrinter.ScreenResolution )
    self.printer.setOutputFormat ( QPrinter.PdfFormat )
    self.printer.setPaperSize ( QPrinter.A4 )

    self.printer.setPageMargins(32, 32, 32, 32, QPrinter.DevicePixel)
    self.printer.setFullPage( True )
    #self.printer.setPaperSize ( QSizeF( contentsSize ),
QPrinter.DevicePixel )
    self.printer.setOrientation ( QPrinter.Portrait )
    self.printer.setOutputFileName ( self.dest )

    self.painter = QPainter ( self.printer )
    self.painter.translate(96.0, 24.0)
    self.painter.setRenderHint ( QPainter.Antialiasing )

    region = QRegion( 0, 0, 729, 1059)
    for page in range(pages):
        self.painter.setClipRegion( region )
        self.mainFrame.render ( self.painter )
        self.printer.newPage()
        region.translate(0, 1059)
        
    self.painter.end()
    app = QtGui.QApplication.instance()
    app.exit ( 0 )
    
    

def main( url, dest ):
  app = QtGui.QApplication ( sys.argv )
  wk = WebKitPDF ( url, dest )
  sys.exit ( app.exec_() )



main( 'http://127.0.0.1:8000/purchase/recv_report?id=23', 'c:\\report2.pdf')



More information about the PyQt mailing list