2012-05-10 17 views
4

PDFBoxのJavaライブラリを使用してPDFフォームに記入したいと思います。 PDFフォームはAdobe Live Designerで作成されるため、XFA形式を使用します。XBoxとPDFBoxの組み合わせ

XFA PDFフォームをPDFBoxで埋め尽くすためのリソースを見つけようとしていますが、これまでのところ運がありません。私はPDAcroForm.setXFAメソッドがAPIで利用可能であることを知っていましたが、私はそれをどのように使用するか分かりません。

PDFフォームにPDFBoxを記入することが可能かどうか知っていますか? 「はい」の場合は、これを実現するコードサンプルまたはチュートリアルはありますか? いいえの場合は、これを達成するための最良の方法は何ですか?

答えて

2

私はpdfboxに慣れていませんが、XFA(XML)DOMにアクセスするとiText(http://itextpdf.com/)でこれを行うことができます。

+0

私は最終的にitextを選択しました。 – OutOfBound

-1

AcroFormは静的フィールドを持つPDF用です。 PDFにxfaフォームがある場合は、itext(Java)またはitextsharp(.net)を使用してデータを取り込むことができます。 XFAフォームで問題が発生するのは、フラットファイルに変換できないということです。フラットファイルには、bullzipやそれに類似したPDFファイル作成ツールを使用してxfa pdfを作成し、bullzipでフラットファイル形式に変換します。これがあなたにいくつかのアイデアを与えることを望みます。

以下のコードは、xfaがどのように満たされているかを概略的に示しています。

XfaForm xfa = pdfFormFields.Xfa; 
dynamic bytes = Encoding.UTF8.GetBytes("<?xml version=\"1.0\" encoding=\"UTF-8\"?> <form1> <staticform>" + "\r\n<barcode>" + barcode + "</barcode></staticform> <flowForm><Extra>" + Extra + "</Extra></flowForm> </form1>"); 
MemoryStream ms = new MemoryStream(bytes); 
pdfStamper.AcroFields.Xfa.FillXfaForm(ms); 

あなたは今、あなたが作成したXFA PDFファイルを使用してbullzip

のconst文字列PRINTER_NAME = "BullZip PDF Printerは続き" を通じて印刷することができます。

    PdfSettings pdfSettings = new PdfSettings(); 
        pdfSettings.PrinterName = Printer_Name; 
        pdfSettings.SetValue("Output", flatten_pdf); 
        pdfSettings.SetValue("ShowPDF", "no"); 
        pdfSettings.SetValue("ShowSettings", "never"); 
        pdfSettings.SetValue("ShowSaveAS", "never"); 
        pdfSettings.SetValue("ShowProgress", "no"); 
        pdfSettings.SetValue("ShowProgressFinished", "no"); 
        pdfSettings.SetValue("ConfirmOverwrite", "no"); 
        pdfSettings.WriteSettings(PdfSettingsFileType.RunOnce); 
        PdfUtil.PrintFile(xfa_pdffile, Printer_Name); 

出力ファイルは、PDFを平らになります。..

+5

さて、私たちは常に**コードが必要です。だから缶を提供できるなら、それを提供する。 – j0k

+0

これはJavaとタグ付けされた質問です。 Java用のBullzipは使用できません。 –

5

質問は、具体的対象にPDFBoxライブラリを識別します。 iTextは必要ありませんが、PDFBox 1.8で利用可能なPDXFAオブジェクトを使用してXFAの操作を行うことができます。

PDFBox + XFAでの彼の素晴らしい仕事のMaruan Sahyounに感謝します。

このコードは、PDDocumentのすべてのセキュリティを削除する場合にのみ機能します。
また、PDXFAのCOSオブジェクトがCOSStreamであることを前提としています。 以下の単純な例では、xmlストリームを読み込んでPDFに書き戻しています。

PDDocument doc = PDDocument.load("filename"); 
doc.setAllSecurityToBeRemoved(true); 

PDDocumentCatalog docCatalog = doc.getDocumentCatalog(); 
PDAcroForm form = docCatalog.getAcroForm(); 

PDXFA xfa = form.getXFA(); 
COSBase cos = xfa.getCOSObject(); 
COSStream coss = (COSStream) cos; 
InputStream cosin = coss.getUnfilteredStream(); 
Document document = documentBuilder.parse(cosin); 

COSStream cosout = new COSStream(new RandomAccessBuffer()); 
OutputStream out = cosout.createUnfilteredStream(); 

TransformerFactory tFactory = TransformerFactory.newInstance(); 
Transformer transformer = tFactory.newTransformer(); 
DOMSource source = new DOMSource(xmlDoc); 
StreamResult result = new StreamResult(out); 
transformer.transform(source, result); 

PDXFA xfaout = new PDXFA(cosout); 
form.setXFA(xfaout); 
+0

上記のコードでは、 "documentBuilder"とは何ですか? –

+0

私は上記のコードを使用して、結果のファイルがかなり大きいので少し気になります。 PDFファイルは647kb pdfで始まります。新しいpdf 14000kb。誰もが、新しいファイルのサイズをどのように縮小できるかを知っています。 pdfファイルに書き戻すときに、いくつかの種類の圧縮を設定できますか? – chamalabey

+0

JammyDodgerコードは、XMLにアクセスする方法と、それを戻す方法のみを示しています。フィールドの検索方法、値の設定方法を表示しないでください。 DocumentBuilderは、私が見る限り、javax.xml.parsers.DocumentBuilderFactoryを持つjavax.xml.parsers.DocumentBuilderを取得します。未定義の変数xmlDocはドキュメントです(私の推測) –

3

これは、私が問題に割り当てられた時間に管理できた最高です。私はpdfを(ライフサイクルで)最適化して保存する(私はpdfをやっている人ではない)。これは、PDFのオープン部分であり、XMLの複製と保存です。

PDDocument document = PDDocument.load(fileInputStream); 
    fileInputStream.close(); 
    document.setAllSecurityToBeRemoved(true); 

    Map<String, String> values = new HashMap<String, String>(); 
    values.put("variable_name", "value"); 


    setFields(document, values); // see code below 

    PDAcroForm form = document.getDocumentCatalog().getAcroForm(); 
    Document documentXML = form.getXFA().getDocument(); 

    NodeList dataElements = documentXML.getElementsByTagName("xfa:data"); 
    if (dataElements != null) { 
     for (int i = 0; i < dataElements.getLength(); i++) { 
      setXFAFields(dataElements.item(i), values); 
     } 
    } 

    COSStream cosout = new COSStream(new RandomAccessBuffer()); 

    TransformerFactory.newInstance().newTransformer() 
      .transform(new DOMSource(documentXML), new StreamResult(cosout.createUnfilteredStream())); 

    form.setXFA(new PDXFA(cosout)); 

    FileOutputStream fios = new FileOutputStream(new File(docOut + ".pdf")); 
    document.save(fios); 
    document.close(); 
    try { 
     fios.flush(); 
    } finally { 
     fios.close(); 
    } 

フィールドの値を設定するメソッドです。

public void setXFAFields(Node pNode, Map<String, String> values) throws IOException { 
    if (values.containsKey(pNode.getNodeName())) { 
     pNode.setTextContent(values.get(pNode.getNodeName())); 
    } else { 
     NodeList childNodes = pNode.getChildNodes(); 
     if (childNodes != null) { 
      for (int i = 0; i < childNodes.getLength(); i++) { 
       setXFAFields(childNodes.item(i), values); 
      } 
     } 
    } 
} 

public void setFields(PDDocument pdfDocument, Map<String, String> values) throws IOException { 

    @SuppressWarnings("unchecked") 
    List<PDField> fields = pdfDocument.getDocumentCatalog().getAcroForm().getFields(); 
    for (PDField pdField : fields) { 
     setFields(pdField, values); 
    } 
} 

private void setFields(PDField field, Map<String, String> values) throws IOException { 
    List<COSObjectable> kids = field.getKids(); 
    if (kids != null) { 
     for (COSObjectable pdfObj : kids) { 
      if (pdfObj instanceof PDField) { 
       setFields((PDField) pdfObj, values); 
      } 
     } 
    } else { 
     // remove the [0] from the name to match values in our map 
     String partialName = field.getPartialName().replaceAll("\\[\\d\\]", ""); 
     if (!(field instanceof PDSignatureField) && values.containsKey(partialName)) { 
      field.setValue(values.get(partialName)); 
     } 
    } 
} 

この作品は、なく、PDFのライフサイクルの農産物のすべての「種類」のために、いくつかは、「拡張fonctionは」もはや有効ですが、まだ動作していないという警告メッセージが表示されました:私はXFAとAcroFormの両方を設定します。最適化されたバージョンは、私が見つけた唯一のものです。

私はXFAとAcroformを埋めます。そうでないと、すべてのビューアで動作しません。

関連する問題