3

我正在按照本文中的说明将信息写入 PDF 文档中的注释。

上述文章中的脚本确实有效。但是,在执行脚本并打开输出文件后,这些字段仍然不可见。单击注释时,将显示从脚本添加的文本。但随后单击文档中的其他位置时,脚本中的文本消失了。

是否需要触发某种标志,以通知 PDF 阅读器字段已被填写?

当前脚本的输出示例


编辑:

文章中给出的脚本可能并不正确。

阅读未编辑 PDF的第一个注释时,我得到以下信息:

{'/T': '(business_name_1)', '/AA': {'/F': (113, 0)}, '/MK': {}, '/F': '4', '/Rect': ['77.433', '639.425', '538.174', '663.305'], '/Type': '/Annot', '/FT': '/Tx', '/AP': {'/N': (12, 0)}, '/DA': '(/Helv 0 Tf 1 1 1 rg)', '/Subtype': '/Widget', '/TU': '([Business Name])', '/Q': '1', '/P': (11, 0)}

当使用 PDF 阅读器手动填写字段并保存,然后读取该 PDF 文件时,'/V':属性会添加到前面的代码中,即第一个注释是以下代码:

{'/V': '(Bostata)', '/T': '(business_name_1)', '/AA': {'/F': (113, 0)}, '/MK': {}, '/F': '4', '/Rect': ['77.433', '639.425', '538.174', '663.305'], '/Type': '/Annot', '/FT': '/Tx', '/AP': {'/N': (12, 0)}, '/DA': '(/Helv 0 Tf 1 1 1 rg)', '/Subtype': '/Widget', '/TU': '([Business Name])', '/Q': '1', '/P': (11, 0)}

但是,在脚本将值添加到注释后,也会添加大量数据(10k+ 字符,所以我不会在这里粘贴)。

有人可以发现本文中给出的脚本的错误吗


编辑2:

在这里,我找到了部分答案。

将代码更改为:

annotation.update( pdfrw.PdfDict(AP=data_dict[key], V=data_dict[key]) )

当我在谷歌浏览器中使用 Adob​​e 阅读器打开 pdf 时,它工作正常。如果我用 PDF-XChange 打开文件,它工作正常。

但是,当我在 Windows 10 机器上安装的 Adob​​e acrobate 中打开 PDF 文件时,我遇到了同样的问题,即该字段为空。

4

2 回答 2

3

您需要将 /NeedAppearances 标记设置为 True。

看看这个 - https://github.com/pmaupin/pdfrw/issues/84#issuecomment-463493521

于 2020-02-08T04:20:11.320 回答
3

我想我会用完整的工作代码分享答案

import pdfrw

def write_fillable_pdf(input_pdf_path, output_pdf_path, data_dict):
    ANNOT_KEY = '/Annots'
    ANNOT_FIELD_KEY = '/T'          # name
    ANNOT_FORM_type = '/FT'         # Form type (e.g. text/button)
    ANNOT_FORM_button = '/Btn'      # ID for buttons, i.e. a checkbox
    ANNOT_FORM_text = '/Tx'         # ID for textbox
    SUBTYPE_KEY = '/Subtype'
    WIDGET_SUBTYPE_KEY = '/Widget' 
    try:
        template_pdf = pdfrw.PdfReader(input_pdf_path)
        i =0
        for Page in template_pdf.pages:
            if Page[ANNOT_KEY]:
                for annotation in Page[ANNOT_KEY]:
                    if annotation[ANNOT_FIELD_KEY] and annotation[SUBTYPE_KEY] == WIDGET_SUBTYPE_KEY :
                        key = annotation[ANNOT_FIELD_KEY][1:-1] # Remove parentheses
                        if key in data_dict.keys():
                            i += 1
                            if annotation[ANNOT_FORM_type] == ANNOT_FORM_button:
                                annotation.update( pdfrw.PdfDict( V=pdfrw.PdfName(data_dict[key]) , AS=pdfrw.PdfName(data_dict[key]) ))
                            elif annotation[ANNOT_FORM_type] == ANNOT_FORM_text:
                                annotation.update( pdfrw.PdfDict( V=data_dict[key] , AP=data_dict[key] ) )    
        if i>0:
            template_pdf.Root.AcroForm.update(pdfrw.PdfDict(NeedAppearances=pdfrw.PdfObject('true')))
            pdfrw.PdfWriter().write(output_pdf_path, template_pdf)
            return True
    except Exception as ex:
        print(ex)
        return False

if __name__ == '__main__':
    data_dict = {
    'item_1' : 'soap',
    'ManufacturingNo': '98765',
    'ceck_T102': 'Yes',
    'ceck_T104': 'Off',
    'ceck_T001': 'Yes'
    }
    INVOICE_TEMPLATE_PATH = 'TemplateFile.pdf'
    INVOICE_OUTPUT_PATH = 'OutputFile.pdf'

    if write_fillable_pdf(INVOICE_TEMPLATE_PATH, INVOICE_OUTPUT_PATH, data_dict):
        print("Success")
于 2020-05-28T07:58:17.237 回答