apache.poi 处理word模板

在这里插入图片描述
里面的表头的 “编号”实际为 ##{foreachData}##编号,其中 ##{foreachData}##被隐藏
隐藏方式:
在这里插入图片描述
开始中 有个下角,点击,然后隐藏文字

 <!--word模板-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>
        
//word的产品信息
        List<Map<String, Object>> contractProductInfoVOList = getProductInfoVoByInsertContract(contractProductInfoVOListObj);
Map<String, Object> wordDataMap = new HashMap<String, Object>();// 存储报表全部数据 循环的数据
Map<String, Object> parametersMap = new HashMap<String, Object>();// 存储报表中不循环的数据

        parametersMap.put("partyAName",productQuotesInfoVO.getCustomerName()); //甲方名称
 wordDataMap.put("parametersMap", parametersMap);
  wordDataMap.put("foreachData", contractProductInfoVOList);
try {
//            fileInputStream = new FileInputStream(new File(contractTemplatePath+"hetongmoban-01.docx"));
            fileInputStream = new FileInputStream(new File(outTemplatePath)); // TODO 直接读文件服务器待验证
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        ContractFileWordTemplate template = null;
        try {
            template = new ContractFileWordTemplate(fileInputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 替换数据
        try {
            template.replaceDocument(wordDataMap);
        } catch (Exception e) {
            e.printStackTrace();
        }
package com.ampc.workstation.util;

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 io.netty.util.internal.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.beans.BeanUtils;

    /**
     *
     * 对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里设置页边距窄一点,而不是直接拖动表格边框来实现。
     *
     */

    @Slf4j
    public class ContractFileWordTemplate {

        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 ContractFileWordTemplate(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) throws Exception {

            if (!dataMap.containsKey("parametersMap")) {
                System.out.println("数据源错误--数据源(parametersMap)缺失");
                return;
            }
            @SuppressWarnings("unchecked")
            Map<String, Object> parametersMap = (Map<String, Object>) dataMap
                    .get("parametersMap");

            //***************************** 页眉
            //替换页眉中的变量
            this.replaceHeaderOverWrite(document,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) {

//                        // 处理表格
                        List<XWPFTableCell> tableCells = table.getRows().get(0).getTableCells();// 获取到模板表格第一行,用来判断表格类型
                        String tableText = table.getText();// 表格中的所有文本
                        log.info("ContractFileWordTemplate-tableText",tableText);
//
                        if (tableText.contains("##{foreachData}##")) {  //TODO 判断是否是循环body体
//                            // 查找到##{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;
//                            }
//
//                            String tableType = tableCells.get(0).getText();
//                            String dataSource = tableCells.get(1).getText(); //TODO 获取循环表格数据源 可使用标签进行替换
//                            System.out.println("读取到数据源:"+dataSource);
//                            if (!dataMap.containsKey(dataSource)) {
//                                System.out.println("文档中第" + (curT + 1) + "个表格模板数据源缺失");
//                                return;
//                            }
//                            @SuppressWarnings("unchecked")
//                            List<Map<String, Object>> tableDataList = (List<Map<String, Object>>) dataMap
//                                    .get(dataSource);  //TODO 获取循环表格数据源 可使用标签进行替换 ##{foreachContractProductInfoVOList}## 中的左右括号替换掉
                        List<Map<String, Object>> tableDataList = (List<Map<String, Object>>) dataMap
                                .get("foreachData");

//                            if ("##{foreachTable}##".equals(tableType)) {
//                                // System.out.println("循环生成表格");
//                                addTableInDocFooter(table, tableDataList, parametersMap, 1);
//
//                            } else if ("##{foreachTableRow}##".equals(tableType)) {
//                                // System.out.println("循环生成表格内部的行");
//                                addTableInDocFooter(table, tableDataList, parametersMap, 2);
//                            }
                            addTableInDocFooter(table, tableDataList, parametersMap, 2);

//                    } else if (tableText.indexOf("{") > -1) {
                        } else if (tableText.indexOf("{") > -1) {
                            // 没有查找到##{foreach标签,查找到了普通替换数据的{}标签,该表格只需要简单替换
                            addTableInDocFooter(table, null, parametersMap, 3);
                        } else {
                            // 没有查找到任何标签,该表格是一个静态表格,仅需要复制一个即可。
                            addTableInDocFooter(table, null, null, 0);
                        }
                        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);

                        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) {

            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);//替换标签
                }

            } else if (flag == 2) {// 表格表格内部行循环
                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) {   //TODO 判断从table表的第几行开始  tagRowsIndex
                    if (rowText.indexOf("##{foreachData}##") > -1) {   //TODO 判断从table表的第几行开始  tagRowsIndex
                        tagRowsIndex = i;
                        break;
                    }
                }

                /* 复制模板行和标签行之前的行 */
//                for (int i = 1; i < tagRowsIndex; i++) {
                for (int i = 0; i < tagRowsIndex+1; i++) {
                    XWPFTableRow newCreateRow = newCreateTable.createRow();
                    CopyTableRow(newCreateRow, TempTableRows.get(i));// 复制行
                    replaceTableRow(newCreateRow, parametersMap);// 处理不循环标签的替换
                }

                /* 循环生成模板行 */
                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));// 处理标签替换
                }

                /* 复制模板行和标签行之后的行 */
                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();
                    CopyTableRowNotBorder(newCreateRow, templateTableRows.get(i));// 复制模板行文本和样式到新行,去掉边框
                }
                newCreateTable.removeRow(0);// 移除多出来的第一行
                document.createParagraph();// 添加回车换行
                replaceTable(newCreateTable, parametersMap);

            } 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();// 添加回车换行
            }

        }

        private void CopyTableRowNotBorder(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++) {
                copyTableCellNotBorder(target.getCell(i), source.getCell(i));
            }
        }

        private void copyTableCellNotBorder(XWPFTableCell newTableCell, XWPFTableCell templateTableCell) {
            // 列属性
            newTableCell.getCTTc().setTcPr(templateTableCell.getCTTc().getTcPr());

            //去掉边框
            CTTcBorders tblBorders = newTableCell.getCTTc().getTcPr().addNewTcBorders();
            tblBorders.addNewLeft().setVal(STBorder.NIL);
            tblBorders.addNewRight().setVal(STBorder.NIL);
            tblBorders.addNewTop().setVal(STBorder.NIL);
            tblBorders.addNewBottom().setVal(STBorder.NIL);
            newTableCell.getCTTc().getTcPr().setTcBorders(tblBorders);

            // 删除目标 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);
            }
        }


        /**
         * 根据 模板段落 和 数据 在文档末尾生成段落
         *
         * @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) {

            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);

            } 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) {
            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();

                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));
                        insertNewRun.setText(getValueBykey(key.toString(),parametersMap));
                        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());
                        // 设置文本
                        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=beginRunText.substring(0,beginRunText.indexOf("{"))+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);
                        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);

            }//if 有标签

        }


        /**
         * 复制表格行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) {

            List<XWPFTableCell> tableCells = tableRow.getTableCells();
            for (XWPFTableCell xWPFTableCell : tableCells) {
                List<XWPFParagraph> paragraphs = xWPFTableCell.getParagraphs();
                for (XWPFParagraph xwpfParagraph : paragraphs) {

                    replaceParagraph(xwpfParagraph, parametersMap);
                }
            }

        }

        /**
         * 根据map替换表格中的{key}标签
         * @author Juveniless
         * @date 2017年12月4日 下午2:47:36
         * @param xwpfTable
         * @param parametersMap
         *
         */
        public void replaceTable(XWPFTable xwpfTable,Map<String, Object> parametersMap){
            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);
                    }
                }
            }

        }

        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;
        }



        /***
         *功能描述
         * 替换页眉中的内容
         * @author wenzhe.zhou
         * @date 2020/5/25
         * @param doc
         * @param dynaBean
         * @return void
         */
        private void replaceHeaderOverWrite(XWPFDocument doc,Map<String, Object> dynaBean) throws Exception {
            List<XWPFHeader> xwpfHeaderList = doc.getHeaderList();
            Iterator iterator = xwpfHeaderList.iterator();
            XWPFParagraph para;
            XWPFHeader xwpfHeader;
            while (iterator.hasNext()) {
                xwpfHeader = (XWPFHeader) iterator.next();
                List<XWPFParagraph> xwpfParagraphList = xwpfHeader.getParagraphs();
                Iterator iteratorPara = xwpfParagraphList.iterator();
                while (iteratorPara.hasNext()){
                    para = (XWPFParagraph) iteratorPara.next();
                    this.replaceInParaOverWrite(para,dynaBean);
                }
            }
        }

        /**
         *功能描述
         * 替换段落里面的变量
         * @author wenzhe.zhou
         * @date 2020/5/9
         * @param para
         * @param dynaBean
         * @return void
         */
        private void replaceInParaOverWrite(XWPFParagraph para,Map<String, Object> dynaBean) {
            List<XWPFRun> runs;
            Boolean matcher;
            if (this.matcher(para.getParagraphText())) {
                runs = para.getRuns();
                for (int i=0; i<runs.size(); i++) {
                    XWPFRun run = runs.get(i);
                    int fontSize = run.getFontSize();
                    String fontFamily = run.getFontFamily();
                    String runText = run.toString().trim();
                    Boolean isDic =false;
                    matcher = this.matcher(runText);
                    if (matcher|| StringUtils.isNotEmpty(dynaBean.get("contractNo").toString())) {
                        if ((this.matcher(runText))) {
                            //普通字段
                            if (!runText.contains("ONE")&&!runText.contains("LIST")&&!runText.contains("DIC")){
                                runText = runText.replaceAll("\\{","").replaceAll("}","").replaceAll("#","");
                                if (Objects.equals(runText.trim(),"")){
                                    runText ="";
                                }else {
                                    runText = getRangeData( dynaBean,runText.trim());
                                }
                            } else if (runText.contains("DIC")){
                                //字典
                                isDic = true;
                            }
                            else {
                                runText ="";
                            }
                        }else {
                            runText = getRangeData( dynaBean,runText.trim());
                        }
                        //直接调用XWPFRun的setText()方法设置文本时,在底层会重新创建一个XWPFRun,把文本附加在当前文本后面,
                        //所以我们不能直接设值,需要先删除当前run,然后再自己手动插入一个新的run。
                        para.removeRun(i);
                        XWPFRun newRun=para.insertNewRun(i);
                        //字典
                        if (isDic){
                            List<String> valueList = substringData(runText);
                            String dicCode =valueList.get(0);
                            String paramValue = valueList.get(1);
                            //是否换行
                            Boolean isBreak = false;
                            if (valueList.size()>3){
                                isBreak= StringUtils.isNotEmpty(valueList.get(3))?Boolean.valueOf(valueList.get(3)):false;
                            }
                            paramValue = getRangeData( dynaBean,paramValue.trim());
                            //设置字典
//                        this.setCheckBox(dicCode,paramValue,newRun,isBreak);
                        }else {
                            newRun.setText(runText);
                        }
                        //设置字体大小、格式
                        if (StringUtils.isNotEmpty(fontFamily)){
                            newRun.setFontFamily(fontFamily);
                        }
                        if (fontSize>=0){
                            newRun.setFontSize(fontSize);
                        }
                    }
                }
            }
        }


        /***
         *功能描述
         * 验证格式
         * @author wenzhe.zhou
         * @date 2020/5/9
         * @param str
         * @return java.lang.Boolean
         */
        private Boolean matcher(String str) {
            return str.contains("{") || str.contains("}");
        }

        /***
         *功能描述
         * 获取要填充的数据
         * @author wenzhe.zhou
         * @date 2020/5/9
         * @param dataBean
         * @param key
         * @return java.lang.String
         */
        private String getRangeData(Map<String, Object> dataBean,String key){
            //自己实现数据逻辑
            return  key.replace("contractNo",dataBean.get("contractNo").toString());
        }


        /**
         *功能描述
         * 截取字符串
         * "#表##值##类型#"
         * @author wenzhe.zhou
         * @date 2020/5/20
         * @param text
         * @return java.lang.String
         */
        public List<String> substringData(String text) {
            String regex = "#([^#]+)#";
            List<String> paramList = new ArrayList<>(16);
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(text);
            while (matcher.find()) {
                paramList.add(matcher.group(1));
            }
            return paramList;
        }


    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值