java - 使用java替换MS word Templete(Docx)中的文本
问题描述
我正在尝试在 docx 中搜索一个字符串并使用 java apache poi 替换为其他一些文本,但它正在替换随机出现的错误,因为 arrayIndexoutofbound Exception in line
"声明命名空间 w=' http://schemas.openxmlformats.org/wordprocessingml/2006/main ' .//w:ffData/w:name/@w:val")[0];
public class WordReplaceTextInFormFields {
private static void replaceFormFieldText(XWPFDocument document, String ffname, String text) {
boolean foundformfield = false;
for (XWPFParagraph paragraph : document.getParagraphs()) {
for (XWPFRun run : paragraph.getRuns()) {
XmlCursor cursor = run.getCTR().newCursor();
cursor.selectPath(
"declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:fldChar/@w:fldCharType");
while (cursor.hasNextSelection()) {
cursor.toNextSelection();
XmlObject obj = cursor.getObject();
if ("begin".equals(((SimpleValue) obj).getStringValue())) {
cursor.toParent();
obj = cursor.getObject();
obj = obj.selectPath(
"declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:ffData/w:name/@w:val")[0];
if (ffname.equals(((SimpleValue) obj).getStringValue())) {
foundformfield = true;
} else {
foundformfield = false;
}
} else if ("end".equals(((SimpleValue) obj).getStringValue())) {
if (foundformfield)
return;
foundformfield = false;
}
}
if (foundformfield && run.getCTR().getTList().size() > 0) {
run.getCTR().getTList().get(0).setStringValue(text);
// System.out.println(run.getCTR());
}
}
}
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument(new FileInputStream("WordTemplate.docx"));
replaceFormFieldText(document, "Text1", "Моя Компания");
replaceFormFieldText(document, "Text2", "Аксель Джоачимович Рихтер");
replaceFormFieldText(document, "Text3", "Доверенность");
document.write(new FileOutputStream("WordReplaceTextInFormFields.docx"));
document.close();
}
}
它遗漏了一些字符串,它不会替换整个文档。请提供示例代码帮助
解决方案
我在https://github.com/centic9/poi-mail-merge的项目中做了类似的事情,它提供了基于 POI 的通用邮件合并功能。它使用了与 XmlBeans 稍有不同的功能,它替换文档的完整 XML 内容中的字符串,而不是单独替换每个段落。
private static void appendBody(CTBody src, String append, boolean first) throws XmlException {
XmlOptions optionsOuter = new XmlOptions();
optionsOuter.setSaveOuter();
String srcString = src.xmlText();
String prefix = srcString.substring(0,srcString.indexOf(">")+1);
final String mainPart;
// exclude template itself in first appending
if(first) {
mainPart = "";
} else {
mainPart = srcString.substring(srcString.indexOf(">")+1,srcString.lastIndexOf("<"));
}
String suffix = srcString.substring( srcString.lastIndexOf("<") );
String addPart = append.substring(append.indexOf(">") + 1, append.lastIndexOf("<"));
CTBody makeBody = CTBody.Factory.parse(prefix+mainPart+addPart+suffix);
src.set(makeBody);
}
}
推荐阅读
- javascript - 如何阻止页面重定向到上一个访问过的页面?
- git - 在我的 git repo 的子目录中合并上游
- c# - 存储库模式 - 如何组合数据库和内存实体?
- amazon-web-services - 如果我们可以使用 Instance Property 直接将 EIP 关联到实例,那么需要 EIPAssociation 资源吗?
- d3.js - 使用 C3/D3 修复饼图标签重叠
- javascript - 为 HTTP Post 请求从 JavaScript 函数转换为 Java
- angular - 将 .subscribe 的结果分配给它后未定义的接口数组
- r - 使用传单和 state_popup 交换地图结果
- dart - 我如何从库比蒂诺日期选择器中隐藏日期
- azure-data-factory-2 - 根据列的存在拆分数据因子管道