gpt4 book ai didi

表单字段的 Python Django PDF 扁平化

转载 作者:行者123 更新时间:2023-12-04 01:12:20 31 4
gpt4 key购买 nike

我有一个项目,我需要填写预制的 PDF,我想到的最合乎逻辑的解决方案是将预制的 PDF 制作成 PDF 表单,以便输入值应该放在标签中,然后我可以查看 PDF 中的表单标签,并将它们与值字典对齐。

我已经使用 完成了这项工作PyPDF2 .总的来说,我拍了一张网络表单的图像,然后打开 Acrobat 并根据图像中看到的字段创建了一个 PDF 表单,然后使用 PyPDF2 用于填写 PDF 表单字段,但需要注意的是,在某些浏览器中打印填写的值似乎有问题,Firefox 就是其中之一。

我如何将我的 PDF 表单转换为标准/平面 PDF 以便我可以保留预先填充的值,但会丢失可编辑的字段(因为我认为这是问题所在)?

from io import BytesIO

import PyPDF2
from django.http import HttpResponse

from PyPDF2.generic import BooleanObject, NameObject, IndirectObject


def pdf_view(request):
template = 'templates/template.pdf'

outfile = "templates/test.pdf"

input_stream = open(template, "rb")
pdf_reader = PyPDF2.PdfFileReader(input_stream, strict=False)
if "/AcroForm" in pdf_reader.trailer["/Root"]:
pdf_reader.trailer["/Root"]["/AcroForm"].update(
{NameObject("/NeedAppearances"): BooleanObject(True)})

pdf_writer = PyPDF2.PdfFileWriter()
set_need_appearances_writer(pdf_writer)
if "/AcroForm" in pdf_writer._root_object:
# Acro form is form field, set needs appearances to fix printing issues
pdf_writer._root_object["/AcroForm"].update(
{NameObject("/NeedAppearances"): BooleanObject(True)})

data_dict = {
'first_name': 'John',
'last_name': 'Smith',
'email': 'mail@mail.com',
'phone': '889-998-9967',
'company': 'Amazing Inc.',
'job_title': 'Dev',
'street': '123 Main Way',
'city': 'Johannesburg',
'state': 'New Mexico',
'zip': 96705,
'country': 'USA',
'topic': 'Who cares...'

}

pdf_writer.addPage(pdf_reader.getPage(0))
pdf_writer.updatePageFormFieldValues(pdf_writer.getPage(0), data_dict)

output_stream = BytesIO()
pdf_writer.write(output_stream)

# print(fill_in_pdf(template, data_dict).getvalue())

# fill_in_pdf(template, data_dict).getvalue()
response = HttpResponse(output_stream.getvalue(), content_type='application/pdf')
response['Content-Disposition'] = 'inline; filename="completed.pdf"'
input_stream.close()

return response


def set_need_appearances_writer(writer):
try:
catalog = writer._root_object
# get the AcroForm tree and add "/NeedAppearances attribute
if "/AcroForm" not in catalog:
writer._root_object.update({
NameObject("/AcroForm"): IndirectObject(len(writer._objects), 0, writer)})

need_appearances = NameObject("/NeedAppearances")
writer._root_object["/AcroForm"][need_appearances] = BooleanObject(True)


except Exception as e:
print('set_need_appearances_writer() catch : ', repr(e))

return writer

最佳答案

解决方案非常简单,如有疑问,请阅读文档( 第 552/978 页 ):

https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference.pdf

我需要做的就是将字段标志的位位置更改为 1,使字段只读,如下所示:

from io import BytesIO

import PyPDF2
from django.http import HttpResponse

from PyPDF2.generic import BooleanObject, NameObject, IndirectObject, NumberObject


def pdf(request):
template = 'templates/template.pdf'

outfile = "templates/test.pdf"

input_stream = open(template, "rb")
pdf_reader = PyPDF2.PdfFileReader(input_stream, strict=False)
if "/AcroForm" in pdf_reader.trailer["/Root"]:
pdf_reader.trailer["/Root"]["/AcroForm"].update(
{NameObject("/NeedAppearances"): BooleanObject(True)})

pdf_writer = PyPDF2.PdfFileWriter()
set_need_appearances_writer(pdf_writer)
if "/AcroForm" in pdf_writer._root_object:
# Acro form is form field, set needs appearances to fix printing issues
pdf_writer._root_object["/AcroForm"].update(
{NameObject("/NeedAppearances"): BooleanObject(True)})

data_dict = {
'first_name': 'John\n',
'last_name': 'Smith\n',
'email': 'mail@mail.com\n',
'phone': '889-998-9967\n',
'company': 'Amazing Inc.\n',
'job_title': 'Dev\n',
'street': '123 Main Way\n',
'city': 'Johannesburg\n',
'state': 'New Mexico\n',
'zip': 96705,
'country': 'USA\n',
'topic': 'Who cares...\n'

}

pdf_writer.addPage(pdf_reader.getPage(0))
page = pdf_writer.getPage(0)
pdf_writer.updatePageFormFieldValues(page, data_dict)
for j in range(0, len(page['/Annots'])):
writer_annot = page['/Annots'][j].getObject()
for field in data_dict:
# -----------------------------------------------------BOOYAH!
if writer_annot.get('/T') == field:
writer_annot.update({
NameObject("/Ff"): NumberObject(1)
})
# -----------------------------------------------------
output_stream = BytesIO()
pdf_writer.write(output_stream)

response = HttpResponse(output_stream.getvalue(), content_type='application/pdf')
response['Content-Disposition'] = 'inline; filename="completed.pdf"'
input_stream.close()

return response


def set_need_appearances_writer(writer):
try:
catalog = writer._root_object
# get the AcroForm tree and add "/NeedAppearances attribute
if "/AcroForm" not in catalog:
writer._root_object.update({
NameObject("/AcroForm"): IndirectObject(len(writer._objects), 0, writer)})

need_appearances = NameObject("/NeedAppearances")
writer._root_object["/AcroForm"][need_appearances] = BooleanObject(True)


except Exception as e:
print('set_need_appearances_writer() catch : ', repr(e))

return writer

关于表单字段的 Python Django PDF 扁平化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55187651/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com