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." 文本内的文本。可能有更有效的方法来执行此操作,但这是我发现的方法。
我开始使用 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." 文本内的文本。可能有更有效的方法来执行此操作,但这是我发现的方法。