POI不同版本替换Word模板时的问题
一、問題描述
通過POI,把Word中的占位符替換為實(shí)際的值,以生成復(fù)雜結(jié)構(gòu)的業(yè)務(wù)報(bào)告。
在POI 3.9上,功能正常。由于某些原因升級到POI 3.10.1后,項(xiàng)目組反饋說Word模板出錯,無法生成Word文件,總是報(bào)解析錯誤。
?
二、問題分析
Word模板功能相關(guān)的代碼應(yīng)該說是比較穩(wěn)定了,相關(guān)代碼很久沒有變動過,而且已經(jīng)有投產(chǎn)項(xiàng)目在正式使用。現(xiàn)在出了問題,應(yīng)該是升級POI版本導(dǎo)致的。
Word模板內(nèi)容示例:
本期產(chǎn)品為向${ds:ds001,col:INVESTER_TYPE_NAME}發(fā)行的混合類理財(cái)產(chǎn)品,本期產(chǎn)品投資期限為${ds:ds001,col:TERM}天,收益率為${ds:ds001,col:YTM_100}%/年,為${ds:ds001,col:INCOME_TYPE_NAME}類產(chǎn)品,到期還本付息。是一款具有投資安全性高、回報(bào)率高重點(diǎn)的理財(cái)產(chǎn)品。
分析、調(diào)試代碼。發(fā)現(xiàn)兩個版本的POI在處理Paragraph.getRuns()有區(qū)別:
3.9版本:一個段落就是一個XWPFRun;
3.10.1版本:一個段落不知道根據(jù)什么規(guī)則,胡亂分成了List<XWPFRun>。如上述示例模板,會被切換為長度為14的List;
這樣就導(dǎo)致獲取、替換段落文本時(shí)出錯。
?
三、問題解決
問題被定位后,就嘗試解決。主要的思路,就是強(qiáng)制把List中的內(nèi)容合并成一個字符串,替換內(nèi)容后,把段落中的XWPFRun全部remove掉,然后新建一個含有替換后內(nèi)容的XPWFRun,并賦給當(dāng)前段落。
解決問題的過程中,“對于removeRun方法無法達(dá)到本應(yīng)達(dá)成的預(yù)期效果的問題”,耗費(fèi)了不少時(shí)間。總結(jié)來說:不能從0到size()移除Run,這樣的話Run不會被移除;而應(yīng)該從size()到0進(jìn)行移除。
需要繼續(xù)關(guān)注表格替換時(shí)是否會有問題。
解決這類第三方軟件引起的問題,幾乎沒有道理可言,如果不想被埋在相關(guān)源代碼中,只能靠經(jīng)驗(yàn)+運(yùn)氣。
?
四、附代碼
在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);
??? }
}
?
轉(zhuǎn)載于:https://www.cnblogs.com/yujj-cn/p/4915431.html
總結(jié)
以上是生活随笔為你收集整理的POI不同版本替换Word模板时的问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: storm生产环境部署问题
- 下一篇: iOS 第五期考核题(字典与数组嵌套,字