docx4j、java 和 MS Word 模板的示例代码

Sample code for docx4j, java and MS Word templates

我开始使用 MS Word .dotx 模板中的一些内容控件(使用“开发人员工具”菜单)。我想做的是使用 Java 和 docx4j 库以编程方式添加一些文本。有谁知道我在哪里可以找到这方面的代码示例?

我在下面添加了我想要使用的内容控件的 XML 表示。在这种情况下,我想用我自己的文本替换文本 "Klicken Sie hier, um Text einzugeben."。

-<w:sdt>
-<w:sdtPr>
-<w:rPr>
<w:rStyle w:val="CAPITALS"/>
</w:rPr>
<w:alias w:val="Zeugnisart"/>
<w:tag w:val="Zeugnisart"/>
<w:id w:val="-1662376684"/>
-<w:placeholder>
<w:docPart w:val="DefaultPlaceholder_1082065158"/>
</w:placeholder>
<w:showingPlcHdr/>
<w:text/>
</w:sdtPr>
-<w:sdtEndPr>
-<w:rPr>
<w:rStyle w:val="Absatz-Standardschriftart"/>
<w:rFonts w:hAnsiTheme="minorHAnsi" w:asciiTheme="minorHAnsi"/>
<w:b w:val="0"/>
<w:bCs w:val="0"/>
<w:smallCaps w:val="0"/>
<w:spacing w:val="0"/>
<w:sz w:val="22"/>
</w:rPr>
</w:sdtEndPr>
<w:sdtContent>
<w:p w:rsidP="00D144D4" w:rsidRDefault="006D40B2" w:rsidR="00D144D4">
-<w:r w:rsidRPr="00372E7E">
-<w:rPr>
<w:rStyle w:val="Platzhaltertext"/>
</w:rPr>
<w:t>Klicken Sie hier, um Text einzugeben.</w:t>
</w:r>
</w:p>
</w:sdtContent>
</w:sdt>

我尝试了以下代码但没有成功:

private void replacePlaceholder(WordprocessingMLPackage template, String name, String placeholder ) throws Exception{       

    MainDocumentPart documentPart = template.getMainDocumentPart();
    HashMap<String, String> mappings = new HashMap<String, String>();
    mappings.put("Zeugnisart", "a new value");
    documentPart.variableReplace(mappings);
}

private void writeDocxToStream(WordprocessingMLPackage template, String target) throws IOException, Docx4JException {
    File f = new File(target);
    template.save(f);
}

关于我哪里出错的任何提示?

从您的说明来看,您似乎只想 VariableReplace

如果您想将其内容绑定到 XML 部分(通过 XPath),请参阅 ContentControlsMergeXML。当然,您需要先设置数据绑定(通过 SdtPr 中的 w:dataBinding 元素)。

我已经使用以下代码成功解决了这个问题:

private static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {

    List<Object> result = new ArrayList<Object>();
    if (obj instanceof JAXBElement) obj = ((JAXBElement<?>) obj).getValue();

    if (obj.getClass().equals(toSearch))
        result.add(obj); 
    else if (obj instanceof ContentAccessor) {
        List<?> children = ((ContentAccessor) obj).getContent();
        for (Object child : children) {
            result.addAll(getAllElementFromObject(child, toSearch));
        }
    }
    return result; 
}


private void replaceTextValue(WordprocessingMLPackage template, String name, String placeholder ) throws Exception{     

    List<Object> texts = getAllElementFromObject(template.getMainDocumentPart(), SdtBlock.class);

    for (Object text : texts) {         

        SdtBlock textElement = (SdtBlock) text;
        List<Object> cList = textElement.getSdtContent().getContent();

        SdtPr pr = textElement.getSdtPr();
        List<Object> al = pr.getRPrOrAliasOrLock();

        for (Object alias : al) {   // go through all SdtPr objects

            if ( alias.getClass().toString().contains("org.docx4j.wml.Tag")) {

                String CTagVal = ((org.docx4j.wml.Tag) alias).getVal(); 

                if (CTagVal.equalsIgnoreCase(placeholder))  {   

                ClassFinder finder = new ClassFinder(Text.class);
                new TraversalUtil(cList, finder);

                for (Object o : finder.results) {
                    Object o2 = XmlUtils.unwrap(o);
                    if (o2 instanceof org.docx4j.wml.Text) {
                    org.docx4j.wml.Text txt = (org.docx4j.wml.Text)o2;
                    txt.setValue(name);
                    } else {
                    System.out.println( XmlUtils.marshaltoString(o, true, true));
                    }
                    }

                }

        }           

    }
}
}

我调用 replaceTextValue 方法来更改标签内 "Klicken Sie hier, um Text einzugeben." 文本内的文本。可能有更有效的方法来执行此操作,但这是我发现的方法。