Как заполнять 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
Является ли это возможным. Любые предложения будут полезны.
5 ответов
Я написал библиотеку, основанную на:'pdfrw', 'pdf2image', 'Pillow', 'PyPDF2', под названием fillpdf (
pip install fillpdf
и зависимость от Поплера
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')
Вы можете найти поля формы здесь:
pdf.Root.AcroForm.Fields
или здесь
pdf.Root.Pages.Kids[page_index].Annots
Это объект PdfArray. В основном список. Название поля находится здесь:
pdf.Root.AcroForm.Fields[field_index].T
Другие ключи включают значение.V Существует куча отображаемой информации, например, шрифт и т. Д. В.AP.N.Resources
Однако, если вы обновите значение для поля и выведете файл PDF. Он может отображать значение только тогда, когда поле имеет фокус, т.е.
Я еще не понял, как это исправить.
Используйте это для заполнения всех полей, если они проиндексированы.
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)
Здесь было предоставлено полное решение: как редактировать редактируемый PDF-файл с помощью библиотеки pdfrw?
Ключевой частью является:
template_pdf.Root.AcroForm.update(pdfrw.PdfDict(NeedAppearances=pdfrw.PdfObject('true')))
Формы на основе 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()