[英]Serving dynamic PDF through Flask, generated with pdfrw
我正在嘗試通過 Flask 向我的用戶提供動態 PDF。 他們填寫表格以顯示一些計算,但他們希望將值自動填充到 PDF 模板,然后將其打印在紙上。
我讓它在本地工作,只是將值填充到 PDF 模板中,但我不知道如何將它工作到我的 Flask 應用程序中。 我在本地得到的是我有一個模板 PDF 文件,一個帶有值的字典,一個將值填充到模板並將其寫出到新 PDF 文件的函數。 當你用 Flask 托管它時,我希望它動態地為它們提供由函數創建的新 PDF,而不是將它寫入文件。
我正在使用 pdfrw 庫進行 pdf 修改,我意識到我可能需要使用 make_reponse 或 IO 或組合。 只是不知道如何從 pdfrw 獲取結果而不是文件。 或者從哪里開始。
這是函數:
import os
import pdfrw
data_dict = #just a plain dict corresponding with the temp.pdf keys
PDF_TEMPLATE_PATH = 'temp.pdf'
PDF_OUT_PATH = 'out.pdf'
ANNOT_KEY = '/Annots'
ANNOT_FIELD_KEY = '/T'
ANNOT_VAL_KEY = '/V'
ANNOT_RECT_KEY = '/Rect'
SUBTYPE_KEY = '/Subtype'
WIDGET_SUBTYPE_KEY = '/Widget'
def write_fillable_pdf(input_pdf_path, output_pdf_path, data_dict):
template_pdf = pdfrw.PdfReader(input_pdf_path)
annotations = template_pdf.pages[0][ANNOT_KEY]
for annotation in annotations:
if annotation[SUBTYPE_KEY] == WIDGET_SUBTYPE_KEY:
if annotation[ANNOT_FIELD_KEY]:
key = annotation[ANNOT_FIELD_KEY][1:-1]
if key in data_dict.keys():
annotation.update(
pdfrw.PdfDict(V='{}'.format(data_dict[key]))
)
pdfrw.PdfWriter().write(output_pdf_path, template_pdf)
if __name__ == '__main__':
write_fillable_pdf(PDF_TEMPLATE_PATH, PDF_OUT_PATH, data_dict)
所以我想,我如何得到這條線
pdfrw.PdfWriter().write(output_pdf_path, template_pdf)
能夠與例如服務。 make_reponse 或 IO 或可能? 當我讓它工作時,我將在燒瓶中為 /pdf 路線制作一個按鈕-href。
抱歉,我對此很陌生,正在努力滿足用戶的願望。
感謝您的任何指導或方向。
假設您不想將 PDF 保存到服務器,而只是將其保存在內存中,然后使用 Flask 的send_file
函數提供它,您可以修改write_fillable_pdf
函數以返回一個字節類型對象。 所以而不是:
pdfrw.PdfWriter().write(output_pdf_path, template_pdf)
您可以執行以下操作:
buf = io.BytesIO()
pdfrw.PdfWriter().write(buf, template_pdf)
buf.seek(0)
return buf
記得在文件頂部import io
!
然后在您的燒瓶代碼中,可以將write_fillable_pdf
的返回值直接傳遞給發送文件函數:
from flask import send_file
data = write_fillable_pdf() # With some arguments
return send_file(data, mimetype='application/pdf')
您可能想要修改write_fillable_pdf
接受的參數,因為您不再希望提供output_pdf_path
。 您還希望將您的data_dict
傳遞給data_dict
,它可以根據用戶或其他地方提供的值構建。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.