The solution to the problem that pypdf2 does not display after filling the form field

For pdf operations under python, pypdf2 is the best choice, except... this:

Use this code (a handful on the Internet) to fill the form field in the pdf, the form field

# -*- coding: UTF-8 -*-
from PyPDF2 import PdfFileWriter, PdfFileReader

infile = "mb2.pdf"
outfile = "c.pdf"

pdf = PdfFileReader(open(infile, "rb"), strict=False)

pdf2 = PdfFileWriter()

field_dictionary = {'idnumber':'11ddas111','now_year':'2018-2-1','name':'好的'}

pdf2.addPage(pdf.getPage(0))
pdf2.updatePageFormFieldValues(pdf2.getPage(0), field_dictionary)

outputStream = open(outfile, "wb")
pdf2.write(outputStream)

 The resulting pdf, when opened with acrobat reader, does not display the content of the form field, it can only be displayed after the mouse is clicked, and disappears again after losing the focus, and can only be displayed after copying and pasting again:

 

 When the mouse is clicked it will display:



 

 

There are many similar situations online:

https://stackoverflow.com/questions/47369740/pypdf2-appends-the-same-file-over-and-over  modify fields mentioned, pypdf2 form fields can not be displayed in acrobat reader, can not fill cb and rb:
   PyPdf2 seems to be the best option despite all the bugs python packages have for pdfs such as fields not showing in acroreader and being unable to fill checkboxes or radio buttons .  
There does appear to be a bug (with pdfs generally? maybe) where the pdf file is not redrawn . If one clicks on the field one can see the new text that PyPDF2 entered however one then has to manually copy and paste in order to see that change permanently .

 

Finally found a solution in this issue:

https://github.com/mstamy2/PyPDF2/issues/355

and thanks to this great guy ( https://github.com/ademidun ) for giving a reference:

Okay, I think I have figured it out. If you read section 12.7.2 (page 431) of the PDF 1.7 specification, you will see that you need to set the NeedAppearances flag of the Acroform.

 

ok, we don't produce code, only porters of code :D

Here is the solution:

 

# -*- coding: UTF-8 -*-
from PyPDF2 import PdfFileWriter, PdfFileReader
from PyPDF2.generic import BooleanObject, NameObject, IndirectObject

def set_need_appearances_writer(writer):
    # See 12.7.2 and 7.7.2 for more information: http://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf
    try:
        catalog = writer._root_object
        # get the AcroForm tree
        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)
        return writer

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

infile = "mb2.pdf"
outfile = "c.pdf"

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

pdf2 = PdfFileWriter()
set_need_appearances_writer(pdf2)
if "/AcroForm" in pdf2._root_object:
    pdf2._root_object["/AcroForm"].update(
        {NameObject("/NeedAppearances"): BooleanObject(True)})

field_dictionary = {'idnumber':'11ddas111','now_year':'2018-2-1','name':'好的'}

pdf2.addPage(pdf.getPage(0))
pdf2.updatePageFormFieldValues(pdf2.getPage(0), field_dictionary)

outputStream = open(outfile, "wb")
pdf2.write(outputStream)

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326132189&siteId=291194637
Recommended