1

javaとdocx4jを使ってdocxファイルにデータを追加する方法を教えてください。

私がやっていることは、一部のフィールドが実行時に Java によってディールされる docx 形式のテンプレートを使用していることです。

私の問題は、新しいファイルを作成するデータのグループごとにあり、新しいファイルを1つのファイルに追加したいだけです。これはJavaストリームを使用して行われません

String outputfilepath = "e:\\Practice/DOC/output/generatedLatterOUTPUT.docx";
String outputfilepath1 = "e:\\Practice/DOC/output/generatedLatterOUTPUT1.docx";
WordprocessingMLPackage wordMLPackage;

public void templetsubtitution(String name, String age, String gender, Document document)
        throws Exception {

    // input file name
    String inputfilepath = "e:\\Practice/DOC/profile.docx";
    // out put file name

    // id of Xml file
    String itemId1 = "{A5D3A327-5613-4B97-98A9-FF42A2BA0F74}".toLowerCase();
    String itemId2 = "{A5D3A327-5613-4B97-98A9-FF42A2BA0F74}".toLowerCase();
    String itemId3 = "{A5D3A327-5613-4B97-98A9-FF42A2BA0F74}".toLowerCase();
    // Load the Package

    if (inputfilepath.endsWith(".xml")) {

        JAXBContext jc = Context.jcXmlPackage;
        Unmarshaller u = jc.createUnmarshaller();
        u.setEventHandler(new org.docx4j.jaxb.JaxbValidationEventHandler());

        org.docx4j.xmlPackage.Package wmlPackageEl = (org.docx4j.xmlPackage.Package) ((JAXBElement) u
                .unmarshal(new javax.xml.transform.stream.StreamSource(
                        new FileInputStream(inputfilepath)))).getValue();

        org.docx4j.convert.in.FlatOpcXmlImporter xmlPackage = new org.docx4j.convert.in.FlatOpcXmlImporter(
                wmlPackageEl);

        wordMLPackage = (WordprocessingMLPackage) xmlPackage.get();

    } else {
        wordMLPackage = WordprocessingMLPackage
                .load(new File(inputfilepath));
    }

    CustomXmlDataStoragePart customXmlDataStoragePart = wordMLPackage
            .getCustomXmlDataStorageParts().get(itemId1);
    // Get the contents
    CustomXmlDataStorage customXmlDataStorage = customXmlDataStoragePart
            .getData();
    // Change its contents
    ((CustomXmlDataStorageImpl) customXmlDataStorage).setNodeValueAtXPath(
            "/ns0:orderForm[1]/ns0:record[1]/ns0:name[1]", name,
            "xmlns:ns0='EasyForm'");

    customXmlDataStoragePart = wordMLPackage.getCustomXmlDataStorageParts()
            .get(itemId2);
    // Get the contents
    customXmlDataStorage = customXmlDataStoragePart.getData();
    // Change its contents
    ((CustomXmlDataStorageImpl) customXmlDataStorage).setNodeValueAtXPath(
            "/ns0:orderForm[1]/ns0:record[1]/ns0:age[1]", age,
            "xmlns:ns0='EasyForm'");

    customXmlDataStoragePart = wordMLPackage.getCustomXmlDataStorageParts()
            .get(itemId3);
    // Get the contents
    customXmlDataStorage = customXmlDataStoragePart.getData();
    // Change its contents
    ((CustomXmlDataStorageImpl) customXmlDataStorage).setNodeValueAtXPath(
            "/ns0:orderForm[1]/ns0:record[1]/ns0:gender[1]", gender,
            "xmlns:ns0='EasyForm'");

    // Apply the bindings
    BindingHandler.applyBindings(wordMLPackage.getMainDocumentPart());
    File f = new File(outputfilepath);
    wordMLPackage.save(f);
    FileInputStream fis = new FileInputStream(f);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] buf = new byte[1024];
    try {
        for (int readNum; (readNum = fis.read(buf)) != -1;) {
            bos.write(buf, 0, readNum);
        }
        // System.out.println( buf.length);

    } catch (IOException ex) {
    }
    byte[] bytes = bos.toByteArray();
    FileOutputStream file = new FileOutputStream(outputfilepath1, true);
    DataOutputStream out = new DataOutputStream(file);
    out.write(bytes);
    out.flush();
    out.close();

    System.out.println("..done");
}

public static void main(String[] args) {
  utility u = new utility();
  u.templetsubtitution("aditya",24,mohan);
}

前もって感謝します

4

2 に答える 2

4

私の理解が正しければ、あなたは基本的にドキュメントのマージについて話しているのです。使用できる 2 つの非常に単純なアプローチがあり、その有効性は、データの構造とその後の使用法に大きく依存します。

  1. PhilippeAuriach は、彼の回答で 1 つのアプローチについて説明しています。これは、インスタンス内のすべてのコンポーネントMaindocumentPartを別のインスタンスに追加することを伴います。最終的な docx ファイルに関しては、これは表示されるコンテンツを意味しdocument.xmlます。たとえば、ヘッダーとフッターは考慮されませんが、それで問題ない場合があります。

  2. 複数のドキュメントを要素として挿入することで、複数のドキュメントを 1 つの docx ファイルに挿入できますAltChunk(docx4j のドキュメントを参照してください)。これにより、あるWordファイルから別のWordファイル、ヘッダーなどすべてにすべてがもたらされます。これの欠点は、最終ドキュメントを開いて MS Word 自体に保存するまで、適切なフロー Word ファイルにならないことです (インポートされたコンポーネントは、docx バンドル内のスタンドアロン ファイルとして残ります)。「マージされた」ファイルを生成し、PDF をレンダリングするなどの操作を行う場合、これにより問題が発生します。マージされたコンテンツは単に無視されます。

より完全な (そして複雑な) アプローチは、「ディープ マージ」を実行することです。これにより、ドキュメント内に保持されているすべての参照が更新および維持されます。インポートされたコンテンツは、ドキュメントのメインの「フロー」の一部になる (つまり、個別の参照として保存されない) ため、最終結果は、PDF などにレンダリングできる適切にマージされたファイルになります。

これの欠点は、docx 構造と API に関する十分な知識が必要であり、かなりの量のコードを作成する必要があることです (代わりに、 Plutext の MergeDocx のライセンスを購入することをお勧めします)。

于 2013-08-23T17:16:04.983 に答える