Search code examples
pythonreportlab

I am trying to add a QrCode to my PDF but I am getting IOError


I am trying to add a QrCode to my PDF using Reportlab but I am getting an IOerror. I have successfully appended my barcode before but the QrCode seems to be a bit trickier.

This is my QrCode Code:

def get_QRcode(self,inventory):
    receipt = str(inventory.identifier)
    qr_code = qr.QrCodeWidget(receipt)
    bounds = qr_code.getBounds()
    width = bounds[2] - bounds[1]
    height = bounds[3] - bounds[1]
    d = Drawing(45,45, transform = [45./width,0,0,45./height,0,0])
    d.add(qr_code)
    filename = tempfile.mkstemp()[1] + '.png'
    d.save(filename)


    return filename

Here is my append of QrCode:

parts.append(Image(self.qrCode, width=.15* 0.35 *inch, height=.2*.25*inch))

After trying to run this I get :

IOError at /inventories/download_tag/2525/
Cannot open resource "/tmp/tmpUf7ASf.png"
fileName='/tmp/tmpUf7ASf.png' identity=[ImageReader@0x7f6665819490 filename='/tmp/tmpUf7ASf.png']

Any help is appreciated! Thank you

EDIT: Here is a snippet that appends my barcode and currently attempting to append a QRCode

def get_pdf_flows(self):
        sku = self.sku_name 
        sku =  sku + " ({0})".format(self.num_cases) if self.num_cases else sku
        sku = Paragraph(sku, self.sku_style)
        grower_detail = self.get_grower_detail()

        col1, col2 = self.get_table_rows()

        parts = []
        parts.append(Spacer(1, 30))
        parts.append(sku)
        parts.append(Spacer(1, 5))
        parts.append(Image(self.barcode_file, width=.15* 0.35 *inch, height=.2*.25*inch))
        parts.append(self.qrCode)
        parts.append(grower_detail)
        parts.append(Spacer(1, 5))
        t1 = Table(col1,colWidths='*')
        t2 = Table(col2,colWidths='*')
        data = [[t1, t2]]
        if self.foodhub.company_name== "Harvest Santa Barbara":
            parts.append(Table(data, colWidths=(1.75*inch, 2.25*inch)))
        return parts

    def get_doc(self):
        buff = StringIO.StringIO()
        doc = SimpleDocTemplate(buff, pagesize=(4*inch, 3*inch), rightMargin=0, leftMargin=0, topMargin=1*mm, bottomMargin=0)
        return doc, buff 

Solution

  • I can share how I have done it, but my implementation is to draw it directly on the canvas, then I add it in the footnote on the document template. Your method is to create a png and then add it (I do a similar thing with a graph object, but then I use pdfrw, which is a nice addin, I struggled a bit with write-access to folders when I started out). See if below works out for you.

    from reportlab.lib.units import mm, cm
    from reportlab.lib.pagesizes import A4
    from reportlab.graphics.barcode import qr, code128
    from reportlab.graphics.shapes import Drawing
    from reportlab.platypus import Table, TableStyle
    from reportlab.platypus import SimpleDocTemplate
    from reportlab.lib import colors
    
    def func(canvas, doc):
        canvas.saveState()
    
        # draw a QR code
        receipt = str(f'hello')
        qr_code = qr.QrCodeWidget(f'{receipt}')
        bounds = qr_code.getBounds()
        width = bounds[2] - bounds[0]
        height = bounds[3] - bounds[1]
        d = Drawing(60, 60, transform=[60. / width, 0, 0, 60. / height, 0, 0])
        d.add(qr_code)
        d.drawOn(canvas, 1.77 * cm, 259.55 * mm)
    
        #Draw Bar code
        canvas.setFillColor(colors.black)
        barcode = code128.Code128(receipt, barWidth=0.17 * mm, barHeight=5 * mm, ratio=2.75, humanReadable=1)
        barcode.drawOn(canvas, 5.95 * cm, 259.55 * mm)
        canvas.restoreState()
    
        return func
    #
    def create_pdf():
        story = []
        data = [['Data1', 'Data2', 'Data3', 'Data4', 'Data5', 'Data6'],
                ['0.2', '-0.1', '0', '0', '-0.5', '0.6']]
    
        colwidths = (50)
        rowheights = (10)
    
        t = Table(data, colwidths, rowheights)
    
        GRID_STYLE = TableStyle(
            [('FONTSIZE', (0, 0), (-1, -1), 5),
             ('GRID', (0, 0), (-1, -1), 0.5, colors.black),
             ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
             ('LEFTPADDING', (0, 0), (-1, -1), 0),
             ('RIGHTPADDING', (0, 0), (-1, -1), 0),
             ('TOPPADDING', (0, 0), (-1, -1), 0),
             ('BOTTOMPADDING', (0, 0), (-1, -1), 0),
             ('FONTNAME', (0, 0), (-1, -1), 'Helvetica'),
             ('SIZE', (0, 0), (-1, -1), 7),
             ('LEADING', (0, 0), (-1, -1), 8.2),
             ]
        )
    
        t.setStyle(GRID_STYLE)
        story.append(t)
    
        doc = SimpleDocTemplate('mydoc.pdf', pagesize=A4, topMargin=50)
        doc.build(story, onFirstPage=func)
    
        # ----------------------------------------------------------------------
    if __name__ == "__main__":
        create_pdf()  # Printing the pdf