Search code examples
flaskpypdf

Flask - PyPDF2 - Exporting in memory pdf file


I'm trying to export a pdf file from a flask app but for some reason I can't seem to write it correctly. It does work when I'm exporting to my local folder but I get a blank pdf when exporting through Flask. Any ideas ?

    pdf = PdfFileWriter()
    p1 = PdfFileReader(open(os.path.join(STATICDIR,'page1.pdf'), "rb"))
    p2 = PdfFileReader(open(os.path.join(STATICDIR,'page2.pdf'), "rb"))
    p3 = PdfFileReader(open(os.path.join(STATICDIR,'lastpage.pdf'), "rb"))

    pdf.addPage(p1.getPage(0))
    pdf.addPage(p2.getPage(0))
    pdf.addPage(p3.getPage(0))
    
    #this works
    #outputStream = open(r"output.pdf", "wb")
    #pdf.write(outputStream)

    outfile = BytesIO()
    pdf.write(outfile)

    return Response(pdf, mimetype='application/pdf',
                    headers={'Content-Disposition': 'attachment;filename=output.pdf'})

Solution

  • BytesIO is just a buffer containing some data it isn't associated with any real file on the disk, It's just a chunk of memory that behaves like a file. You first need to write the contents of PdfFileWriter() to the buffer then write the values of the buffer to the pdf file. Flask has a neat function send_file which allows you to send the contents of a file to the client.

    from pypdf2 import PdfFileWriter
    from flask import send_file
    
    pdf = PdfFileWriter()
    p1 = PdfFileReader(open(os.path.join(STATICDIR,'page1.pdf'), "rb"))
    p2 = PdfFileReader(open(os.path.join(STATICDIR,'page2.pdf'), "rb"))
    p3 = PdfFileReader(open(os.path.join(STATICDIR,'lastpage.pdf'), "rb"))
    
    pdf.addPage(p1.getPage(0))
    pdf.addPage(p2.getPage(0))
    pdf.addPage(p3.getPage(0))
        
    #this works
    outputStream = open(r"output.pdf", "wb")
    pdf.write(outputStream)
    
    outfile = BytesIO()
    pdf.write(outfile)
    
    with open("output.pdf", "wb") as f:
        f.write(outfile.getvalue())
    
    return send_file('./output.pdf', mimetype='application/pdf')