POI不同版本替换Word模板时的问题
一、问题描述
通过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模板时的问题的更多相关文章
- 利用POI 技术动态替换word模板内容
项目中需要实现一个功能,动态替换给定模板里面的内容,生成word文档提供下载功能. 中间解决了问题有: 1.页眉的文档logo图片解决,刚开始的时候,HWPFDocument 对象无法读取图片对象(已 ...
- tp5 使用phpword 替换word模板并利用com组件转换pdf
tp5 使用phpword 替换word模板并利用com组件转换pdf 一.首先composer安装PHPword,就不多说了 二.然后是把模板中要替换的部分用变量代替 三.把原始的模板文件放入项 ...
- javascript下用ActiveXObject控件替换word书签,将内容导出到word后打印第1/2页
由于时间比较紧,没多的时候去学习研究上述工具包,现在用javascript操作ActiveXObject控件,用替换word模板中的书签方式解决. 最近有需求将数据导出到word里,然后编辑打印. 想 ...
- 【3】利用Word模板生成文档的总结
阅读目录 Word二次开发概况 使用DsoFramer进行开发 使用Interop进行开发 打开.关闭和写入操作 批量替换文本 遍历段落替换文本 查找后逐个替换文本 结论 在各类应用系统开发中,和Wo ...
- Open Xml SDK Word模板开发最佳实践(Best Practice)
1.概述 由于前面的引文已经对Open Xml SDK做了一个简要的介绍. 这次来点实际的——Word模板操作. 从本质上来讲,本文的操作都是基于模板替换思想的,即,我们通过替换Word模板中指定元素 ...
- Java中用Apache POI生成excel和word文档
概述: 近期在做项目的过程中遇到了excel的数据导出和word的图文表报告的导出功能.最后决定用Apache POI来完毕该项功能.本文就项目实现过程中的一些思路与代码与大家共享.同一时候.也作为自 ...
- 读取word模板,填充数据后导出
一.需求说明 定期生成word报告,报告中含有文本.表格.图表等元素,依次获取进行替换,保留原有样式,生成新的word文档 二.引入依赖 <dependency> <groupId& ...
- C# 利用占位符替换word中的字符串和添加图片
利用占位符替换word中的字符串和添加图片 ///<summary> /// 替换word模板文件内容,包括表格中内容 /// 调用如下:WordStr ...
- POI Word 模板 文字 图片 替换
实验环境:POI3.7+Word2007 Word模板: 替换后效果: 代码: 1.入口文件 public class Test { public static void main(String[] ...
随机推荐
- Linux JDK配置
第一步:下载jdk-7-linux-i586.tar.gz wget -c http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-linux-i586 ...
- Ngnix技术研究系列2-基于Redis实现动态路由
上篇博文我们写了个引子: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 发现了新大陆,OpenResty OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台 ...
- [js高手之路] javascript面向对象写法与应用
一.什么是对象? 对象是n个属性和方法组成的集合,如js内置的document, Date, Regexp, Math等等 document就是有很多的属性和方法, 如:getElementById, ...
- JavaScript 版数据结构与算法(一)栈
今天,我们要讲的是数据结构与算法中的栈. 栈的简介 栈是什么?栈是一个后进先出(LIFO)的数据结构.栈有啥作用?栈可以模拟算法或生活中的一些后进先出的场景,比如: 十进制转二进制,你需要将余数倒序输 ...
- CSS div阴影效果
<div class="image"><img src="default.jpg" /></div> .image{box- ...
- Java视频扩展知识 线程池的了解
Java视频扩展知识 线程池的了解 1.简单介绍: Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用.为我们在开发中处理线程的 ...
- 为什么阿里的程序员那么帅?---原来他们都有"编码规约扫描"神器在手
为了迎接十九大的到来,帝都城这几天也是满城风雨,听说早高峰期地铁站的人都排到天桥上了,哎,这就是该死的北漂生活.但是无论怎样,我依然在北京向各位问好! 之前总结过俩篇关于阿里Java开发手册的编程规约 ...
- vue-cli 自定义指令directive 添加验证滑块
vue项目注册登录页面遇到了一个需要滑块的功能,网上看了很多插件发现都不太好用,于是自己写了一个插件供大家参考: 用的是vue的自定义指令direcive,只需要在需要的组件里放入对应的标签嵌套即可: ...
- win10 uwp 上传Nuget 让别人用我们的库
Nuget 我们的开发经常使用别人的dll,那么我们需要每次都从网上下载,然后复制到我们的项目, 而不知道我们的dll是否安全? 当我们的库更新的时候,我们又需要从网上搜索,这样不好,于是我们就用Nu ...
- WPF MVVM模式的一些理解
/*本文转自 http://www.cnblogs.com/sirkevin/archive/2012/11/28/2793471.html */ 使用WPF+Mvvm开发一年多,期间由于对Mvvm模 ...