POI替换word文档文字,后台获取数据修改word文档中的数据
相信做做oa系统的都会遇到客户各种各样的奇葩的要求,以前我们只需要做权限,做功能就好了,但是现在我发现越来越多的客户
要求我们做一个导出excel文件的功能丶打印数据的功能,看起来好像很简单,但是做我们这行的都知道难做,主要是因为这种功能比较偏门,知道一些操作文档
API的人不多,所以今天给大家分享一个可以修改word文档数据的api
具体可以参考:
https://stackoverflow.com/questions/22268898/replacing-a-text-in-apache-poi-xwpf/22269035#22269035
第一步,我们需要添加poi-ooxml的依赖:
<!--<!– https://mvnrepository.com/artifact/org.apache.poi/poi –>--> <!--<dependency>--> <!--<groupId>org.apache.poi</groupId>--> <!--<artifactId>poi</artifactId>--> <!--<version>3.9</version>--> <!--</dependency>--> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency>
第二步,开始写工具类了:
package com.poi.word.util; import org.apache.poi.POIXMLDocument; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.xwpf.usermodel.*; import java.io.FileOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; public class DocWriter1 { public static void writer(String inputSrc, String outSrc, Map<String,String> map) { try { XWPFDocument doc = new XWPFDocument(POIXMLDocument.openPackage(inputSrc)); /** * 替换段落中指定的文本 */ for(XWPFParagraph p : doc.getParagraphs()){ List<XWPFRun> runs = p.getRuns(); if(runs != null){ for(XWPFRun r : runs){ //需要替换的文本 String text = r.getText(0); //替换指定的文本 for(String key : map.keySet()){ if(text != null && text.equals(key)){ //替换的时候要注意,setText是有两个参数的 //第一个是替换的文本,第二个是从哪里开始替换 //0是替换全部,如果不设置那么默认就是从原文字 //结尾开始追加 r.setText(map.get(key),0); } } } } } /** * 替换表格中指定的文字 */ for(XWPFTable tab : doc.getTables()){ for(XWPFTableRow row : tab.getRows()){ for(XWPFTableCell cell : row.getTableCells()){ //注意,getParagraphs一定不能漏掉 //因为一个表格里面可能会有多个需要替换的文字 //如果没有这个步骤那么文字会替换不了 for(XWPFParagraph p : cell.getParagraphs()){ for(XWPFRun r : p.getRuns()){ String text = r.getText(0); for(String key : map.keySet()){ if(text.equals(key)){ r.setText(map.get(text),0); } } } } } } } doc.write(new FileOutputStream(outSrc)); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException, InvalidFormatException { Map<String, String> map = new HashMap<String, String>(); map.put("people", "people"); for(int i =0; i<3;i++){ if(i ==0){ map.put("beginTime", "2018-01-01"); map.put("endTime", "2018-01-02"); map.put("${how}", "实施"); map.put("address", "南屏一中"); map.put("day", "1"); map.put("traffic", "滴滴"); map.put("zhusu", "100"); map.put("buzu", "50"); map.put("xiche", "30"); map.put("tingche", "50"); map.put("guoqiao", "50"); map.put("another", "20"); map.put("remark", "agree"); }else{ map.put("how"+i+"", "实施"); map.put("address"+i+"", "南平一中"); map.put("day"+i+"", "1"); map.put("traffic"+i+"", "滴滴"); map.put("zhusu"+i+"", "100"); map.put("buzu"+i+"", "50"); map.put("xiche"+i+"", "50"); map.put("tingche"+i+"", "20"); map.put("guoqiao"+i+"", "60"); map.put("another"+i+"", "40"); map.put("remark"+i+"", "agree"); } } map.put("bankAddress", "斗门交通银行支行"); map.put("bankNum", "46898566446464646898565"); map.put("people1", "people1"); map.put("people2", "people2"); map.put("people3", "people3"); map.put("sumMoney", "265"); map.put("isAgree", "agree"); map.put("writeTime", "2019-10-12"); map.put("remarkpro", "hello");
//文件路径 String srcPath = "D:\\word\\needle.docx";
//替换后新文件的路径 String destPath = "D:\\word\\output.docx"; writer(srcPath,destPath,map); } }
因为我写的是测试的没有应用到项目中,所以路径都是写死的,当然有需要的话可以直接响应回客户端下载,也可以放在服务器上面需要的时候再下载。
关于下载的话上一篇文章介绍有,其实这也可以实现打印功能的。
如果要实现打印的能的话,传过来数据替换掉生成新文件后调用打印功能打新文件打印就可以了
考虑到这个api的确比较偏门。所以我把word文档模板也贴出来吧