Динамическое обслуживание от c PDF до Flask, созданное с помощью pdfrw - PullRequest
2 голосов
/ 26 января 2020

Я пытаюсь предоставить динамический c PDF моим пользователям через Flask. Они заполняют форму, чтобы представить некоторые расчеты, но они хотели бы автоматически заполнить значения в 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 или скорее всего? Я просто сделаю кнопку-href для / pdf маршрута в flask для этого, когда у меня это получится.

Извините, я довольно новичок в этом, стараясь изо всех сил выполнить желания мои пользователи.

Спасибо за любые указания или указания.

1 Ответ

1 голос
/ 26 января 2020

Предполагая, что вы не хотите сохранять PDF-файл на сервере и просто хранить его в памяти, а затем использовать его с функцией Flask *1020*, вы можете изменить функцию 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 вверху файла!

Тогда в вашем flask код, возвращаемое значение 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, поскольку вы больше не будете sh на поставку output_pdf_path. Вы также хотели бы передать это свой data_dict, который может быть построен на основе значений, предоставленных пользователем или где-то еще.

...