天天看點

Java-POI替換Word模闆文檔中的變量,生成Word文檔第一步:在項目中導入POI的jar包,以及相關的jar包。第二步:建立util工具類。第三步:在項目的對應目錄下放入Word模闆。第四步:導出Word的java實作。後語

第一步:在項目中導入POI的jar包,以及相關的jar包。

所需的jar包清單:

Java-POI替換Word模闆文檔中的變量,生成Word文檔第一步:在項目中導入POI的jar包,以及相關的jar包。第二步:建立util工具類。第三步:在項目的對應目錄下放入Word模闆。第四步:導出Word的java實作。後語

下載下傳位址:http://download.csdn.net/download/qq_34908167/10046670

第二步:建立util工具類。

public class DocxUtil{
    /**
      * @Description: 将t中的字段轉換成替換模闆需要的資料${字段}-->字段值
*      在word模闆中變量為${valuename},為每個值建一個以‘${valuename}’為鍵,‘value’為值的Map集合,
*      利用鍵去和Word模闆中尋找相等的變量
     */
    public <T> Map<String, String> copyParamFromBean(T t, Map<String, String> params) {
        Field[] fields = t.getClass().getDeclaredFields();
        String key;
        String value;
        for (Field field : fields) {
            String fieldName = field.getName();
            key = "${" + fieldName + "}";
            String name = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            try {
                value = String.valueOf(t.getClass().getMethod(name).invoke(t));
                params.put(key, value);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return params;
    }
/***
*替換Word模闆中的對應變量。
*兩種情況:1-段落中的變量。 2-表格中的變量
*/
 public static void searchAndReplace(XWPFDocument document,Map<String, String> map) {
        try {
            // 替換段落中的指定文字
            Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();//獲得word中段落
            while (itPara.hasNext()) {       //周遊段落
                XWPFParagraph paragraph = (XWPFParagraph) itPara.next();
                Set<String> set = map.keySet();
                Iterator<String> iterator = set.iterator();
                while (iterator.hasNext()) {
                    String key = iterator.next();
                    List<XWPFRun> run=paragraph.getRuns();
                    for(int i=0;i<run.size();i++)
                    {
                        if(run.get(i).getText(run.get(i).getTextPosition())!=null &&
                                run.get(i).getText(run.get(i).getTextPosition()).equals(key))
                        {
                            /**
                             * 參數0表示生成的文字是要從哪一個地方開始放置,設定文字從位置0開始
                             * 就可以把原變量替換掉
                             */
                            run.get(i).setText(map.get(key),0);
                        }
                    }
                }
            }         
            // 替換表格中的指定文字
            Iterator<XWPFTable> itTable = document.getTablesIterator();//獲得Word的表格
            while (itTable.hasNext()) { //周遊表格
                XWPFTable table = (XWPFTable) itTable.next();
                int count = table.getNumberOfRows();//獲得表格總行數
                for (int i = 0; i < count; i++) { //周遊表格的每一行
                    XWPFTableRow row = table.getRow(i);//獲得表格的行
                    List<XWPFTableCell> cells = row.getTableCells();//在行元素中,獲得表格的單元格
                    for (XWPFTableCell cell : cells) {   //周遊單元格
                        for (Entry<String, String> e : map.entrySet()) {
                            if (cell.getText().equals(e.getKey())) {//如果單元格中的變量和‘鍵’相等,就用‘鍵’所對應的‘值’代替。
                                cell.removeParagraph(0);//是以這裡就要求每一個單元格隻能有唯一的變量。
                                cell.setText(e.getValue());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
/**
     * 關閉輸出流
     *
     * @param os
     */
    public void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
           

第三步:在項目的對應目錄下放入Word模闆。

這裡給出我的Word模闆:http://download.csdn.net/download/qq_34908167/10046772

第四步:導出Word的java實作。

public String exportDoc(){
        XWPFDocument doc = null;
        OutputStream out = null;
        FileInputStream in = null;
        DocxUtil docxUtil = null;
        try {
            String rootPath = "";
            ServletContext context = servletRequest.getSession().getServletContext();
            String studentId = this.servletRequest.getParameter("studentid");//得到頁面的參數
            RankExportDocVO docVo=null;
            if (studentId!=null) {
                rootPath = context.getRealPath("/docmodel/PG/RankPrintAll_WordTemplate.docx");//Word模闆所在的路徑
                docVo = rankPrintService.queryStudentInfo((studentId);//調用service得到對應的VO類
            }else{
                throw new Exception("傳輸字段為空!");
            }
            Map<String, String> params = new HashMap<String, String>();
            docxUtil = new DocxUtil();
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(rootPath));//讀取Word模闆
            docxUtil.copyParamFromBean(docVo, params);//調用DocxUtil中的copyParamFromBean方法,為VO的每個值建立“${valuename}”鍵
            docxUtil.searchAndReplace(document, params);//替換模闆中的對應變量。
            // 清空response
            this.servletResponse.reset();
            // 設定response的Header
            String userAgent = this.servletRequest.getHeader("User-Agent");
            String realname = "學生資訊文檔_"+docVo.getXm()+".docx";//最終導出文檔的新文檔名
            if (userAgent.contains("Firefox")) {
                // 采用BASE64編碼
                realname = "=?UTF-8?B?" + new BASE64Encoder().encode(realname.getBytes("utf-8")) + "?=";
            } else {
                // 其它浏覽器 IE 、google 采用URL編碼
                realname = URLEncoder.encode(realname, "utf-8");
                realname = realname.replace("+", " ");
            }
            servletResponse.setHeader("Content-Disposition", "attachment;filename=" + realname);
            String minitype = ServletActionContext.getServletContext().getMimeType(realname);
            servletResponse.setContentType(minitype);
            out = this.servletResponse.getOutputStream();
            document.write(out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != docxUtil) {
                docxUtil.close(out);//關閉流
            }
        }
        return null;
    }
           

這就是利用Java-poi技術導出Word文檔的全部步驟。

這樣的好處,就在于我們可以根據需求制定我們需要的Word樣式。

後語

注意事項:

1:Word模闆中,表格的單元格的變量必須是唯一的,如果需要多個變量,我們可以利用word的隐藏表格功能,

來實作視覺上的一個單元格有多個變量的效果。

2:Word模闆中的變量左右不能有空格,不然不能識别。

3:都 9102 年了,還在看java-poi嗎?去看看我的另外一篇使用freemaker來根據模闆定制word文檔的博文吧:

Java-Freemarker替換模闆檔案.ftl中的變量,生成Word文檔

-----------------------------------------------------------------------------------------不關注我“象話”嗎?(哈哈,逗比)

繼續閱讀