gpt4 book ai didi

java - 如何使用 iText 7(或其他)从 Java 中的 XFA PDF 文档中提取 XML?

转载 作者:数据小太阳 更新时间:2023-10-29 02:28:42 31 4
gpt4 key购买 nike

使用 Java 和 iText 7,我试图从 XFA PDF 表单中提取 XML 数据以解析(并可能修改)数据,但我所能做的就是获取一些相同的基本通用数据对于我使用的任何 XFA 文件。

我知道它必须是可能的,因为它是在 iText RUPS 工具中完成的,但我已经绕了好几天了。

public class Parse {

private PdfDocument pdf;
private PdfAcroForm form;
private XfaForm xfa;
private Document domDocument;
private Map<Integer, String> data;
private int numberOfPages;
private String pdfText;

public void openPdf(String src, String dest) throws IOException, TransformerException {

PdfReader reader = new PdfReader(src);
reader.setUnethicalReading(true);
pdf = new PdfDocument(reader, new PdfWriter(dest));
form = PdfAcroForm.getAcroForm(pdf, true);

data = new HashMap<Integer, String>();
numberOfPages = getNumberOfPdfPages();
PdfPage currentPage;
String textFromPage;

for (int page = 1; page <= numberOfPages; page++) {
System.out.println("Reading page: " + page + " -----------------");
currentPage = pdf.getPage(page);
textFromPage = PdfTextExtractor.getTextFromPage(currentPage);
data.put(page, textFromPage);
pdfText += currentPage + ":" + "\n" + textFromPage + "\n";
}


xfa = form.getXfaForm();
domDocument = xfa.getDomDocument();
Map<String, Node> map = xfa.extractXFANodes(domDocument);

System.out.println("The template node = " + map.get("template").toString() + "\n");
System.out.println("Dom document = " + domDocument.toString() + "\n");
System.out.println("In map form = " + map.toString() + "\n");
System.out.println("pdfText = " + pdfText + "\n");

Node node = xfa.getDatasetsNode();
NodeList list = node.getChildNodes();

for (int i = 0; i < list.getLength(); i++) {
System.out.println("Get Child Nodes Output = " + list.item(i) + "\n");
}

}
}

这是我收到的通用输出。

Reading page: 1 -----------------
The template node = [template: null]

Dom document = [#document: null]

In map form = {template=[template: null], form=[form: null], xfdf=[xfdf: null], xmpmeta=[x:xmpmeta: null], datasets=[xfa:datasets: null], config=[config: null], PDFSecurity=[PDFSecurity: null]}

pdfText = nullcom.itextpdf.kernel.pdf.PdfPage@6fa38a:

> Please wait...
>
> If this message is not eventually replaced by the proper contents of
> the document, your PDF viewer may not be able to display this type of
> document. You can upgrade to the latest version of Adobe Reader
> for Windows®, Mac, or Linux® by visiting
> http://www.adobe.com/go/reader_download. For more assistance with
> Adobe Reader visit http://www.adobe.com/go/acrreader. Windows is
> either a registered trademark or a trademark of Microsoft Corporation
> in the United States and/or other countries. Mac is a trademark of
> Apple Inc., registered in the United States and other countries. Linux
> is the registered trademark of Linus Torvalds in the U.S. and other
> countries.

Get Child Nodes Output = [xfa:data: null]

最佳答案

您有一个纯 XFA 文件。这意味着存储在此文件中的唯一 PDF 内容包含“请稍候...”消息。该页面显示在不知道如何呈现 XFA 的 PDF 查看器中。

这也是您使用以下方法从页面中提取内容时获得的内容:

currentPage = pdf.getPage(page);
textFromPage = PdfTextExtractor.getTextFromPage(currentPage);

这是您在面对纯 XFA 文件时不应该做的事情,因为所有相关内容都存储在 XML 流中,而 XML 流存储在 PDF 文件中。

第一部分你已经答对了:

xfa = form.getXfaForm();
domDocument = xfa.getDomDocument();

XFA 流可在 /AcroForm 条目中找到。我知道这很尴尬,但这就是 PDF 的设计方式。那不是我们的选择,而且 XFA 在 PDF 2.0 中已被弃用,所以 XFA 无论如何都会消亡。当 XFA 最终死亡并被埋葬时,问题就会消失。

也就是说,您有一个 org.w3c.dom.Document 的实例,并且您想要获取存储在该对象中的 XML 文件。您不需要 iText 来执行此操作。例如在 Converting a org.w3c.dom.Document in Java to String using Transformer 中对此进行了解释

我使用以下代码片段在 XFA 文件上测试了该代码:

public static void main(String[] args) throws IOException, TransformerException {
PdfDocument pdf = new PdfDocument(new PdfReader(SRC));
PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
XfaForm xfa = form.getXfaForm();
Document doc = xfa.getDomDocument();
DOMSource domSource = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(domSource, result);
writer.flush();
System.out.println(writer.toString());
}

屏幕上的输出是包含我预期的所有 XFA 信息的 XDP XML 文件。

请注意,我在替换 XFA XML 文件时会很小心。最好不要干预 XFA 结构,而是创建一个只包含使用适当模式创建的数据的 XML 文件,并按照常见问题解答中的描述填写表格:How to fill out a pdf file programmatically? (Dynamic XFA)

关于java - 如何使用 iText 7(或其他)从 Java 中的 XFA PDF 文档中提取 XML?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47778469/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com