记录一次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

 

posted @ 2020-05-09 09:36  早上起床喝酸_奶  阅读(827)  评论(0编辑  收藏  举报