相信做做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文檔模板也貼出來吧