NeedAppearances=pdfrw.PdfObject('true') 强制在 Acrobat Reader 中手动保存 pdf

问题描述 投票:0回答:3

我们有一个 pdf 表单文件

example.pdf
,其中有 3 列:

名称_1, 公司_1,以及 客户_1

我们要填写的数据有希伯来语和英语。 我们的目标是拥有一个可以在浏览器和 Acrobat Reader 中以 RTL 方式打开的文件。 当我们通过以下代码手动保存导出的文件时,我们的目标就达到了,但是我们 不想手动保存它,或者如果没有其他选择,则以编程方式保存它。

import pdfrw


INVOICE_TEMPLATE_PATH = 'example.pdf'
INVOICE_OUTPUT_PATH = 'output.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)
    template_pdf.Root.AcroForm.update(pdfrw.PdfDict(NeedAppearances=pdfrw.PdfObject('true')))
    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(AP=data_dict[key], V='{}'.format(data_dict[key]), Ff=1)
                    )
    pdfrw.PdfWriter().write(output_pdf_path, template_pdf)



data_dict = {
    'name_1': 'עידו',
    'company_1': 'IBM',
    'client_1': 'אסם'
}

if __name__ == '__main__':
    write_fillable_pdf(INVOICE_TEMPLATE_PATH, INVOICE_OUTPUT_PATH, data_dict)

我们认为

NeedAppearances
与需要手动保存有关。 在 Acrobat Reader 中打开导出的文件时,Acrobat Reader 会对该文件应用特定的工作。因此,退出时程序会询问我们是否要保存文件。 此操作对我们来说至关重要,但我们自动需要它。

这个操作是什么以及如何在我们的代码中以编程方式执行它?出口之前或之后..

python forms pdf pypdf hebrew
3个回答
2
投票

当我将 NeedAppearances 设置为 true 时,我遇到了同样的问题。我发现下面的代码适用于我的 pdf。请告诉我这是否适合您。

from pikepdf import Pdf

with Pdf.open('source_pdf.pdf') as pdf:
    pdf.generate_appearance_streams()
    pdf.save('output.pdf')

我认为 generate_appearance_streams() 能够生成外观流,而不是让 PDF 阅读器来做,因此使用 Adobe Acrobat Reader 打开时不需要手动保存。


0
投票

使用

pdfrw
,您可以使用以下代码将 NeedAppearances 设置为 True

from pdfrw import PdfReader, PdfDict, PdfObject def set_need_appearances(pdf_reader: PdfReader): pdf_reader.Root.AcroForm.update(PdfDict(NeedAppearances=PdfObject("true"))) return pdf_reader
使用

PyPDF2

,您可以使用
PdfWriter类上的内置方法
设置需要的外观:

pdf_writer = PdfWriter() pdf_writer.set_need_appearances_writer()
    

0
投票
我找到了解决办法。使用 pdfrw,我已经实现将 NeedAppearances 设置为 true,但它仍然没有保存。当我在 Acrobat 中打开文件时,系统会询问我是否要保存。

我尝试使用 pdfrw 保存文件并使用 pikepdf 和 PyPDF2 重新打开,但出现了更多问题。我尝试设置

annotation["/AP"] = ""

 取得了一些成功,设置 
del annotation["/AP"]
 取得了更大的成功,但它并不完整/绝对 - 仍然有人问我是否要保存。

解决方案是让 Adobe 以编程方式保存文件。当我最终对其进行编程时,表单字段中的值随处可见(除了常见的 PDF 查看器之外,Explorer PDF 预览器、SharePoint 预览器等),并且不再要求我保存文件。

这适用于当前版本的 Acrobat。如果您仍在使用旧版本,则需要使用 ArcoExch.AVDoc 并且不需要创建 PDDoc 对象的实例:

import pdfrw import win32com.client pdf = PdfReader("your path") output_path = "your path" <actions on the PDF here> pdf.Root.AcroForm.update(PdfDict(NeedAppearances=PdfObject("true"))) PdfWriter().write(output_path, pdf) # Create an instance of the Acrobat Application object acrobat_app = win32com.client.Dispatch("AcroExch.App") # Create an instance of the PDDoc object pdf_doc = win32com.client.Dispatch("AcroExch.PDDoc") # Open the PDF file pdf_doc.Open(output_path) # Save the PDF pdf_doc.Save(1, output_path) # Close the PDF pdf_doc.Close() # Quit Acrobat acrobat_app.Exit()
'NeedAppearances = true'可以在读取和写入PDF之间的任何位置,这似乎并不重要。我什至尝试使用此解决方案将其完全删除,但它仍然有效。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.