首页 > 解决方案 > 无法使用 python pdfrw lib 更新/显示 PDF 表单

问题描述

我有一些关于 pdf 表格填写的问题。首先让我给你一些背景信息:我正在尝试制作一个 100% python pdf 表单填写服务,为此我正在使用 pdfrw 库。

这是我的代码,它以pdf路径和data_dict(json变成dict)作为参数:

import pdfrw

_ANNOT_KEY = "/Annots"
_ANNOT_FIELD_KEY = "/T"
_ANNOT_VAL_KEY = "/V"
_ANNOT_RECT_KEY = "/Rect"
_SUBTYPE_KEY = "/Subtype"
_WIDGET_SUBTYPE_KEY = "/Widget"

def fill_pdf_with_values(input_pdf_path, data_dict):

    template_pdf = pdfrw.PdfReader(input_pdf)
    template_pdf.Root.AcroForm.update(
        pdfrw.PdfDict(NeedAppearances=pdfrw.PdfObject("true"))
    )
    annotations = template_pdf.pages[0][_ANNOT_KEY]
    
    for page in template_pdf.pages:
        for annotation in annotations:
            if annotation[_SUBTYPE_KEY] != _WIDGET_SUBTYPE_KEY:
                continue
            if not annotation[_ANNOT_FIELD_KEY]:
                continue
            key = annotation[_ANNOT_FIELD_KEY][1:-1]
            if key not in data_dict.keys():
                continue
            if isinstance(data_dict[key], bool):
                if data_dict[key]:
                    # If the value is True then the checkbox will be checked
                    # "On" is not necessary, by that i mean you can put whatever you want,
                    # but without this line we cant get the checkbox to works..
                    # annotation.update(pdfrw.PdfDict(AS=pdfrw.PdfName("On")))
                    annotation.update(
                        pdfrw.PdfDict(AP=data_dict[key], AS=pdfrw.PdfName("On"))
                    )
                else:
                    # If the value is False then we dont want the checkbox to be checked
                    # annotation.update(pdfrw.PdfDict(AS=pdfrw.PdfName("Off")))
                    annotation.update(
                        pdfrw.PdfDict(AP=data_dict[key], AS=pdfrw.PdfName("Off"))
                    )
                continue
            annotation.update(pdfrw.PdfDict(AP=data_dict[key], V=data_dict[key]))
    
    output_pdf = pdfrw.PdfWriter()
    output_pdf.write("test.pdf", template_pdf)

但我努力让它发挥作用。这是我的两个问题:

  1. 根据 pdf 查看器的不同,文本字段中的数据不会显示,我的复选框也是如此。我没有足够的关于 PDF 的知识来区分每个查看器之间的区别,在任何情况下我应该有什么才能显示它?

  2. 我对一个特定字段也有一个大问题=>当我打开“清理过的”pdf时我可以编辑它,但是当我通过我的代码传递它时,什么都没有写,而且文本不可编辑......还有当我打印时相应的注释,对于“窃听者”,这是我得到的(在填充之前):

annotation = {'/AP': {'/N': (216, 0)}, '/DA': '(/Helv 0 Tf 0 g)', '/DR': {'/Encoding': {'/PDFDocEncoding': {'/Differences': ['24', '/breve', '/caron', '/circumflex', '/dotaccent', '/hungarumlaut', '/ogonek', '/ring', '/tilde', '39', '/quotesingle', '96', '/grave', '128', '/bullet', '/dagger', '/daggerdbl', '/ellipsis', '/emdash', '/endash', '/florin', '/fraction', '/guilsinglleft', '/guilsinglright', '/minus', '/perthousand', '/quotedblbase', '/quotedblleft', '/quotedblright', '/quoteleft', '/quoteright', '/quotesinglbase', '/trademark', '/fi', '/fl', '/Lslash', '/OE', '/Scaron', '/Ydieresis', '/Zcaron', '/dotlessi', '/lslash', '/oe', '/scaron', '/zcaron', '160', '/Euro', '164', '/currency', '166', '/brokenbar', '168', '/dieresis', '/copyright', '/ordfeminine', '172', '/logicalnot', '/.notdef', '/registered', '/macron', '/degree', '/plusminus', '/twosuperior', '/threesuperior', '/acute', '/mu', '183', '/periodcentered', '/cedilla', '/onesuperior', '/ordmasculine', '188', '/onequarter', '/onehalf', '/threequarters', '192', '/Agrave', '/Aacute', '/Acircumflex', '/Atilde', '/Adieresis', '/Aring', '/AE', '/Ccedilla', '/Egrave', '/Eacute', '/Ecircumflex', '/Edieresis', '/Igrave', '/Iacute', '/Icircumflex', '/Idieresis', '/Eth', '/Ntilde', '/Ograve', '/Oacute', '/Ocircumflex', '/Otilde', '/Odieresis', '/multiply', '/Oslash', '/Ugrave', '/Uacute', '/Ucircumflex', '/Udieresis', '/Yacute', '/Thorn', '/germandbls', '/agrave', '/aacute', '/acircumflex', '/atilde', '/adieresis', '/aring', '/ae', '/ccedilla', '/egrave', '/eacute', '/ecircumflex', '/edieresis', '/igrave', '/iacute', '/icircumflex', '/idieresis', '/eth', '/ntilde', '/ograve', '/oacute', '/ocircumflex', '/otilde', '/odieresis', '/divide', '/oslash', '/ugrave', '/uacute', '/ucircumflex', '/udieresis', '/yacute', '/thorn', '/ydieresis'], '/Type': '/Encoding'}}, '/Font': {'/Helv': {'/BaseFont': '/Helvetica', '/Name': '/Helv', '/Subtype': '/Type1', '/Type': '/Font'}}}, '/F': '4', '/FT': '/Tx', '/P': (12, 0), '/Rect': ['453.96', '455.04', '749.16', '463.2'], '/Subtype': '/Widget', '/T': '(Nomdusage)', '/TU': '(Nomdusage)', '/Type': '/Annot'}

当所有其他应该以相同的方式使用时,我得到:

annotation = {'/DA': '(/Helv 12 Tf 0 g)', '/F': '4', '/FT': '/Tx', '/MK': {}, '/P': (12, 0), '/Rect': ['129.105', '454.669', '395.032', '463.725'], '/Subtype': '/Widget', '/T': '(Nomdenaissance)', '/TU': '(Nomdenaissance)', '/Type': '/Annot'}

有了这个,我不知道我是否做错了什么......我的观点是“干净”的pdf有一个不好的注释实现,我尝试了很多不同的东西,但事实证明我找不到互联网上的解决方案。

如果需要,我可以提供 pdf 和 data_set。

感谢您的阅读和您的时间!希望你能帮我解决这个问题:)

标签: pythonpdfpdf-generationpdfrw

解决方案


推荐阅读