2017-12-12 3 views
2

Java 및 iText 7을 사용하여 데이터를 구문 분석 (및 수정)하기 위해 XFA PDF 양식에서 XML 데이터를 정확하게 분석하려고하지만 동일한 작업을 수행하기 위해 모든 기본 데이터를 수집합니다. 내가 사용하는 모든 XFA 파일.iText 7 (또는 기타)을 사용하여 Java의 XFA PDF 문서에서 XML을 추출하는 방법은 무엇입니까?

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 = [email protected]: 

> 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] 

답변

1

파일이 순수 XFA 파일입니다. 즉,이 파일에 저장된 유일한 PDF 내용은 "Please wait ..."메시지로 구성됩니다. 이 페이지는 XFA를 렌더링하는 방법을 모르는 PDF 뷰어에 표시됩니다.

사용하는 페이지에서 내용을 추출 할 때 그것은 또한 당신이 얻는 내용이다 : 모든 관련 콘텐츠가 저장되어 있기 때문에,

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

이 순수 XFA 파일을 직면 할 때하지 말아야 할 일이있다 PDF 파일 내에 저장된 XML 스트림.

당신은 이미 첫 부분의 권리가 있습니다 :

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 파일을 만들고 FAQ에 설명 된대로 양식을 채우는 것이 좋습니다. How to fill out a pdf file programmatically? (Dynamic XFA)

+0

정확히 내가 한 것! 완벽하게 작동합니다! 고맙습니다! – Bryan

관련 문제