记录一次POI导出word文件的细节问题
首先百科一下POI是什么:
Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。通过字面意思,我们大概知道这个API是可以用来做 java 导出word 及excel 的。下面不废话了,直接总结一下,java 用模板导出 word 的方法。目前项目中我用到的方法分为两种(今天先说第一种)。
1.使用poi读取模板word,然后导出所需要的word。
先说一下准备工作:
1.1 所需jar 包:这里我使用的是poi-3.9 jar 包,下面上依赖:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.1</version>
</dependency>
1.2 模板文件 xxxx.docx
这里要说一下有一个小坑,poi-3.9 目前只支持读取 .docx 格式的 word,也就是office 2007以后的格式。请大家注意使用时把 word 模板改为 .docx 后缀名。然后就是准备好替换的模板,如下图:
PS:这里重点说明一下,一个问题,就是在输入占位符的时候,一定一定一定要是从做到右连续输入占位符,不然会被识别为多个片段,导致占位符不匹配,!!!!!!!困扰了我半天,所以来特此记录一下0.0
下面直接上代码,注意看步骤:
String path = request.getSession().getServletContext().getRealPath("/exceldemo/关于安排2017年市级机关住房解困资金的报告.docx");//获取模板路径
FileInputStream is = new FileInputStream(path);//读入流中
XWPFDocument xdf = new XWPFDocument(is);//新建一个word文档
//变量
Map<String, Object> params = new HashMap<String, Object>();
params.put("year", year);
params.put("month", month);
params.put("day", day);
params.put("win",win);
this.replaceText(xdf,params);//替换word中的变量。
这里用了一个方法replaceText(),就是替换变量的方法,代码如下:
/**
* 替换文档中的参数(word)
* @param doc
* @param params
*/
private void replaceText(XWPFDocument doc, Map<String, Object> params) {
Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
XWPFParagraph para;
while (iterator.hasNext()) {
para = iterator.next();
this.replaceInPara(para, params);
}
}
/**
* 替换段落中的参数(word)
* @param para
* @param params
*/
private void replaceInPara(XWPFParagraph para, Map<String, Object> params) {
List<XWPFRun> runs;
Matcher matcher;
if (matcher(para.getParagraphText()).find()) {
runs = para.getRuns();
for (int i=0; i<runs.size(); i++) {
XWPFRun run = runs.get(i);
String runText = run.toString();
matcher = matcher(runText);
if (matcher.find()) {
while ((matcher = matcher(runText)).find()) {
runText = matcher.replaceFirst(String.valueOf(params.get(matcher.group(1))));
}
para.removeRun(i);
//重新插入run里内容格式可能与原来模板的格式不一致
para.insertNewRun(i).setText(runText);
}
}
}
}
下面看看替换后的效果:
博客原址:https://blog.csdn.net/ahutdbx/article/details/81326092