flask pdfkit sqlalchemy 通过 sql 查询从 for 循环打印到一个 pdf 文档的多个模板
flask pdfkit sqlalchemy print to one pdf document multiple templates from a for loop through a sql query
我希望能够将多页打印到一个 PDF 文档,其中每页都是 for 循环中查询的不同结果,我在不同的平台上销售,当我想打印每个销售文档时,我可以选中一个或多个框并单击打印,然后所有选定的页面都会转换为一个文档,我希望能够对 Flask 执行相同的操作。我的代码仅打印队列中的最后一个文档,但正如您从终端中看到的那样,每个文档都已处理,本例中有四个文档要打印。
这是我目前的代码
@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
这是终端输出
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
如您所见,每一页都已生成,但显示的文档是最后一页,我不敢将代码更改太多,我已尝试删除除最后一段以外的所有代码
pdf = pdfkit.from_string(rendered, False)
response = make_response(pdf)
response.headers['Content-Type'] = 'application/pdf'
response.headers['Content-Disposition'] = 'inline;
但随后没有生成文件。
非常感谢大家的帮助。
热烈的问候
保罗
更新
请注意,我尝试更改模板,因此只有一个模板,并制作了 'response.headers' 'attachment' 但同样的问题。
我花了很多时间尝试使用这段代码,但无济于事,所以我重新看了看,决定必须将 for 循环放在一个模板中,而不是放在具有四个不同模板的函数中。这是我为像我一样迷路的人准备的新代码。
@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代码
{% 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 %}
所以我决定把我所有的数据打包成“数据”,必须按相同的顺序解包,然后使用
style = "page-break-after:always;"
分解页面,这是最难的部分之一。
希望这对其他人有帮助。
我希望能够将多页打印到一个 PDF 文档,其中每页都是 for 循环中查询的不同结果,我在不同的平台上销售,当我想打印每个销售文档时,我可以选中一个或多个框并单击打印,然后所有选定的页面都会转换为一个文档,我希望能够对 Flask 执行相同的操作。我的代码仅打印队列中的最后一个文档,但正如您从终端中看到的那样,每个文档都已处理,本例中有四个文档要打印。
这是我目前的代码
@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
这是终端输出
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
如您所见,每一页都已生成,但显示的文档是最后一页,我不敢将代码更改太多,我已尝试删除除最后一段以外的所有代码
pdf = pdfkit.from_string(rendered, False)
response = make_response(pdf)
response.headers['Content-Type'] = 'application/pdf'
response.headers['Content-Disposition'] = 'inline;
但随后没有生成文件。
非常感谢大家的帮助。
热烈的问候
保罗
更新
请注意,我尝试更改模板,因此只有一个模板,并制作了 'response.headers' 'attachment' 但同样的问题。
我花了很多时间尝试使用这段代码,但无济于事,所以我重新看了看,决定必须将 for 循环放在一个模板中,而不是放在具有四个不同模板的函数中。这是我为像我一样迷路的人准备的新代码。
@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代码
{% 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 %}
所以我决定把我所有的数据打包成“数据”,必须按相同的顺序解包,然后使用
style = "page-break-after:always;"
分解页面,这是最难的部分之一。
希望这对其他人有帮助。