pmaupin / pdfrw

pdfrw is a pure Python library that reads and writes PDFs
Other
1.84k stars 271 forks source link

Filled PDF form fields not visible in Windows preview #246

Open jrennemo77 opened 2 months ago

jrennemo77 commented 2 months ago

I'm using pdfrw to fill out a PDF form. However, the filled values in the PDF's text input fields are not visible when I preview the file using Windows' built-in preview feature. If I open the file in Adobe Acrobat and then save it (even without making any changes), the text fields become visible in Windows preview. I would like the filled fields to be visible in Windows preview immediately after the file is generated. I would appreciate any help. Thanks.

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 merge_pdfs(pdf_paths, output_path):
    writer = pdfrw.PdfWriter()

    for path in pdf_paths:
        reader = pdfrw.PdfReader(path)
        writer.addpages(reader.pages)
    writer.trailer.Root.AcroForm = pdfrw.PdfDict(NeedAppearances=pdfrw.PdfObject('true'))   
    writer.write(output_path)
    return output_path

def fill_pdf(input_pdf_path, output_pdf_path, data_dict):
    template_pdf = pdfrw.PdfReader(input_pdf_path)
    for page in template_pdf.pages:
        annotations = page[ANNOT_KEY]
        if annotations:
            for annotation in annotations:
                if annotation[SUBTYPE_KEY] == WIDGET_SUBTYPE_KEY and annotation[ANNOT_FIELD_KEY]:
                    key = annotation[ANNOT_FIELD_KEY][1:-1]  
                    if key in data_dict:
                        if type(data_dict[key]) == bool:  # Hantering för kryssrutor
                            annotation.update(
                                pdfrw.PdfDict(V=pdfrw.PdfName('On' if data_dict[key] else 'Off'),
                                              AS=pdfrw.PdfName('On' if data_dict[key] else 'Off')))
                        else:  # Hantering för textfält
                            annotation.update(
                                pdfrw.PdfDict(V='{}'.format(data_dict[key])))
                            annotation.update(pdfrw.PdfDict(AP=''))

    if template_pdf.Root and '/AcroForm' in template_pdf.Root:
        template_pdf.Root.AcroForm.update(pdfrw.PdfDict(NeedAppearances=pdfrw.PdfObject('true')))

    pdfrw.PdfWriter().write(output_pdf_path, template_pdf)

def fill_simple_pdf_file(data, template_input, template_output):
    return fill_pdf(template_input, template_output, data)