Mark Wellings
Mark Wellings

Reputation: 81

Flask: Generate preview PDF with reportlab

with Flask I'm sending out emails with an xml and pdf attached. Before the mail is sent I'd like to have a preview of the pdf available, so that the user can check the data.

The pdf is constructed from the xml with the PDFOrder function. The PDF is stored in the variable 'pdf'. So, my question is how can I generate the pdf in memory and make it available as a preview for the user?

Here is the sample code of the outgoing email:

def send_mail():
    Email1 = session.get('Email1')
    Email2 = session.get('Email2')
    invno = session.get('invno')
    username = session['username']
    invId = session['invId']
    xmlStr,xmlFile = XmlGenerator(invId)

try:
    msg = Message(Hi,
    sender="[email protected]",
    recipients=[Email1,Email2])

    msg.body = '\nHi'

    myxmlinv = xml.dom.minidom.parseString(xmlStr)
    xmlStr = myxmlinv.toprettyxml(encoding="utf-8")
    msg.attach("Test+".xml","application/xml",xmlStr)

    buff = BytesIO()


    pdfdoc = SimpleDocTemplate(buff, pagesize = letter)

    frame = Frame(pdfdoc.leftMargin,
            pdfdoc.bottomMargin,
            pdfdoc.width,
            pdfdoc.height,
            id = 'normal')

    template = PageTemplate(id = 'test', frames = frame)

    pdfdoc.addPageTemplates(template)

    pdforder = PDFOrder(xmlStr)
    Document = pdforder.createPDF()

    pdfdoc.build(Document)

    pdf = buff.getvalue()

    buff.close()

    msg.attach("Test_"+str(invId)+".pdf", "application/pdf", str(pdf))                  
    mail.send(msg)

except Exception, e:
    return(str(e))

The code below takes the user to /preview which should open the pdf. I'd prefer to have the pdf stored in memory. How would I have to render it in HTML?

<a href="/preview" target="_blank"><center><button type=button class="btn btn-default btn-lg">

Thanks!

UPDATE I've managed to save the pdf. But unfortunately it only holds some test of reportlab, although it's got .pdf extension. So, homehow doesnt render in to pdf. Any idea? It strange as the email sending works perfectly with both xml and pdf. You think this part is important: "application/pdf", str(pdf) enter image description here That's my updated definition

@app.route('/preview/')
def preview():
invId = session['invId']
xmlStr,xmlFile = XmlGenerator(invId)

try:
    myxmlinv = xml.dom.minidom.parseString(xmlStr)
    xmlStr = myxmlinv.toprettyxml(encoding="utf-8")

pdfdoc = SimpleDocTemplate("/var/www/FlaskApp/FlaskApp/static/mypdf.pdf", pagesize = letter)
pdforder = PDFOrder(xmlStr)
Document = pdforder.createPDF()
pdfdoc.build(Document)

except Exception, e:
    return(str(e))

return render_template("test.html")

Upvotes: 0

Views: 2161

Answers (1)

Joe
Joe

Reputation: 3007

As far as I can tell you are not actually naming your PDF file. This would be done in the simpledoc declaration. Here is an example of one that I have done: doc = SimpleDocTemplate(filename, pagesize=letter) In this situation the filename variable is the full path to where I want the pdf. example: filename = r'C:\User\joe\Desktop\some_file.pdf'`

If you want the file to go into the same directory that you are using you can just give it a name without the full path. ie: filename = 'some_file.pdf'

Once your code hits the doc.build line it will create the pdf.

To open it up use one of these lines:

For MACs:

os.system("open " + filename)

Windows:

os.system("start " + filename)

Upvotes: 1

Related Questions