簡體   English   中英

如何使用itext從文本文件中的數據填寫(動態XFA)PDF

[英]How to use itext to fill out (dynamic XFA) PDF from data in a text file

我有一個本地PDF表單,該表單具有一個永不更改的特定模板。 由於沒有返回鍵集,因此我將表單標識為XFA(xml)動態表單。 我正在嘗試使用itext用.txt文件中包含的數據填寫表單。 根據我的理解,我需要以某種方式從文本文件中獲取數據並將其正確放置到.xml文件中,以便itext可以使用給定的xml來處理原始PDF。

表單具有以下布局作為示例:

例

我在Eclipse中使用的示例代碼可以成功編譯/運行,但需要使用data.xml中的數據,以便使用字段數據填充空表單並輸出填充的版本。 問題是,對於我的實際項目,我沒有要正確填充表單的data.xml文件。 原始字段數據在.txt文件中,每行包含PDF中不同字段的數據。

示例:參考上面的圖像,我的.txt文件看起來像這樣,直到包含(包括)“ FOUR”的字段為止的字段:

  • 約翰
  • 15
  • 黑色
  • 本田
  • 豐田汽車
  • 福特汽車
  • 寶馬

我對兩件事感到困惑:

1.如何提取原始PDF的xml結構,以便在使用.txt文件中的數據填充時知道要遵循的格式?

2.如何從文本文件中獲取值並將其正確插入.xml結構中?

以下代碼有效,但需要data.xml才能填寫“ incomplete.pdf”。 它使用代碼xfa.fillXfaForm(new FileInputStream(XML)); 輸入數據,但是我一直堅持如何識別“ XML”的結構以及如何首先填充它。

任何幫助表示贊賞,非常感謝。

碼:

package sandbox;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;


import java.io.PrintStream;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.XfaForm;


public class FillXFA {

    public static final String SRC = "C:/Workspace/PDF/incomplete.pdf";
    public static final String XML = "C:/Workspace/PDF/data.xml";
    public static final String DEST = "C:/Workspace/PDF/completed.pdf";

    public static void main(String[] args) throws IOException, DocumentException {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new FillXFA().manipulatePdf(SRC, DEST);
    }

    public void readXfa(String src, String dest)
            throws IOException, ParserConfigurationException, SAXException,
                TransformerFactoryConfigurationError, TransformerException {
            FileOutputStream os = new FileOutputStream(dest);
            PdfReader reader = new PdfReader(src);
            XfaForm xfa = new XfaForm(reader);
            Document doc = xfa.getDomDocument();
            Transformer tf = TransformerFactory.newInstance().newTransformer();
            tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            tf.setOutputProperty(OutputKeys.INDENT, "yes");
            tf.transform(new DOMSource(doc), new StreamResult(os));
            reader.close();
        }

    public void manipulatePdf(String src, String dest)
        throws IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        PdfStamper stamper = new PdfStamper(reader,
                new FileOutputStream(dest));
        AcroFields form = stamper.getAcroFields();
        XfaForm xfa = form.getXfa();
        xfa.fillXfaForm(new FileInputStream(XML));
        stamper.close();
        reader.close();
    }
}

在XFA中,表單字段和表單數據之間的鏈接是使用稱為數據綁定的概念進行的。 字段可以具有類似XPath的表達式,以從XML數據結構中選擇其值。 這意味着需要對XML數據進行適當的結構化以使其適合特定的XFA格式,但是此結構不一定是唯一的。

一個簡單的示例:假設您有一個僅包含1個文本字段的XFA表單。 該文本字段具有綁定到標簽名稱為“ Name”的任何XML元素的數據。 在這種情況下,您的data.xml可以簡單地是:

<Name>Hurmle</Name>

但是,這和無數種不同的XML結構也將起作用:

<StackOverflow>
    <accounts>
        <account>
            <Name>Hurmle</Name>
        </account>
    </accounts>
</StackOverflow>

您的代碼示例中的readXfa方法將用於從XFA表單中提取完整的XML流。 它由不同部分組成。 最相關的是:

  • template :描述邏輯表單結構,包括所有字段及其數據綁定。
  • xfa:datasets :保存有關數據的信息。 由2部分組成。
    • dataDescription :表單數據的模式,可選。 數據描述語法在XFA規范中定義。
    • xfa:data :表單數據。

確定哪種XML結構將起作用的一種方法是查看所有字段的數據綁定(參見template )。 因此,您將知道這些字段期望從何處獲取其數據。 對於非平凡的形式,這可能很復雜和/或需要大量工作。

如果在XFA表單中可用,則可以使用dataDescription 它將為您提供數據和信息的結構,例如元素的最小和最大出現次數。

最后,您可以查看已經采用格式的數據 (參見xfa:data )。 請記住,此XML結構不一定完整:可以省略空元素。 例如,如果一個表單有2個字段,則值可以指定為:

<SomeRoot>
    <Field1>Value1</Field1>
    <Field2></Field2>
</SomeRoot>

但是也:

<SomeRoot>
    <Field1>Value1</Field1>
</SomeRoot>

第一種情況將使您更容易找出所需的結構。 如果xfa:data丟失或不完整,您可以嘗試使用具有XFA功能的PDF查看器手動填寫所有表單字段。 保存時,查看器將根據數據描述和數據綁定填充xfa:data

供參考: XFA規范

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM