I want to be able to print to one PDF document multiple pages where each page is a different result from a query in a for loop, I sell on different platforms, and when I want to print each sale document I can check one or more boxes and the click print and all the chosen pages are then transformed into one document, I want to be able to do the same with flask. My code prints only the last document in the que but as you can see from the terminal print out each document is prossessed, there are four documents to print in this example.
Here is the code that I have so far
@bp.route('/sales/factures_pdf', methods=['GET', 'POST'])
@login_required
def factures_pdf():
addresses = Add1.query.order_by(Add1.id.desc()).filter(Add1.suivi=="0").all()
for add in addresses:
print(add.id, add.order_id)
if add.erdmaddress:
invoice = Erdmsale.query.filter(Erdmsale.id==add.erdmaddress).first()
buyer = Erdmsale.query.filter(Erdmsale.invoice==invoice.invoice).all()
eu = eu_poste.query.filter(eu_poste.pays==invoice.pays).first()
if eu:
rendered = render_template('/erdm_sales/erdm_print_facture2.html', buyer=buyer, invoice=invoice)
pdf = pdfkit.from_string(rendered, False)
response = make_response(pdf)
response.headers['Content-Type'] = 'application/pdf'
response.headers['Content-Disposition'] = 'inline; filename=Facture.pdf'
rendered = render_template('/erdm_sales/erdm_print_facture.html', buyer=buyer, invoice=invoice)
pdf = pdfkit.from_string(rendered, False)
response = make_response(pdf)
response.headers['Content-Type'] = 'application/pdf'
response.headers['Content-Disposition'] = 'inline; filename=Facture.pdf'
if add.bdfaddress:
invoice = Sale.query.filter(Sale.id==add.bdfaddress).first()
buyer = Sale.query.filter(Sale.invoice==invoice.invoice).all()
eu = eu_poste.query.filter(eu_poste.pays==invoice.pays).first()
if eu:
rendered = render_template('/sales/print_facture1.html', buyer=buyer, invoice=invoice)
pdf = pdfkit.from_string(rendered, False)
response = make_response(pdf)
response.headers['Content-Type'] = 'application/pdf'
response.headers['Content-Disposition'] = 'inline; filename=Facture.pdf'
rendered = render_template('/sales/print_facture.html', buyer=buyer, invoice=invoice)
pdf = pdfkit.from_string(rendered, False)
response = make_response(pdf)
response.headers['Content-Type'] = 'application/pdf'
response.headers['Content-Disposition'] = 'inline; filename=Facture.pdf'
return response
and here is the terminal out put
9139 2789695212
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-www-data'
Loading page (1/2)
[> ] 0%\r[=============================> ] 49%\r[============================================================] 100%\rPrinting pages (2/2) $
[> ] \rDone
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-www-data'
Loading page (1/2)
[> ] 0%\r[================> ] 27%\r[============================================================] 100%\rPrinting pages (2/2) $
[> ] \rDone
9138 2791653417
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-www-data'
Loading page (1/2)
[> ] 0%\r[=============================> ] 49%\r[============================================================] 100%\rPrinting pages (2/2) $
[client 91.173.134.192:49218] [> ] \rDone
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-www-data'
Loading page (1/2)
[> ] 0%\r[================> ] 27%\r[============================================================] 100%\rPrinting pages (2/2) $
[> ] \rDone
9135 69665725955778
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-www-data'
Loading page (1/2)
[> ] 0%\r[===============> ] 26%\r[============================================================] 100%\rPrinting pages (2/2) $
[> ] \rDone
9125 07363785112922
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-www-data'
Loading page (1/2)
[> ] 0%\r[===============> ] 26%\r[============================================================] 100%\rPrinting pages (2/2) $
[> ] \rDone
as you can see each page is produced but the document displayed is the last page, I am scared to change the code to much, I have tried by deleting all but the last of this code
pdf = pdfkit.from_string(rendered, False)
response = make_response(pdf)
response.headers['Content-Type'] = 'application/pdf'
response.headers['Content-Disposition'] = 'inline;
but then the documents are not produced.
All help much appreciated.
Warm regards
Paul
UPDATE
as a note I tried changing the templates so there is only one template, and made 'response.headers' 'attachment' but same problem.
I have spent a lot of time trying to use this code but to no avail, so I re looked at it and decided that I must put the for loop in one template rather than in the function with four different templates. here is my new code for those lost like me.
@bp.route('/sales/factures_pdf', methods=['GET', 'POST'])
@login_required
def factures_pdf():
bdfbuyers = []
erdmbuyers = []
eus = []
addresses = Add1.query.order_by(Add1.id.desc()).filter(Add1.suivi=="0").all()
for add in addresses:
bdfinvoice = Sale.query.filter(Sale.id==add.bdfaddress).first()
erdminvoice = Erdmsale.query.filter(Erdmsale.id==add.erdmaddress).first()
bdfbuyer = Sale.query.filter(Sale.invoice==bdfinvoice.invoice).all() if bdfinvoice != None else 0
erdmbuyer = Erdmsale.query.filter(Erdmsale.invoice==erdminvoice.invoice).all() if erdminvoice != None else 0
eus.append(EU(add.Pays))
bdfbuyers.append(bdfbuyer if bdfinvoice != None else 0)
erdmbuyers.append(erdmbuyer if erdminvoice != None else 0)
data = list(zip( eus, bdfbuyers, erdmbuyers))
rendered = render_template('sales/print_factures.html', data=data, eu=eu)
pdf = pdfkit.from_string(rendered, False)
response = make_response(pdf)
response.headers['Content-Type'] = 'application/pdf'
response.headers['Content-Disposition'] = 'inline; filename=Facture.pdf'
return response
html code
{% for eu, bdfbuyer, erdmbuyer in data %}
{% if bdfbuyer %}
{% if eu %}
<div>bdf {{ bdfbuer }} order id : {{ bdfbuyer.invoice }} </div>
{% for buy in bdfbuyer %}
<div> description {{ buy.description }} </div>
<div> date {{ buy.date }} </div>
<div> sku {{ buy.bdf.sku }} </div>
{% endfor %}
{% else %}
<div>bdf {{ bdfbuyer }} order id : {{ bdfbuyer.invoice }} </div>
{% for buy in bdfbuyer %}
<div> description {{ buy.description }} </div>
<div> date {{ buy.date }} </div>
{% endfor %}
{% endif %}
<div style = "page-break-after:always;"></div>
{% if eu %}
{% for buy in erdmbuyer %}
<div> description {{ buy.description }} </div>
<div> date {{ buy.date }} </div>
{% endfor %}
{% else %}
{% for buy in erdmbuyer %}
<div> description {{ buy.description }} </div>
<div> date {{ buy.date }} </div>
{% endfor %}
{% endif %}
<div style = "page-break-after:always;"></div>
{% endif %}
{% endfor %}
So I decided to pack all my data into "data", which has to be unpacked in the same order, and use
style = "page-break-after:always;"
to break up the pages, which is one of the hardest parts.
Hope this helps other.