java - 替换文本框 docx4j 中的占位符
问题描述
我正在使用 docx4j。我有一个word文档,我在其中画了一个文本框。在那个文本框中,我有“dummyPlaceHolderInTextBox”这个词。我想用“testString”替换这个占位符,如下面我调用的方法所示。尽管我在 getAllElementFromObject 方法中将类更改为 CTTextbox.class,但这不起作用。我怎样才能做到这一点?
replacePlaceholder(wp, "testString", "dummyPlaceHolderInTextBox")
代替
private static void replacePlaceholder(WordprocessingMLPackage template, String name, String placeholder) {
List<Object> texts = getAllElementFromObject(template.getMainDocumentPart(), CTTextbox.class);
for (Object text : texts) {
Text textElement = (Text) text;
if (textElement != null && textElement.getValue() != null
&& placeholder != null && textElement.getValue().equals(placeholder)) {
textElement.setValue(name);
}
}
}
获取所有元素
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;
}
解决方案
我猜你的文本框看起来像:
<w:p w:rsidR="00000000" w:rsidRDefault="00880BC0">
<w:r>
<w:rPr>
<w:noProof/>
</w:rPr>
<mc:AlternateContent>
<mc:Choice Requires="wps">
<w:drawing>
<wp:anchor xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" allowOverlap="true" behindDoc="false" distB="45720" distL="114300" distR="114300" distT="45720" layoutInCell="true" locked="false" relativeHeight="251659264" simplePos="false" wp14:anchorId="19C599C7" wp14:editId="4CA921F6">
<wp:simplePos x="0" y="0"/>
<wp:positionH relativeFrom="column">
<wp:align>center</wp:align>
</wp:positionH>
<wp:positionV relativeFrom="paragraph">
<wp:posOffset>182880</wp:posOffset>
</wp:positionV>
<wp:extent cx="2360930" cy="1404620"/>
<wp:effectExtent b="11430" l="0" r="22860" t="0"/>
<wp:wrapSquare wrapText="bothSides"/>
<wp:docPr id="217" name="Text Box 2"/>
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"/>
</wp:cNvGraphicFramePr>
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
<wps:wsp xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
<wps:cNvSpPr txBox="true">
<a:spLocks noChangeArrowheads="true"/>
</wps:cNvSpPr>
<wps:spPr bwMode="auto">
<a:xfrm>
<a:off x="0" y="0"/>
<a:ext cx="2360930" cy="1404620"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:solidFill>
<a:srgbClr val="FFFFFF"/>
</a:solidFill>
<a:ln w="9525">
<a:solidFill>
<a:srgbClr val="000000"/>
</a:solidFill>
<a:miter lim="800000"/>
<a:headEnd/>
<a:tailEnd/>
</a:ln>
</wps:spPr>
<wps:txbx>
<w:txbxContent>
<w:p w:rsidP="00880BC0" w:rsidR="00880BC0" w:rsidRDefault="00880BC0">
<w:r>
<w:t>Some testString</w:t>
</w:r>
</w:p>
</w:txbxContent>
</wps:txbx>
<wps:bodyPr anchor="t" anchorCtr="false" bIns="45720" lIns="91440" rIns="91440" rot="0" tIns="45720" vert="horz" wrap="square">
<a:spAutoFit/>
</wps:bodyPr>
</wps:wsp>
</a:graphicData>
</a:graphic>
<wp14:sizeRelH relativeFrom="margin">
<wp14:pctWidth>40000</wp14:pctWidth>
</wp14:sizeRelH>
<wp14:sizeRelV relativeFrom="margin">
<wp14:pctHeight>20000</wp14:pctHeight>
</wp14:sizeRelV>
</wp:anchor>
</w:drawing>
</mc:Choice>
<mc:Fallback>
<w:pict>
<v:shapetype xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml" coordsize="21600,21600" id="_x0000_t202" path="m,l,21600r21600,l21600,xe" o:spt="202.0">
<v:stroke joinstyle="miter"/>
<v:path gradientshapeok="t" o:connecttype="rect"/>
</v:shapetype>
<v:shape xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:v="urn:schemas-microsoft-com:vml" id="Text Box 2" style="position:absolute;margin-left:0;margin-top:14.4pt;width:185.9pt;height:110.6pt;z-index:251659264;visibility:visible;mso-wrap-style:square;mso-width-percent:400;mso-height-percent:200;mso-wrap-distance-left:9pt;mso-wrap-distance-top:3.6pt;mso-wrap-distance-right:9pt;mso-wrap-distance-bottom:3.6pt;mso-position-horizontal:center;mso-position-horizontal-relative:text;mso-position-vertical:absolute;mso-position-vertical-relative:text;mso-width-percent:400;mso-height-percent:200;mso-width-relative:margin;mso-height-relative:margin;v-text-anchor:top" type="#_x0000_t202" o:gfxdata="UEsDBBQAB..AAAAhwUAAAAA" o:spid="_x0000_s1026">
<v:textbox style="mso-fit-shape-to-text:t">
<w:txbxContent>
<w:p w:rsidP="00880BC0" w:rsidR="00880BC0" w:rsidRDefault="00880BC0">
<w:r>
<w:t>Some testString</w:t>
</w:r>
</w:p>
</w:txbxContent>
</v:textbox>
<w10:wrap xmlns:w10="urn:schemas-microsoft-com:office:word" type="square"/>
</v:shape>
</w:pict>
</mc:Fallback>
</mc:AlternateContent>
</w:r>
</w:p>
在此示例中,请注意它使用 2 种替代格式表示:
- v:textbox/w:txbxContent
- wps:txbx/w:txbx内容
那是一个 org.docx4j.wml.CTTxbxContent
您的代码假定每个父对象都实现 ContentAccessor。我怀疑情况是否如此。
因此,如果您想做这样的事情,请尝试使用 TraversalUtil 更强大的 get children 的 org.docx4j.finders.ClassFinder。见https://github.com/plutext/docx4j/blob/master/docx4j-samples-docx4j/src/main/java/org/docx4j/samples/TraverseFind.java
在这里,我的包含“testString”的运行没有拆分,但在您的情况下这可能是一个问题(例如拼写/语法检查或编辑会话)。
作为一般性评论,这似乎是一种非常费力的 docgen 方式。有些人使用变量替换:https ://github.com/plutext/docx4j/blob/master/docx4j-samples-docx4j/src/main/java/org/docx4j/samples/VariableReplace.java但正如它所说的那样,对于复杂文档 我建议将内容控件绑定到 XML 部件(通过 XPath)
推荐阅读
- reactjs - 如何在 Create-react-app 应用程序中包含自定义脚本文件
- sed - sed 删除花括号之间的部分
- powershell - 获取windows服务失败动作值
- authentication - Twilio 两因素身份验证是否支持对特定扩展的调用
- xamarin - Xamarin 形成警告
- javascript - NodeJS:基于 MongoDB 条目在特定时间发送大量文本的最佳方式?
- laravel - 防止在两次输入时提交多个表单
- html - Angular ng serve 不在本地主机上托管站点
- javascript - 如何使python lambda返回逗号运算符最后一个
- javascript - 是否可以在 NodeJs 中要求子 sdk 库?