• 通过word文件模板生成word文件


    转自csdn:https://blog.csdn.net/qq_33465199/article/details/108149652

    首先加入依赖

                <dependency>
                    <groupId>org.apache.poi</groupId>
                    <artifactId>poi-scratchpad</artifactId>
                    <version>3.16</version>
                </dependency>
                <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>4.1.2</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>4.1.2</version>
            </dependency>

    代码里面有被注释的main方法,可以参考下,直接传入Map对象的参数就生成

    word文件内变量名需要{}来包裹,如下图

     map的key直接设置为{}内的变量名就行,会自动去匹配 {变量名} ,下面上代码

    package com.sjyf.gym.utils;
    
    /**
     * @Title: WordTemplate2.java
     * @Package: com.highdata.templateTools
     * @Description: TODO
     * @author: Juveniless
     * @date: 2017年11月27日 下午3:23:13
     */
    import java.io.ByteArrayInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.*;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import com.sjyf.gym.ex.BusinessException;
    import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
    import org.apache.poi.util.Units;
    import org.apache.poi.xwpf.usermodel.BodyElementType;
    import org.apache.poi.xwpf.usermodel.Document;
    import org.apache.poi.xwpf.usermodel.IBodyElement;
    import org.apache.poi.xwpf.usermodel.PositionInParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFDocument;
    import org.apache.poi.xwpf.usermodel.XWPFParagraph;
    import org.apache.poi.xwpf.usermodel.XWPFRun;
    import org.apache.poi.xwpf.usermodel.XWPFTable;
    import org.apache.poi.xwpf.usermodel.XWPFTableCell;
    import org.apache.poi.xwpf.usermodel.XWPFTableRow;
    import org.springframework.beans.factory.annotation.Value;
    
    /**
     *
     * 对docx文件中的文本及表格中的内容进行替换 --模板仅支持对 {key} 标签的替换
     *
     * @ClassName: WordTemplate
     * @Description: TODO(!!!使用word2013 docx文件)
     * @author Juveniless
     * @date: 2017年11月27日 下午3:25:56
     * <br>(1)word模板注意页边距的问题,存在问题:比如页边距默认为3cm,画表格时,仍然可以通过
     * 拖拽,把表格边框拖动到看起来就像页边距只有1cm的样子,但是实际上此时页边距还是3cm,生成的
     * word报表的页边距还是会按照3cm来生成。解决办法,在word文件里,设置好页边距,如果需要表格
     * 两边页边距很窄,需要在word里设置页边距窄一点,而不是直接拖动表格边框来实现。
     *
     */
    
    public class WordUtils {
    
        private XWPFDocument document;
    
        public XWPFDocument getDocument() {
            return document;
        }
    
        public void setDocument(XWPFDocument document) {
            this.document = document;
        }
    
        /**
         * 初始化模板内容
         *
         * @author Juveniless
         * @date 2017年11月27日 下午3:59:22
         * @param inputStream
         *            模板的读取流(docx文件)
         * @throws IOException
         *
         */
        public WordUtils(InputStream inputStream) throws IOException {
            document = new XWPFDocument(inputStream);
        }
    
        /**
         * 将处理后的内容写入到输出流中
         *
         * @param outputStream
         * @throws IOException
         */
        public void write(OutputStream outputStream) throws IOException {
            document.write(outputStream);
        }
    
    
    
    
    
        /**
         * 根据dataMap对word文件中的标签进行替换; <br><br>
         * !!!!***需要注意dataMap的数据格式***!!!! <br><br>
         * 对于需要替换的普通标签数据标签(不需要循环)-----必须在dataMap中存储一个key为parametersMap的map,
         * 来存储这些不需要循环生成的数据,比如:表头信息,日期,制表人等。 <br><br>
         * 对于需要循环生成的表格数据------key自定义,value为 --ArrayList&lt;Map&lt;String, String>>
         * @author Juveniless
         * @date 2017年11月27日 下午3:29:27
         * @param dataMap
         *
         */
        public void replaceDocument(Map<String, Object> dataMap,String uploadPath) {
    
            if (!dataMap.containsKey("parametersMap")) {
                System.out.println("数据源错误--数据源(parametersMap)缺失");
                return;
            }
            @SuppressWarnings("unchecked")
            Map<String, Object> parametersMap = (Map<String, Object>) dataMap
                    .get("parametersMap");
    
            List<IBodyElement> bodyElements = document.getBodyElements();// 所有对象(段落+表格)
            int templateBodySize = bodyElements.size();// 标记模板文件(段落+表格)总个数
    
            int curT = 0;// 当前操作表格对象的索引
            int curP = 0;// 当前操作段落对象的索引
            for (int a = 0; a < templateBodySize; a++) {
                IBodyElement body = bodyElements.get(a);
                if (BodyElementType.TABLE.equals(body.getElementType())) {// 处理表格
                    XWPFTable table = body.getBody().getTableArray(curT);
    
                    List<XWPFTable> tables = body.getBody().getTables();
                    table = tables.get(curT);
                    if (table != null) {
    
                        // 处理表格
                        String tableText = table.getText();// 表格中的所有文本
    
                        if (tableText.indexOf("##{foreach") > -1) {
                            // 查找到##{foreach标签,该表格需要处理循环
    /*                        if (tableCells.size() != 2
                                    || tableCells.get(0).getText().indexOf("##{foreach") < 0
                                    || tableCells.get(0).getText().trim().length() == 0) {
                                System.out
                                        .println("文档中第"
                                                + (curT + 1)
                                                + "个表格模板错误,模板表格第一行需要设置2个单元格,"
                                                + "第一个单元格存储表格类型(##{foreachTable}## 或者 ##{foreachTableRow}##),第二个单元格定义数据源。");
                                return;
                            }*/
                            int row = -1;
                            int cell = -1;
                            for(int i=0;i<table.getRows().size();i++){
                                List<XWPFTableCell> tableCells2 = table.getRows().get(i).getTableCells();
                                for (int j = 0; j < tableCells2.size(); j++) {
                                    if (tableCells2.get(j).getText().equals("##{foreachTableRow}##")) {
                                        row = i;
                                        cell = j;
                                        break;
                                    }
                                }
                            }
                            System.out.println("row:"+row);
                            System.out.println("cell:"+cell);
                            List<XWPFTableCell> tableCells = table.getRows().get(row).getTableCells();// 获取到模板表格第一行,用来判断表格类型
                            String tableType = tableCells.get(cell).getText();
                            String dataSource = tableCells.get(cell+1).getText();
                            System.out.println("读取到数据源:"+dataSource);
                            if (!dataMap.containsKey(dataSource)) {
                                System.out.println("文档中第" + (curT + 1) + "个表格模板数据源缺失");
                            }
                            @SuppressWarnings("unchecked")
                            List<Map<String, Object>> tableDataList = (List<Map<String, Object>>) dataMap.get(dataSource);
                            if ("##{foreachTable}##".equals(tableType)) {
                                // System.out.println("循环生成表格");
                                addTableInDocFooter(table, tableDataList, parametersMap, 1,uploadPath);
    
                            } else if ("##{foreachTableRow}##".equals(tableType)) {
                                // System.out.println("循环生成表格内部的行");
                                addTableInDocFooter1(table, tableDataList, parametersMap, 2,row,cell,uploadPath);
                            }
    
                        } else if (tableText.indexOf("{") > -1) {
                            // 没有查找到##{foreach标签,查找到了普通替换数据的{}标签,该表格只需要简单替换
                            addTableInDocFooter(table, null, parametersMap, 3,uploadPath);
                        } else {
                            // 没有查找到任何标签,该表格是一个静态表格,仅需要复制一个即可。
                            addTableInDocFooter(table, null, null, 0,uploadPath);
                        }
                        curT++;
    
                    }
                } else if (BodyElementType.PARAGRAPH.equals(body.getElementType())) {// 处理段落
                    // System.out.println("获取到段落");
                    XWPFParagraph ph = body.getBody().getParagraphArray(curP);
                    if (ph != null) {
                        // htmlText = htmlText+readParagraphX(ph);
                        addParagraphInDocFooter(ph, null, parametersMap, 0,uploadPath);
    
                        curP++;
                    }
                }
    
            }
            // 处理完毕模板,删除文本中的模板内容
            for (int a = 0; a < templateBodySize; a++) {
                document.removeBodyElement(0);
            }
    
        }
    
    
    
    
    
    
    
    
        /**
         * 根据 模板表格 和 数据list 在word文档末尾生成表格
         * @author Juveniless
         * @date 2017年12月6日 上午10:12:05
         * @param templateTable 模板表格
         * @param list   循环数据集
         * @param parametersMap  不循环数据集
         * @param flag   (0为静态表格,1为表格整体循环,2为表格内部行循环,3为表格不循环仅简单替换标签即可)
         *
         */
        public void addTableInDocFooter(XWPFTable templateTable, List<Map<String, Object>> list,
                                        Map<String, Object> parametersMap, int flag,String uploadPath) {
    
            if (flag == 1) {// 表格整体循环
                for (Map<String, Object> map : list) {
                    List<XWPFTableRow> templateTableRows = templateTable.getRows();// 获取模板表格所有行
                    XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
                    for (int i = 1; i < templateTableRows.size(); i++) {
                        XWPFTableRow newCreateRow = newCreateTable.createRow();
                        CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行
                    }
                    newCreateTable.removeRow(0);// 移除多出来的第一行
                    document.createParagraph();// 添加回车换行
                    replaceTable(newCreateTable, map,uploadPath);//替换标签
                }
    
            } else if (flag == 2) {// 表格表格内部行循环
                System.out.println("list:"+list);
                System.out.println("parametersMap:"+parametersMap);
                XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
                List<XWPFTableRow> TempTableRows = templateTable.getRows();// 获取模板表格所有行
                int tagRowsIndex = 0;// 标签行indexs
                for (int i = 0, size = TempTableRows.size(); i < size; i++) {
                    String rowText = TempTableRows.get(i).getCell(0).getText();// 获取到表格行的第一个单元格
                    if (rowText.indexOf("##{foreachRows}##") > -1) {
                        tagRowsIndex = i;
                        break;
                    }
                    System.out.println("rowText:"+rowText);
                    System.out.println("i:"+i);
                }
    
                System.out.println("tagRowsIndex:"+tagRowsIndex);
                /* 复制模板行和标签行之前的行 */
                for (int i = 1; i < tagRowsIndex; i++) {
                    XWPFTableRow newCreateRow = newCreateTable.createRow();
                    CopyTableRow(newCreateRow, TempTableRows.get(i));// 复制行
                    replaceTableRow(newCreateRow, parametersMap,uploadPath);// 处理不循环标签的替换
                }
    
                /* 循环生成模板行 */
                XWPFTableRow tempRow = TempTableRows.get(tagRowsIndex + 1);// 获取到模板行
                for (int i = 0; i < list.size(); i++) {
                    XWPFTableRow newCreateRow = newCreateTable.createRow();
                    CopyTableRow(newCreateRow, tempRow);// 复制模板行
                    replaceTableRow(newCreateRow, list.get(i),uploadPath);// 处理标签替换
                }
    
                /* 复制模板行和标签行之后的行 */
    /*            for (int i = tagRowsIndex + 2; i < TempTableRows.size(); i++) {
                    XWPFTableRow newCreateRow = newCreateTable.createRow();
                    CopyTableRow(newCreateRow, TempTableRows.get(i));// 复制行
                    replaceTableRow(newCreateRow, parametersMap);// 处理不循环标签的替换
                }*/
                newCreateTable.removeRow(0);// 移除多出来的第一行
                document.createParagraph();// 添加回车换行
    
            } else if (flag == 3) {
                //表格不循环仅简单替换标签
                List<XWPFTableRow> templateTableRows = templateTable.getRows();// 获取模板表格所有行
                XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
                for (int i = 0; i < templateTableRows.size(); i++) {
                    XWPFTableRow newCreateRow = newCreateTable.createRow();
                    CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行
                }
                newCreateTable.removeRow(0);// 移除多出来的第一行
                document.createParagraph();// 添加回车换行
                replaceTable(newCreateTable, parametersMap,uploadPath);
    
            } else if (flag == 0) {
                List<XWPFTableRow> templateTableRows = templateTable.getRows();// 获取模板表格所有行
                XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
                for (int i = 0; i < templateTableRows.size(); i++) {
                    XWPFTableRow newCreateRow = newCreateTable.createRow();
                    CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行
                }
                newCreateTable.removeRow(0);// 移除多出来的第一行
                document.createParagraph();// 添加回车换行
            }
    
        }
    
    
    
        /**
         * 根据 模板表格 和 数据list 在word文档末尾生成表格
         * @author Juveniless
         * @date 2017年12月6日 上午10:12:05
         * @param templateTable 模板表格
         * @param list   循环数据集
         * @param parametersMap  不循环数据集
         * @param flag   (0为静态表格,1为表格整体循环,2为表格内部行循环,3为表格不循环仅简单替换标签即可)
         *
         */
        public void addTableInDocFooter1(XWPFTable templateTable, List<Map<String, Object>> list,
                                         Map<String, Object> parametersMap, int flag,int row,int cell,String uploadPath) {
    
            if (flag == 1) {// 表格整体循环
                for (Map<String, Object> map : list) {
                    List<XWPFTableRow> templateTableRows = templateTable.getRows();// 获取模板表格所有行
                    XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
                    for (int i = 1; i < templateTableRows.size(); i++) {
                        XWPFTableRow newCreateRow = newCreateTable.createRow();
                        CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行
                    }
                    newCreateTable.removeRow(0);// 移除多出来的第一行
                    document.createParagraph();// 添加回车换行
                    replaceTable(newCreateTable, map,uploadPath);//替换标签
                }
    
            } else if (flag == 2) {// 表格表格内部行循环
                System.out.println("list:"+list);
                System.out.println("parametersMap:"+parametersMap);
                XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
                List<XWPFTableRow> TempTableRows = templateTable.getRows();// 获取模板表格所有行
                int tagRowsIndex = 0;// 标签行indexs
                for (int i = row, size = TempTableRows.size(); i < size; i++) {
                    String rowText = TempTableRows.get(i).getCell(cell).getText();// 获取到表格行的第一个单元格
                    if (rowText.indexOf("##{foreachRows}##") > -1) {
                        tagRowsIndex = i;
                        break;
                    }
                    System.out.println("rowText:"+rowText);
                    System.out.println("i:"+i);
                }
    
                System.out.println("tagRowsIndex:"+tagRowsIndex);
                /* 复制模板行和标签行之前的行 */
                for (int i = 0; i < tagRowsIndex; i++) {
                    XWPFTableRow newCreateRow = newCreateTable.createRow();
                    CopyTableRow(newCreateRow, TempTableRows.get(i));// 复制行
                    replaceTableRow(newCreateRow, parametersMap,uploadPath);// 处理不循环标签的替换
                }
    
                if (list!=null) {
                    /* 循环生成模板行 */
                    XWPFTableRow tempRow = TempTableRows.get(tagRowsIndex + 1);// 获取到模板行
                    for (int i = 0; i < list.size(); i++) {
                        XWPFTableRow newCreateRow = newCreateTable.createRow();
                        CopyTableRow(newCreateRow, tempRow);// 复制模板行
                        replaceTableRow(newCreateRow, list.get(i),uploadPath);// 处理标签替换
                    }
                }
    
                /* 复制模板行和标签行之后的行 */
                for (int i = tagRowsIndex + 2; i < TempTableRows.size(); i++) {
                    XWPFTableRow newCreateRow = newCreateTable.createRow();
                    CopyTableRow(newCreateRow, TempTableRows.get(i));// 复制行
                    replaceTableRow(newCreateRow, parametersMap,uploadPath);// 处理不循环标签的替换
                }
                newCreateTable.removeRow(0);// 移除多出来的第一行
                newCreateTable.removeRow(row);// 移除标签行
                if (cell-1>=0&&list!=null) {
                    List<XWPFTableRow> tableName = newCreateTable.getRows();
                    for (int i = row; i <= list.size()+1; i++) {
                        //对单元格进行合并的时候,要标志单元格是否为起点,或者是否为继续合并
                        XWPFTableCell cell0 = tableName.get(i).getCell(0);
                        XWPFTableCell cell1 = tableName.get(i + 1).getCell(0);
                        cell1.setText(cell0.getText());
    /*                      CTVMerge vmerge = CTVMerge.Factory.newInstance();
                          vmerge.setVal(STMerge.RESTART);
                         cell0.getCTTc().getTcPr().setVMerge(vmerge);
                         cell1.getCTTc().getTcPr().setVMerge(vmerge);
    
                         CTVMerge vmerge1 = CTVMerge.Factory.newInstance();
                         vmerge1.setVal(STMerge.CONTINUE);
                         cell0.getCTTc().getTcPr().setVMerge(vmerge1);
                         cell1.getCTTc().getTcPr().setVMerge(vmerge1);*/
                        //tableName.get(i).getTableCells().get(cell-1).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);//这是起点
                    }
                }
                document.createParagraph();// 添加回车换行
    
            } else if (flag == 3) {
                //表格不循环仅简单替换标签
                List<XWPFTableRow> templateTableRows = templateTable.getRows();// 获取模板表格所有行
                XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
                for (int i = 0; i < templateTableRows.size(); i++) {
                    XWPFTableRow newCreateRow = newCreateTable.createRow();
                    CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行
                }
                newCreateTable.removeRow(0);// 移除多出来的第一行
                document.createParagraph();// 添加回车换行
                replaceTable(newCreateTable, parametersMap,uploadPath);
    
            } else if (flag == 0) {
                List<XWPFTableRow> templateTableRows = templateTable.getRows();// 获取模板表格所有行
                XWPFTable newCreateTable = document.createTable();// 创建新表格,默认一行一列
                for (int i = 0; i < templateTableRows.size(); i++) {
                    XWPFTableRow newCreateRow = newCreateTable.createRow();
                    CopyTableRow(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行
                }
                newCreateTable.removeRow(0);// 移除多出来的第一行
                document.createParagraph();// 添加回车换行
            }
    
        }
    
    
    
    
        /**
         * 根据 模板段落 和 数据 在文档末尾生成段落
         *
         * @author Juveniless
         * @date 2017年11月27日 上午11:49:42
         * @param templateParagraph
         *            模板段落
         * @param list
         *            循环数据集
         * @param parametersMap
         *            不循环数据集
         * @param flag
         *            (0为不循环替换,1为循环替换)
         *
         */
        public void addParagraphInDocFooter(XWPFParagraph templateParagraph,
                                            List<Map<String, String>> list, Map<String, Object> parametersMap, int flag,String uploadPath) {
    
            if (flag == 0) {
                XWPFParagraph createParagraph = document.createParagraph();
                // 设置段落样式
                createParagraph.getCTP().setPPr(templateParagraph.getCTP().getPPr());
                // 移除原始内容
                for (int pos = 0; pos < createParagraph.getRuns().size(); pos++) {
                    createParagraph.removeRun(pos);
                }
                // 添加Run标签
                for (XWPFRun s : templateParagraph.getRuns()) {
                    XWPFRun targetrun = createParagraph.createRun();
                    CopyRun(targetrun, s);
                }
    
                replaceParagraph(createParagraph, parametersMap,uploadPath);
    
            } else if (flag == 1) {
                // 暂无实现
            }
    
        }
    
    
    
    
        /**
         * 根据map替换段落元素内的{**}标签
         * @author Juveniless
         * @date 2017年12月4日 下午3:09:00
         * @param xWPFParagraph
         * @param parametersMap
         *
         */
        public void replaceParagraph(XWPFParagraph xWPFParagraph, Map<String, Object> parametersMap,String uploadPath) {
            List<XWPFRun> runs = xWPFParagraph.getRuns();
            String xWPFParagraphText = xWPFParagraph.getText();
            String regEx = "\{.+?\}";
            Pattern pattern = Pattern.compile(regEx);
            Matcher matcher = pattern.matcher(xWPFParagraphText);//正则匹配字符串{****}
    
            if (matcher.find()) {
                // 查找到有标签才执行替换
                int beginRunIndex = xWPFParagraph.searchText("{", new PositionInParagraph()).getBeginRun();// 标签开始run位置
                int endRunIndex = xWPFParagraph.searchText("}", new PositionInParagraph()).getEndRun();// 结束标签
                StringBuffer key = new StringBuffer();
                System.out.println("beginRunIndex:"+beginRunIndex);
                System.out.println("endRunIndex:"+endRunIndex);
                if (beginRunIndex == endRunIndex) {
                    // {**}在一个run标签内
                    XWPFRun beginRun = runs.get(beginRunIndex);
                    String beginRunText = beginRun.text();
    
                    int beginIndex = beginRunText.indexOf("{");
                    int endIndex = beginRunText.indexOf("}");
                    int length = beginRunText.length();
    
                    if (beginIndex == 0 && endIndex == length - 1) {
                        // 该run标签只有{**}
                        XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
                        insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
                        // 设置文本
                        key.append(beginRunText.substring(1, endIndex));
                        String value = getValueBykey(key.toString(),parametersMap);
                        System.out.println("value:"+value);
                        System.out.println("value:"+value.length());
                        if (value.length()>5&&(value.substring(value.length()-4).equals(".jpg")||value.substring(value.length()-4).equals(".png"))) {
                            try {
                                String [] picValues = value.split(",");
                                System.out.println("picValues:"+picValues);
                                for(int i=0;i<picValues.length;i++){
                                    if (picValues[i]!="") {
                                        FileInputStream fis = new FileInputStream(new File(uploadPath+"/upload/"+picValues[i]));
                                        if (value.substring(picValues[i].length()-4).equals(".jpg")) {
                                            insertNewRun.addPicture(fis, Document.PICTURE_TYPE_JPEG, "", Units.toEMU(120), Units.toEMU(140));
                                        }
                                        else {
                                            insertNewRun.addPicture(fis, Document.PICTURE_TYPE_PNG, "", Units.toEMU(120), Units.toEMU(140));
                                        }
                                        if (fis!=null) {
                                            fis.close();
                                        }
                                    }
    
                                }
    
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
    //                    else if(key.toString().equals("clientSign")){
    //                        FileInputStream fis;
    //                        try {
    //                            System.out.println("value:"+value);
    //                            fis= new FileInputStream(new File(value));
    //                                try {
    //                                    insertNewRun.addPicture(fis, Document.PICTURE_TYPE_JPEG, "", Units.toEMU(120), Units.toEMU(140));
    //                                } catch (InvalidFormatException e1) {
    //                                    // TODO Auto-generated catch block
    //                                    e1.printStackTrace();
    //                                } catch (IOException e1) {
    //                                    // TODO Auto-generated catch block
    //                                    e1.printStackTrace();
    //                                }
    //
    //                            if (fis!=null) {
    //                                try {
    //                                    fis.close();
    //                                } catch (IOException e) {
    //                                    // TODO Auto-generated catch block
    //                                    e.printStackTrace();
    //                                }
    //                            }
    //                        } catch (FileNotFoundException e) {
    //                            // TODO Auto-generated catch block
    //                            e.printStackTrace();
    //                        }
    //                    }
                        else {
                            insertNewRun.setText(value);
                        }
    
                        xWPFParagraph.removeRun(beginRunIndex + 1);
                    } else {
                        // 该run标签为**{**}** 或者 **{**} 或者{**}**,替换key后,还需要加上原始key前后的文本
                        XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
                        insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
                        // 设置文本
                        key.append(beginRunText.substring(beginRunText.indexOf("{")+1, beginRunText.indexOf("}")));
                        String textString=beginRunText.substring(0, beginIndex) + getValueBykey(key.toString(),parametersMap)
                                + beginRunText.substring(endIndex + 1);
                        insertNewRun.setText(textString);
                        xWPFParagraph.removeRun(beginRunIndex + 1);
                    }
    
                }else {
                    // {**}被分成多个run
    
                    //先处理起始run标签,取得第一个{key}值
                    XWPFRun beginRun = runs.get(beginRunIndex);
                    String beginRunText = beginRun.text();
                    int beginIndex = beginRunText.indexOf("{");
                    if (beginRunText.length()>1  ) {
                        key.append(beginRunText.substring(beginIndex+1));
                    }
                    ArrayList<Integer> removeRunList = new ArrayList<>();//需要移除的run
                    //处理中间的run
                    for (int i = beginRunIndex + 1; i < endRunIndex; i++) {
                        XWPFRun run = runs.get(i);
                        String runText = run.text();
                        key.append(runText);
                        removeRunList.add(i);
                    }
    
                    // 获取endRun中的key值
                    XWPFRun endRun = runs.get(endRunIndex);
                    String endRunText = endRun.text();
                    int endIndex = endRunText.indexOf("}");
                    //run中**}或者**}**
                    if (endRunText.length()>1 && endIndex!=0) {
                        key.append(endRunText.substring(0,endIndex));
                    }
    
    
    
                    //*******************************************************************
                    //取得key值后替换标签
    
                    //先处理开始标签
                    if (beginRunText.length()==2 ) {
                        // run标签内文本{
                        XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
                        insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
                        String value = getValueBykey(key.toString(),parametersMap);
                        if (value.length()>5&&(value.substring(value.length()-4).equals(".jpg")||value.substring(value.length()-4).equals(".png"))) {
                            try {
                                String [] picValues = value.split(",");
                                System.out.println("picValues:"+picValues);
                                for(int i=0;i<picValues.length;i++){
                                    if (picValues[i]!="") {
                                        FileInputStream fis = new FileInputStream(new File(uploadPath+"/upload/"+picValues[i]));
                                        if (value.substring(picValues[i].length()-4).equals(".jpg")) {
                                            insertNewRun.addPicture(fis, Document.PICTURE_TYPE_JPEG, "", Units.toEMU(120), Units.toEMU(140));
                                        }
                                        else {
                                            insertNewRun.addPicture(fis, Document.PICTURE_TYPE_PNG, "", Units.toEMU(120), Units.toEMU(140));
                                        }
                                        if (fis!=null) {
                                            fis.close();
                                        }
                                    }
                                }
    
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }else {
                            insertNewRun.setText(value);
                        }
    
                        // 设置文本
                        //insertNewRun.setText(getValueBykey(key.toString(),parametersMap));
                        xWPFParagraph.removeRun(beginRunIndex + 1);//移除原始的run
                    }else {
                        // 该run标签为**{**或者 {** ,替换key后,还需要加上原始key前的文本
                        XWPFRun insertNewRun = xWPFParagraph.insertNewRun(beginRunIndex);
                        insertNewRun.getCTR().setRPr(beginRun.getCTR().getRPr());
    
    
    
    
                        // 设置文本
                        String textString="";
                        textString=beginRunText.substring(0,beginRunText.indexOf("{"))+getValueBykey(key.toString(),parametersMap);
                        System.out.println(textString);
    //                    if(key.toString().equals("clientSign")){
    //                        textString = textString.substring(3, textString.length());
    //                        System.out.println(textString);
    //                    }
                        System.out.println(textString);
                        if (textString.length()>5&&(textString.substring(textString.length()-4).equals(".jpg")||textString.substring(textString.length()-4).equals(".png"))) {
                            try {
                                String [] picValues = textString.split(",");
                                System.out.println("picValues:"+picValues);
                                for(int i=0;i<picValues.length;i++){
                                    if (picValues[i]!="") {
                                        FileInputStream fis = new FileInputStream(new File(uploadPath+"/upload/"+picValues[i]));
                                        if (textString.substring(picValues[i].length()-4).equals(".jpg")) {
                                            insertNewRun.addPicture(fis, Document.PICTURE_TYPE_JPEG, "", Units.toEMU(100), Units.toEMU(60));
                                        }
                                        else {
                                            insertNewRun.addPicture(fis, Document.PICTURE_TYPE_PNG, "", Units.toEMU(120), Units.toEMU(140));
                                        }
                                        if (fis!=null) {
                                            fis.close();
                                        }
                                    }
                                }
    
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }else {
                            //替换换行符
                            if (((String) getValueBykey(key.toString(),parametersMap)).indexOf("
    ") > 0) {
                                //设置换行
                                String[] text = getValueBykey(key.toString(),parametersMap).toString().split("
    ");
    //                            insertNewRun = xWPFParagraph.insertNewRun(0);
                                for (int f = 0; f < text.length; f++) {
                                    if (f == 0) {
                                        insertNewRun.setText(text[f].trim());
                                    } else {
    //                                    insertNewRun.addCarriageReturn();//硬回车
                                        // 换行
                                        insertNewRun.addBreak();
                                        insertNewRun.setText(text[f].trim());
                                    }
                                }
                            } else {
                                insertNewRun.setText((String) getValueBykey(key.toString(),parametersMap));
                            }
                        }
                        //insertNewRun.setText(textString);
                        xWPFParagraph.removeRun(beginRunIndex + 1);//移除原始的run
                    }
    
                    //处理结束标签
                    if (endRunText.length()==1 ) {
                        // run标签内文本只有}
                        XWPFRun insertNewRun = xWPFParagraph.insertNewRun(endRunIndex);
                        insertNewRun.getCTR().setRPr(endRun.getCTR().getRPr());
                        // 设置文本
                        insertNewRun.setText("");
                        xWPFParagraph.removeRun(endRunIndex + 1);//移除原始的run
    
                    }else {
                        // 该run标签为**}**或者 }** 或者**},替换key后,还需要加上原始key后的文本
                        XWPFRun insertNewRun = xWPFParagraph.insertNewRun(endRunIndex);
                        insertNewRun.getCTR().setRPr(endRun.getCTR().getRPr());
                        // 设置文本
                        String textString=endRunText.substring(endRunText.indexOf("}")+1);
                        if (textString.length()>5&&(textString.substring(textString.length()-4).equals(".jpg")||textString.substring(textString.length()-4).equals(".png"))) {
                            try {
                                String [] picValues = textString.split(",");
                                System.out.println("picValues:"+picValues);
                                for(int i=0;i<picValues.length;i++){
                                    if (picValues[i]!="") {
                                        FileInputStream fis = new FileInputStream(new File(uploadPath+"/upload/"+picValues[i]));
                                        if (textString.substring(picValues[i].length()-4).equals(".jpg")) {
                                            insertNewRun.addPicture(fis, Document.PICTURE_TYPE_JPEG, "", Units.toEMU(120), Units.toEMU(140));
                                        }
                                        else {
                                            insertNewRun.addPicture(fis, Document.PICTURE_TYPE_PNG, "", Units.toEMU(120), Units.toEMU(140));
                                        }
                                        if (fis!=null) {
                                            fis.close();
                                        }
                                    }
                                }
    
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }else {
                            insertNewRun.setText(textString);
                        }
                        //insertNewRun.setText(textString);
                        xWPFParagraph.removeRun(endRunIndex + 1);//移除原始的run
                    }
    
                    //处理中间的run标签
                    for (int i = 0; i < removeRunList.size(); i++) {
                        XWPFRun xWPFRun = runs.get(removeRunList.get(i));//原始run
                        XWPFRun insertNewRun = xWPFParagraph.insertNewRun(removeRunList.get(i));
                        insertNewRun.getCTR().setRPr(xWPFRun.getCTR().getRPr());
                        insertNewRun.setText("");
                        xWPFParagraph.removeRun(removeRunList.get(i) + 1);//移除原始的run
                    }
    
                }// 处理${**}被分成多个run
    
                replaceParagraph( xWPFParagraph, parametersMap,uploadPath);
    
            }//if 有标签
    
        }
    
        public ByteArrayInputStream base64ToFile(String strBase64){
            try {
                // 解码,然后将字节转换为文件
                byte[] bytes = Base64.getDecoder().decode(strBase64); // 将字符串转换为byte数组
                return copyByte2File(bytes);
            } catch (Exception ioe) {
                ioe.printStackTrace();
                return null;
            }
        }
    
        private ByteArrayInputStream copyByte2File(byte [] bytes){
            FileOutputStream  out = null;
            try {
                //转化为输入流
                ByteArrayInputStream in = new ByteArrayInputStream(bytes);
    
    //            //写出文件
    //            byte[] buffer = new byte[1024];
    //
    //            out = new FileOutputStream(file);
    //
    //            //写文件
    //            int len = 0;
    //            while ((len = in.read(buffer)) != -1) {
    //                out.write(buffer, 0, len); // 文件写操作
    //            }
                return in;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                try {
                    if(out != null){
                        out.close();
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return null;
        }
    
    
    
    
    
    
        /**
         * 复制表格行XWPFTableRow格式
         *
         * @param target
         *            待修改格式的XWPFTableRow
         * @param source
         *            模板XWPFTableRow
         */
        private void CopyTableRow(XWPFTableRow target, XWPFTableRow source) {
    
            int tempRowCellsize = source.getTableCells().size();// 模板行的列数
            for (int i = 0; i < tempRowCellsize - 1; i++) {
                target.addNewTableCell();// 为新添加的行添加与模板表格对应行行相同个数的单元格
            }
            // 复制样式
            target.getCtRow().setTrPr(source.getCtRow().getTrPr());
            // 复制单元格
            for (int i = 0; i < target.getTableCells().size(); i++) {
                copyTableCell(target.getCell(i), source.getCell(i));
            }
        }
    
    
    
    
    
        /**
         * 复制单元格XWPFTableCell格式
         *
         * @author Juveniless
         * @date 2017年11月27日 下午3:41:02
         * @param newTableCell
         *            新创建的的单元格
         * @param templateTableCell
         *            模板单元格
         *
         */
        private void copyTableCell(XWPFTableCell newTableCell, XWPFTableCell templateTableCell) {
            // 列属性
            newTableCell.getCTTc().setTcPr(templateTableCell.getCTTc().getTcPr());
            // 删除目标 targetCell 所有文本段落
            for (int pos = 0; pos < newTableCell.getParagraphs().size(); pos++) {
                newTableCell.removeParagraph(pos);
            }
            // 添加新文本段落
            for (XWPFParagraph sp : templateTableCell.getParagraphs()) {
                XWPFParagraph targetP = newTableCell.addParagraph();
                copyParagraph(targetP, sp);
            }
        }
    
        /**
         * 复制文本段落XWPFParagraph格式
         *
         * @author Juveniless
         * @date 2017年11月27日 下午3:43:08
         * @param newParagraph
         *            新创建的的段落
         * @param templateParagraph
         *            模板段落
         *
         */
        private void copyParagraph(XWPFParagraph newParagraph, XWPFParagraph templateParagraph) {
            // 设置段落样式
            newParagraph.getCTP().setPPr(templateParagraph.getCTP().getPPr());
            // 添加Run标签
            for (int pos = 0; pos < newParagraph.getRuns().size(); pos++) {
                newParagraph.removeRun(pos);
    
            }
            for (XWPFRun s : templateParagraph.getRuns()) {
                XWPFRun targetrun = newParagraph.createRun();
                CopyRun(targetrun, s);
            }
    
        }
    
        /**
         * 复制文本节点run
         * @author Juveniless
         * @date 2017年11月27日 下午3:47:17
         * @param newRun
         *            新创建的的文本节点
         * @param templateRun
         *            模板文本节点
         *
         */
        private void CopyRun(XWPFRun newRun, XWPFRun templateRun) {
            newRun.getCTR().setRPr(templateRun.getCTR().getRPr());
            // 设置文本
            newRun.setText(templateRun.text());
    
    
        }
    
    
    
    
        /**
         * 根据参数parametersMap对表格的一行进行标签的替换
         *
         * @author Juveniless
         * @date 2017年11月23日 下午2:09:24
         * @param tableRow
         *            表格行
         * @param parametersMap
         *            参数map
         *
         */
        public void replaceTableRow(XWPFTableRow tableRow, Map<String, Object> parametersMap,String uploadPath) {
    
            List<XWPFTableCell> tableCells = tableRow.getTableCells();
            for (XWPFTableCell xWPFTableCell : tableCells) {
                List<XWPFParagraph> paragraphs = xWPFTableCell.getParagraphs();
                for (XWPFParagraph xwpfParagraph : paragraphs) {
    
                    replaceParagraph(xwpfParagraph, parametersMap,uploadPath);
                }
            }
    
        }
    
    
    
    
    
        /**
         * 根据map替换表格中的{key}标签
         * @author Juveniless
         * @date 2017年12月4日 下午2:47:36
         * @param xwpfTable
         * @param parametersMap
         *
         */
        public void replaceTable(XWPFTable xwpfTable,Map<String, Object> parametersMap,String uploadPath){
            List<XWPFTableRow> rows = xwpfTable.getRows();
            for (XWPFTableRow xWPFTableRow : rows ) {
                List<XWPFTableCell> tableCells = xWPFTableRow.getTableCells();
                for (XWPFTableCell xWPFTableCell : tableCells ) {
                    List<XWPFParagraph> paragraphs2 = xWPFTableCell.getParagraphs();
                    for (XWPFParagraph xWPFParagraph : paragraphs2) {
                        replaceParagraph(xWPFParagraph, parametersMap,uploadPath);
                    }
                }
            }
    
        }
    
    
    
        private String getValueBykey(String key, Map<String, Object> map) {
            String returnValue="";
            if (key != null) {
                try {
                    returnValue=map.get(key)!=null ? map.get(key).toString() : "";
                } catch (Exception e) {
                    // TODO: handle exception
                    System.out.println("key:"+key+"***"+e);
                    returnValue="";
                }
    
            }
            return returnValue;
        }
    
        public static void createFile(Long resourceId, Map<String, Object> data) {
            try {
                FileInputStream file = ResourceUtil.getFile(resourceId);
                // 加载模板文件
                WordUtils template = new WordUtils(file);
                Map<String, Object> wordDataMap = new HashMap<String, Object>();// 存储报表全部数据
                wordDataMap.put("parametersMap", data);
                // 替换数据
                template.replaceDocument(wordDataMap,"D://uploadFiles");
                //生成文件
                File outputFile = new File("D://20200529_cf6597f2-23e0-46e1-8ce5-340d243cf3051.docx");//改成你本地文件所在目录
                FileOutputStream fos  = new FileOutputStream(outputFile);
                template.getDocument().write(fos);
                file.close();
                fos.close();
            } catch (Exception e) {
                throw new BusinessException("生成文件失败");
            }
        }
    
        /*public static void main(String[] args) {
            try {
                //模版地址
                File demoFile = new File("C:\Users\qian\Desktop\temp.docx");
                InputStream in = new FileInputStream(demoFile);
                WordUtils template = new WordUtils(in);
                Map<String, Object> wordDataMap = new HashMap<String, Object>();// 存储报表全部数据
                Map<String, Object> parametersMap = new HashMap<String, Object>();// 存储报表中不循环的数据
    
                parametersMap.put("beginTime", "2020-08-02");
                parametersMap.put("providerName", "测试");
                parametersMap.put("idispatchingType", "测试");
                parametersMap.put("projectName", "测试项目");
                parametersMap.put("projectPlace", "测试地点");
                parametersMap.put("projectName", "测试项目");
                parametersMap.put("team", "张三,王五");
                parametersMap.put("workContent", "工作内容");
                parametersMap.put("img", "1597416361020.jpg");//图片名称
                wordDataMap.put("parametersMap", parametersMap);
                System.out.println("wordDataMap:" + wordDataMap);
                // 替换数据
                template.replaceDocument(wordDataMap,"D://uploadFiles");
                // 输出word内容文件流,提供下载
                //生成文件
                File outputFile=new File("D://20200529_cf6597f2-23e0-46e1-8ce5-340d243cf3051.docx");//改成你本地文件所在目录
                FileOutputStream fos  = new FileOutputStream(outputFile);
                template.getDocument().write(fos);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }*/
    
    
    
    
    }
  • 相关阅读:
    java——异常(一)
    java —— 全面解析 Annotation
    多线程(一)——三种实现方式
    java ——static 关键词总结
    java —— equals 与 ==
    java——数组与内存控制
    java—— finall 关键词
    File类实现文件夹和文件复制
    java —— 内部类
    类成员——代码块
  • 原文地址:https://www.cnblogs.com/hjieone/p/14341285.html
Copyright © 2020-2023  润新知