Как заполнять формы PDF с помощью Python

У меня есть PDF form, созданный с использованием Adobe LiveCycle Designer ES 10.4. Мне нужно заполнить его Python, чтобы уменьшить ручной труд. Я поискал в Интернете и прочитал несколько статей, большинство из которых были посвящены библиотеке pdfrw, я попытался использовать ее и извлек некоторую информацию из PDF form, как показано ниже.

Код

from pdfrw import PdfReader
pdf = PdfReader('sample.pdf')
print(pdf.keys())
print(pdf.Info)
print(pdf.Root.keys())
print('PDF has {} pages'.format(len(pdf.pages)))

Вывод

['/Root', '/Info', '/ID', '/Size']
{'/CreationDate': "(D:20180822164509+05'30')", '/Creator': '(Adobe LiveCycle Designer ES 10.4)', '/ModDate': "(D:20180822165611+05'30')", '/Producer': '(Adobe XML Form Module Library)'}
['/AcroForm', '/MarkInfo', '/Metadata', '/Names', '/NeedsRendering', '/Pages', '/Perms', '/StructTreeRoot', '/Type']
PDF has 1 pages

Я не уверен, как еще я могу использовать pdfrw для доступа к заполняемым полям из формы PDF и заполнения их с помощью Python, возможно ли это. Любые предложения будут полезны.


person Atinesh    schedule 21.09.2018    source источник
comment
Формы, созданные в Adobe LiveCycle Designer ES 10.4, бывают двух видов, и ваша задача будет отличаться в зависимости от того, какая у вас есть. Designer может создать статическую форму XFA, которая содержит обычную форму PDF с полями, а также компонент XML для всей логики и сценариев. В качестве альтернативы у вас может быть динамическая форма XFA, которая вообще не содержит формы PDF, но полагается на Adobe Reader (и несколько других программ просмотра) для визуализации XML в форму на лету. Мой ответ будет зависеть от того, какой у вас тип формы.   -  person joelgeraci    schedule 21.09.2018
comment
@joelgeraci У меня есть PDF form, я не знаю, как он создан. Я могу открыть его в Acrobat Reader.   -  person arush1836    schedule 22.09.2018
comment
Вы можете поделиться файлом, я могу определить тип формы.   -  person joelgeraci    schedule 22.09.2018
comment
Возможный дубликат Как я могу автоматически заполнить PDF-форма в Django / Python?   -  person Gabriel Devillers    schedule 15.11.2018
comment
@joelgeraci В моем PDF-файле Producer отображается как «Библиотека модулей форм Adobe XML». Не могли бы вы помочь мне с этим вопросом, пожалуйста. stackoverflow.com/questions/62760343/   -  person    schedule 07.07.2020


Ответы (5)


Вы можете найти поля формы здесь:

pdf.Root.AcroForm.Fields

или здесь

pdf.Root.Pages.Kids[page_index].Annots

Это объект PdfArray. В основном список. Имя поля находится здесь:

pdf.Root.AcroForm.Fields[field_index].T

Другие ключи включают значение .V. В разделе .AP.N.Resources содержится множество отображаемой информации, например, о шрифте и т. Д.

Однако, если вы обновите значение поля и выведите файл pdf. Он может отображать значение только тогда, когда поле находится в фокусе, то есть при нажатии.

Я еще не понял, как это исправить.

person Eddie    schedule 01.12.2018

Используйте это для заполнения всех полей, если они проиндексированы.

template = PdfReader('template.pdf')
page_c = 0
while page_c < len(template.Root.Pages.Kids): #LOOP through pages
    annot_c = 0
    while annot_c < len(template.Root.Pages.Kids[page_c].Annots): #LOOP through fields
        template.Root.Pages.Kids[page_c].Annots[annot_c].update(PdfDict(V=str(annot_c)+'-'+str(page_c)))
        annot_c=annot_c+1
    page_c=page_c+1
PdfWriter().write('output.pdf', template)
person Asif Alam    schedule 08.11.2019

Я написал библиотеку, основанную на: 'pdfrw', 'pdf2image', 'Pillow', 'PyPDF2', под названием fillpdf (pip install fillpdf и зависимость от poppler conda install -c conda-forge poppler)

Основное использование:

from fillpdf import fillpdfs

fillpdfs.get_form_fields("blank.pdf")

# returns a dictionary of fields
# Set the returned dictionary values a save to a variable
# For radio boxes ('Off' = not filled, 'Yes' = filled)

data_dict = {
'Text2': 'Name',
'Text4': 'LastName',
'box': 'Yes',
}

fillpdfs.write_fillable_pdf('blank.pdf', 'new.pdf', data_dict)

# If you want it flattened:
fillpdfs.flatten_pdf('new.pdf', 'newflat.pdf')

Дополнительная информация здесь: https://github.com/t-houssian/fillpdf

Если некоторые поля не заполняются, вы можете использовать fitz (pip install PyMuPDF) и PyPDF2 (pip install PyPDF2), как показано ниже, изменяя точки по мере необходимости:

import fitz
from PyPDF2 import PdfFileReader

file_handle = fitz.open('blank.pdf')
pdf = PdfFileReader(open('blank.pdf','rb'))
box = pdf.getPage(0).mediaBox
w = box.getWidth()
h = box.getHeight()

# For images
image_rectangle = fitz.Rect((w/2)-200,h-255,(w/2)-100,h-118)
pages = pdf.getNumPages() - 1
last_page = file_handle[pages]
last_page._wrapContents()
last_page.insertImage(image_rectangle, filename=f'image.png')

# For text
last_page.insertText(fitz.Point((w/2)-247 , h-478), 'John Smith', fontsize=14, fontname="times-bold")
file_handle.save(f'newpdf.pdf')
person Tyler Houssian    schedule 26.03.2021
comment
Я пытаюсь установить poppler, как вы упомянули, и он просто зависает. У тебя был какой-нибудь трюк? Я пытаюсь прямо в приглашении анаконды. - person misterducky; 07.04.2021
comment
@misterducky Интересно. На этой странице можно попробовать несколько разных команд установки: https://anaconda.org/conda-forge/poppler. Смотрите также здесь: https://stackoverflow.com/questions/57330485/unable-to-install-poppler-on-windows-using-conda - person Tyler Houssian; 12.04.2021

Формы на основе AcroForm с использованием PDFix SDK

def SetFormFieldValue(email, key, open_path, save_path):
    pdfix  = GetPdfix()
    if pdfix is None:
        raise Exception('Pdfix Initialization fail')
    if not pdfix.Authorize(pdfix_email, pdfix_license):
        raise Exception('Authorization fail : ' + pdfix.GetError())
    doc = pdfix.OpenDoc(open_path, "")
    if doc is None:
        raise Exception('Unable to open pdf : ' + pdfix.GetError())
    field = doc.GetFormFieldByName("Text1")
    if field is not None:
        value = field.GetValue()
        value = "New Value"
        field.SetValue(value)
    if not doc.Save(save_path, kSaveFull):
        raise Exception(pdfix.GetError())
    doc.Close()
    pdfix.Destroy()
person paolo    schedule 14.11.2018

Здесь представлено полное решение: Как редактировать редактируемый PDF-файл с помощью библиотеки pdfrw?

Ключевой частью является:

template_pdf.Root.AcroForm.update(pdfrw.PdfDict(NeedAppearances=pdfrw.PdfObject('true'))) 
person Asensio    schedule 08.08.2019