Skip to content Skip to sidebar Skip to footer

Pdf Image In Pdf Document Using Reportlab (python)

I saved some plots from matplotlib into a pdf format because it seems to offer a better quality. How do I include the PDF image into a PDF document using ReportLab? The convenience

Solution 1:

You can use the wonderful pdfrw package together with reportlab and use it to pass file-like objects of matplotlib figures directly into a flowable:

This was answered before, but I want to give a minimal example here, please also look here: https://stackoverflow.com/a/13870512/4497962

from io import BytesIO
import matplotlib.pyplot as plt
from pdfrw import PdfReader, PdfDict
from pdfrw.buildxobj import pagexobj
from pdfrw.toreportlab import makerl
from reportlab.platypus import Flowable
from reportlab.lib.enums import TA_JUSTIFY,TA_LEFT,TA_CENTER,TA_RIGHT

classPdfImage(Flowable):
    """
    PdfImage wraps the first page from a PDF file as a Flowable
    which can be included into a ReportLab Platypus document.
    Based on the vectorpdf extension in rst2pdf (http://code.google.com/p/rst2pdf/)

    This can be used from the place where you want to return your matplotlib image
    as a Flowable:

        img = BytesIO()

        fig, ax = plt.subplots(figsize=(canvaswidth,canvaswidth))

        ax.plot([1,2,3],[6,5,4],antialiased=True,linewidth=2,color='red',label='a curve')

        fig.savefig(img,format='PDF')

        return(PdfImage(img))

    """def__init__(self, filename_or_object, width=None, height=None, kind='direct'):
        # If using StringIO buffer, set pointer to beginingifhasattr(filename_or_object, 'read'):
            filename_or_object.seek(0)
            #print("read")
        self.page = PdfReader(filename_or_object, decompress=False).pages[0]
        self.xobj = pagexobj(self.page)

        self.imageWidth = width
        self.imageHeight = height
        x1, y1, x2, y2 = self.xobj.BBox

        self._w, self._h = x2 - x1, y2 - y1
        ifnot self.imageWidth:
            self.imageWidth = self._w
        ifnot self.imageHeight:
            self.imageHeight = self._h
        self.__ratio = float(self.imageWidth)/self.imageHeight
        if kind in ['direct','absolute'] or width==Noneor height==None:
            self.drawWidth = width or self.imageWidth
            self.drawHeight = height or self.imageHeight
        elif kind in ['bound','proportional']:
            factor = min(float(width)/self._w,float(height)/self._h)
            self.drawWidth = self._w*factor
            self.drawHeight = self._h*factor

    defwrap(self, availableWidth, availableHeight):
        """
        returns draw- width and height

        convenience function to adapt your image 
        to the available Space that is available
        """return self.drawWidth, self.drawHeight

    defdrawOn(self, canv, x, y, _sW=0):
        """
        translates Bounding Box and scales the given canvas
        """if _sW > 0andhasattr(self, 'hAlign'):
            a = self.hAlign
            if a in ('CENTER', 'CENTRE', TA_CENTER):
                x += 0.5*_sW
            elif a in ('RIGHT', TA_RIGHT):
                x += _sW
            elif a notin ('LEFT', TA_LEFT):
                raise ValueError("Bad hAlign value " + str(a))

        #xobj_name = makerl(canv._doc, self.xobj)
        xobj_name = makerl(canv, self.xobj)

        xscale = self.drawWidth/self._w
        yscale = self.drawHeight/self._h

        x -= self.xobj.BBox[0] * xscale
        y -= self.xobj.BBox[1] * yscale

        canv.saveState()
        canv.translate(x, y)
        canv.scale(xscale, yscale)
        canv.doForm(xobj_name)
        canv.restoreState()

Solution 2:

According to ReportLab's FAQ this is only possible with ReportLab PLUS:

Can I use vector graphics in my PDFs?

No, the Open Source package doesn't do this. PageCatcher (see the previous answer) allows you to easily incorporate any vector image by saving it as a PDF and then using it exactly as you would an image file, and Report Markup Language accepts PDF files along with JPG, GIF and PNG.

Update: I haven't looked into this for a while but on the page of pdfrw it says:

pdfrw can read and write PDF files, and can also be used to read in PDFs which can then be used inside reportlab.

Solution 3:

You can use svg export from matplotlib and use svglib python library to include vector graphics in reportlab generated PDF files. svglib takes a svg file and makes a drawing object that can be directly used in reportlab.

See also this question for more details: Generating PDFs from SVG input

Solution 4:

Use from reportlab.graphics import renderPDF

Post a Comment for "Pdf Image In Pdf Document Using Reportlab (python)"