一、问题描述
通过POI,把Word中的占位符替换为实际的值,以生成复杂结构的业务报告。
在POI 3.9上,功能正常。由于某些原因升级到POI 3.10.1后,项目组反馈说Word模板出错,无法生成Word文件,总是报解析错误。
二、问题分析
Word模板功能相关的代码应该说是比较稳定了,相关代码很久没有变动过,而且已经有投产项目在正式使用。现在出了问题,应该是升级POI版本导致的。
Word模板内容示例:
本期产品为向${ds:ds001,col:INVESTER_TYPE_NAME}发行的混合类理财产品,本期产品投资期限为${ds:ds001,col:TERM}天,收益率为${ds:ds001,col:YTM_100}%/年,为${ds:ds001,col:INCOME_TYPE_NAME}类产品,到期还本付息。是一款具有投资安全性高、回报率高重点的理财产品。
分析、调试代码。发现两个版本的POI在处理Paragraph.getRuns()有区别:
3.9版本:一个段落就是一个XWPFRun;
3.10.1版本:一个段落不知道根据什么规则,胡乱分成了List<XWPFRun>。如上述示例模板,会被切换为长度为14的List;
这样就导致获取、替换段落文本时出错。
三、问题解决
问题被定位后,就尝试解决。主要的思路,就是强制把List中的内容合并成一个字符串,替换内容后,把段落中的XWPFRun全部remove掉,然后新建一个含有替换后内容的XPWFRun,并赋给当前段落。
解决问题的过程中,“对于removeRun方法无法达到本应达成的预期效果的问题”,耗费了不少时间。总结来说:不能从0到size()移除Run,这样的话Run不会被移除;而应该从size()到0进行移除。
需要继续关注表格替换时是否会有问题。
解决这类第三方软件引起的问题,几乎没有道理可言,如果不想被埋在相关源代码中,只能靠经验+运气。
四、附代码
在3.10.1下有问题的代码示意:
while (itPara.hasNext()) {
XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
int length = paragraph.getRuns().size();
if (length > 0) {
String text = paragraph.getText();
if (text.indexOf(tag) < 0) {
continue;
}
while (length-- > 0) {
paragraph.removeRun(0);
}
XWPFRun newrun = paragraph.insertNewRun(0);
newrun.setText(text.replace(tag, val));
}
}
修改后的代码示意:
while (itPara.hasNext()) {
XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
int length = paragraph.getRuns().size();
if (length > 0) {
String text = StringUtils.join(paragraph.getRuns().toArray());
if (text.indexOf(tag) < 0) {
continue;
}
for (int i = (length - 1); i >= 0; i--) {
paragraph.removeRun(i);
}
XWPFRun newRun = paragraph.insertNewRun(0);
text = text.replaceAll(tag, val);
newRun.setText(text, 0);
}
}
相关推荐
通过POI可实现根据word模板替换文中或者表格的关键字(包括给定表头动态追加表格)。业务需求我是在模板中直接插入图片(例如衬于文字下方),所有代码中没有插入图片代码。
java使用poi操作.doc word模板替换,循环插入表格
Apache poi 根据word模板生成word报表 替换 循环列表 图片,代码调试过了,修改相应的图片位置,word模板路径即可运行
给出Java-poi导出Word时,所需的Word模板。 注意:1,word模板中的表格单元格只能有唯一的变量。(如需多个变量,可以在word中隐藏表格来实现。) 2,word模板中变量前后不能有空格。
POI 替换word2007文本框的值POI,包含word表中的文本框的值,定义好word模板即可替换word中的值。
* poi-tl引擎实现world模板内容替换(支持docx) * 依赖poi-tl,commons-lang3, poi-ooxml-schemas, poi-ooxml, poi,slf4j
poi解析word模板,在需要填写 空白地方建立书签;程序遍历书签,并根据书签名称进行赋值。 <groupId>org.apache.poi <artifactId>poi <version>3.8 <groupId>org.apache.poi <artifactId>poi-ooxml ...
用于替换指定word模板中的对应内容,包括文字、表格、图片等等的替换
J2W Java 使用 POI 3.17根据Word 模板替换、操作书签
实现了POI根据模板导出word,实现文字、表格、图表的替换生成。支持生成多种结构的表格、图表,关键代码都添加了注释,简单易懂。 其中表格和图表都写了两种实现方式,既可以只传简单的参数生成多个同结构的表格和...
java 使用poi根据模版导出word文件 将文件中的标签替换成文字或者文件 文件中标签用{xxxx}生成新文件
jacob 替换word图片,rtf模板文件字符替换,字符替换成图片,docx4j操作word,itext,poi读取文档图片,条码生成插入文档等... 包和需要的文件都在里面,解压直接可以导入运行
测试Java操作97-2003word模板,测试替换书签内容,替换文本书签和表格内书签
完美市县了DOCX格式的模板文字替换与插入浮于文字上方的图片。
主要介绍了java poi设置生成的word的图片为上下型环绕以及其位置的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
java运用poi操作word,替换word中的占位符填充数据,并将多个word合并成一个word,附件是java代码和相关jar包,以及测试模板,需要注意是,只适用2007以上的word
将模板word文件中的关键字替换为其他文字或者图形。注意:word模板保存的时候一定得注意去掉拼写检查等插件,不然可能会造成无法识别而不能替换
完整的支持POI操作word以下功能: 1.替换模板数据 2,替换表格数据 3.word表格行内添加 4.word写入写出
一次更改多个窗体域内容及属性 ,模板生成docx文件 适用网页按模版生成doc文件,网页合同生成,等等。
2.使用poi填充word报表标签及表格数据技术,解决标签替换不生效、不到位、替换错误,中文乱码等常见问题。 3.使用jacob操作com组件技术将word转为PDF文件,解决转换后部分中文丢失、乱码、表格丢失、转换后失真等...