问题描述
我需要处理一些 PDF 文件并将它们的表单域内容添加到数据库中。
此文档没有设置安全方法,正如我在 PDF 查看器文档属性中看到的那样。
我尝试了我找到的建议 here。
当我使用 pdfminer(或 pdfminer.six)进行测试时,我没有收到错误消息,但它没有检索到任何字段。
import sys
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdftypes import resolve1
fname=r'D:\Atrium\Projects\CTFC\psgf\database\19022021\formulari-dinamic-redaccio-plans-simples-gestio-forestal_Filled.pdf'
fp = open(fname,'rb')
parser = PDFParser(fp)
doc = PDFDocument(parser)
fields = resolve1(doc.catalog['AcroForm'])['Fields']
for i in fields:
field = resolve1(i)
name,value = field.get('T'),field.get('V')
print('{0}: {1}'.format(name,value))
print('Done!')
解决方法
正如 mkl 所解释的,我的 PDF 文件以 XFA 格式存储表单数据,这是一种已弃用的格式。 XFA 是一组 XML 文档,我必须在每个文档中获取字段名称。
我使用 PyPDF2 库来做到这一点:
import PyPDF2 as pypdf
import xml.etree.ElementTree as ET
fname=r'form.pdf'
def findInDict(needle,haystack):
xlas = []
for key in haystack.keys():
try:
value=haystack[key]
except:
continue
if key==needle:
return value
if isinstance(value,dict):
x=findInDict(needle,value)
if x is not None:
return x
pdfobject=open(fname,'rb')
pdf=pypdf.PdfFileReader(pdfobject)
xfaparts=findInDict('/XFA',pdf.resolvedObjects)
for xfa in xfaparts:
if isinstance(xfa,pypdf.generic.IndirectObject):
xml = str(xfa.getObject().getData())
## Then process XML to find form tags