模板:

java 替换html中的参数 java 模板替换_java 替换html中的参数

依赖:

<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>

Controller层

/**
     * 功能描述: Word 导出
     */
    @GetMapping("/filmReview/download")
    public void exportTemplate(HttpServletRequest request, @RequestParam Integer filmId, @RequestParam Integer filmReviewId, HttpServletResponse response) {

        try {
            if (StringUtils.isEmpty(filmId)) throw new FaultException("电影节id不能为空");
            if (StringUtils.isEmpty(filmReviewId)) throw new FaultException("审片管理id不能为空");
            //查询
            wanda.stark.core.data.R film = filmService.findById(filmId);
            HashMap filmResponse = (HashMap) film.getData();
            wanda.stark.core.data.R filmReview = filmReviewService.findById(filmReviewId);
            HashMap filmReviewResponse = (HashMap) filmReview.getData();
            Map<String, Object> wordDataMap = setData(filmResponse, filmReviewResponse);
            String url = GetResource.class.getClassLoader().getResource("template/审片管理模板.docx").getPath();
            url = URLDecoder.decode(url, StandardCharsets.UTF_8);
            File file = new File(url);//改成你本地文件所在目录
            // 读取word模板
            FileInputStream fileInputStream = new FileInputStream(file);
            WordTemplate template = new WordTemplate(fileInputStream);
            // 替换数据
            template.replaceDocument(wordDataMap);

            setResponseHeader(request, response, replaceSpecStr("审片管理模板.docx"));
            ServletOutputStream out = null;
            try {
                out = response.getOutputStream();
                template.write(out);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("导出word出错", e);
        }
    }

    private Map<String, Object> setData(HashMap filmResponse, HashMap filmReviewResponse) {

        Map<String, Object> wordDataMap = new HashMap<String, Object>();// 存储报表全部数据
        Map<String, Object> parametersMap = new HashMap<String, Object>();// 存储报表中不循环的数据

        parametersMap.put("filmSerialNum", filmReviewResponse.get("filmSerialNum"));  //影片编号
        parametersMap.put("filmNameZh", filmReviewResponse.get("filmNameZh"));  //中文片名
        parametersMap.put("filmNameEn", filmReviewResponse.get("filmNameEn"));  //英文片名
        Object completedDate = filmResponse.get("completedDate");
        if (!StringUtils.isEmpty(completedDate)) {
            parametersMap.put("completedDate", completedDate.toString().substring(0, 4));  //    年份
        }
        if (!StringUtils.isEmpty(filmResponse.get("runningTime"))) {
            parametersMap.put("runningTime", filmResponse.get("runningTime") + "分钟");  //片长
        }
        parametersMap.put("productionCountryRegion", filmResponse.get("productionCountryRegionZh"));  //国家
        parametersMap.put("genreZh", filmResponse.get("genreZh"));  //类型
        parametersMap.put("sectionZh", filmReviewResponse.get("sectionZh"));  //申报单元
        parametersMap.put("enterSectionZh", filmReviewResponse.get("enterSectionZh"));  //入围单元
        parametersMap.put("starring", filmResponse.get("starring"));  //演员
        parametersMap.put("director", filmReviewResponse.get("director"));  //导演
        //featureFilmSize
        //当为1的时候显示为 ‘是编剧首部/第二部长片’‘是导演首部/第二部长片
        //’ 为0或者空的时候不显示
        if (!StringUtils.isEmpty(filmReviewResponse.get("featureFilmSize"))) {
            if (Integer.parseInt(filmReviewResponse.get("featureFilmSize").toString()) == 1) {
                parametersMap.put("featureFilmSize", "是导演首部/第二部长片");  //导演

            }
        }
        parametersMap.put("scriptwriter", filmReviewResponse.get("scriptwriter"));  //编剧
        // scriptwriterFeatureFilmSize
        //当为1的时候显示为 ‘是编剧首部/第二部长片’‘是导演首部/第二部长片
        //’ 为0或者空的时候不显示
        if (!StringUtils.isEmpty(filmReviewResponse.get("scriptwriterFeatureFilmSize"))) {
            if (Integer.parseInt(filmReviewResponse.get("scriptwriterFeatureFilmSize").toString()) == 1) {
                parametersMap.put("scriptwriterFeatureFilmSize", "是编剧首部/第二部长片");  //编剧

            }
        }
        parametersMap.put("filmAwards", filmReviewResponse.get("filmAwards"));//影片所获奖项
        parametersMap.put("starringAwards", filmReviewResponse.get("starringAwards"));//演员所获奖项
        parametersMap.put("directorAwards", filmReviewResponse.get("directorAwards"));//导演曾获奖项
        parametersMap.put("remark", filmReviewResponse.get("remark"));//备注
        parametersMap.put("synopsis", filmResponse.get("synopsis"));//故事梗概
        parametersMap.put("firstInstanceOpinion", filmReviewResponse.get("firstInstanceOpinion"));//一审意见  firstInstanceApprover  firstInstanceDay
        if (!StringUtils.isEmpty(filmReviewResponse.get("firstInstanceApprover"))) {
            parametersMap.put("firstInstanceApproverAndDay", filmReviewResponse.get("firstInstanceApprover") + "\t" + filmReviewResponse.get("firstInstanceDay"));
        }
        if (!StringUtils.isEmpty(filmReviewResponse.get("firstInstanceConclusion"))) {
            parametersMap.put("firstInstanceConclusion", filmReviewResponse.get("firstInstanceConclusion").toString().equals("1") ? "通过" : "不通过");//一审结论  firstInstanceConclusion
        }
        parametersMap.put("secondInstanceOpinion", filmReviewResponse.get("secondInstanceOpinion"));//二审意见
        if (!StringUtils.isEmpty(filmReviewResponse.get("secondInstanceApprover"))) {
            parametersMap.put("secondInstanceApproverAndDay", filmReviewResponse.get("secondInstanceApprover") + "\t" + filmReviewResponse.get("secondInstanceDay"));
        }
        if (!StringUtils.isEmpty(filmReviewResponse.get("secondInstanceConclusion"))) {
            parametersMap.put("secondInstanceConclusion", filmReviewResponse.get("secondInstanceConclusion").toString().equals("1") ? "通过" : "不通过");//二审结论
        }
        parametersMap.put("thirdTrialOpinion", filmReviewResponse.get("thirdTrialOpinion"));//三审意见
        if (!StringUtils.isEmpty(filmReviewResponse.get("thirdTrialApprover"))) {
            parametersMap.put("thirdInstanceApproverAndDay", filmReviewResponse.get("thirdTrialApprover") + "\t" + filmReviewResponse.get("thirdTrialDay"));
        }
        if (!StringUtils.isEmpty(filmReviewResponse.get("thirdTrialConclusion"))) {
            parametersMap.put("thirdTrialConclusion", filmReviewResponse.get("thirdTrialConclusion").toString().equals("1") ? "通过" : "不通过");//三审结论
        }
        ArrayList<HashMap> doubtList = (ArrayList<HashMap>) filmReviewResponse.get("doubtList");

        StringBuilder stringBuilder = new StringBuilder();
        for (HashMap map : doubtList) {
            String doubtTime = (String) map.get("doubtTime");
            String doubtContent = (String) map.get("doubtContent");
            String createUserName = (String) map.get("createUserName");
            String createTime = (String) map.get("createTime");
            stringBuilder.append(doubtTime).append("\t").append(doubtContent).append("\t").append(createUserName).append("\t").append(createTime).append("\n");
        }
        String s = stringBuilder.toString();
        if (!StringUtils.isEmpty(s)) {
            String substring = s.substring(0, s.length() - 1);
            parametersMap.put("doubtList", substring);//看片疑点
        }
        wordDataMap.put("parametersMap", parametersMap);
        return wordDataMap;
    }


 /**
     * 正则替换所有特殊字符
     *
     * @param orgStr
     * @return
     */
    public static String replaceSpecStr(String orgStr) {
        if (null != orgStr && !"".equals(orgStr.trim())) {
            String regEx = "[\\\\|:/\"<>?*\\[\\] ]";
            Pattern p = Pattern.compile(regEx);
            Matcher m = p.matcher(orgStr);
            return m.replaceAll("_");
        }
        return null;
    }
/**
     * 设置响应的类型、编码和文件名称
     *
     * @param response
     * @param fileName
     */
    public static void setResponseHeader(HttpServletRequest request, HttpServletResponse response, String fileName) {
        try {
            String userAgent = request.getHeader("User-Agent");
            byte[] bytes = userAgent.contains("MSIE") ? fileName.getBytes() : fileName.getBytes("UTF-8"); // name.getBytes("UTF-8")处理safari的乱码问题  
            fileName = new String(bytes, "ISO-8859-1"); // 各浏览器基本都支持ISO编码  
            response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", fileName));
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/OCTET-STREAM;charset=UTF-8");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

WordTemplate

package ccff.admin.api.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 对docx文件中的文本及表格中的内容进行替换 --模板仅支持对 {key} 标签的替换
 *
 * @ClassName: WordTemplate
 * @Description: TODO(! ! ! 使用word2013 docx文件)
 * <br>(1)word模板注意页边距的问题,存在问题:比如页边距默认为3cm,画表格时,仍然可以通过
 * 拖拽,把表格边框拖动到看起来就像页边距只有1cm的样子,但是实际上此时页边距还是3cm,生成的
 * word报表的页边距还是会按照3cm来生成。解决办法,在word文件里,设置好页边距,如果需要表格
 * 两边页边距很窄,需要在word里设置页边距窄一点,而不是直接拖动表格边框来实现。
 */

@Slf4j
public class WordTemplate {

    private XWPFDocument document;

    public XWPFDocument getDocument() {
        return document;
    }

    public void setDocument(XWPFDocument document) {
        this.document = document;
    }

    /**
     * 初始化模板内容
     *
     * @param inputStream 模板的读取流(docx文件)
     * @throws IOException
     */
    public WordTemplate(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<Map<String, String>>
     *
     * @param dataMap
     */
    public void replaceDocument(Map<String, Object> dataMap) {

        if (!dataMap.containsKey("parametersMap")) {
            log.info("数据源错误--数据源(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) {
                    // 处理表格
                    List<XWPFTableCell> tableCells = table.getRows().get(0).getTableCells();// 获取到模板表格第一行,用来判断表格类型
                    String tableText = table.getText();// 表格中的所有文本
                    if (tableText.indexOf("{") > -1) {
                        // 没有查找到##{foreach标签,查找到了普通替换数据的{}标签,该表格只需要简单替换
                        addTableInDocFooter(table, null, parametersMap, 3);
                    } else {
                        // 没有查找到任何标签,该表格是一个静态表格,仅需要复制一个即可。
                        addTableInDocFooter(table, null, null, 0);
                    }
                    curT++;
                }
            } else if (BodyElementType.PARAGRAPH.equals(body.getElementType())) {// 处理段落

                log.info("获取到段落");
                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文档末尾生成表格
     *
     * @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 == 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);

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


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

    }


    /**
     * 根据map替换段落元素内的{**}标签
     *
     * @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 endRunIndex = xWPFParagraph.searchText("}", new PositionInParagraph()).getEndRun();// 结束标签
            int beginRunIndex = xWPFParagraph.searchText("{", new PositionInParagraph()).getBeginRun();// 标签开始run位置
            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));

                    String runText = getValueBykey(key.toString(), parametersMap);
                    if (runText.contains("\n")) {
                        //参数值包含\n代表需要换行(也可以设置成\r,只是一个标识,因为我在formatStatistic方法中设置的以\n为标识换行)
                        String[] text = runText.split("\n");
                        for (int j = 0; j < text.length; j++) {
                            if(j<text.length-1){
                                insertNewRun.setText(text[j].trim());//往新的段落里set参数值
                                insertNewRun.addBreak();// 换行
                            }else {
                                insertNewRun.setText(text[j].trim());//往新的段落里set参数值
                            }
                        }
                    } else {
                        insertNewRun.setText(runText);
                    }
                    if (runText.contains("\t")) {
                        //参数值包含\n代表需要换行(也可以设置成\t,只是一个标识,因为我在formatStatistic方法中设置的以\t为标识换行)
                        String[] text = runText.split("\t");
                        for (int j = 0; j < text.length; j++) {
                            insertNewRun.addTab();
                        }
                    }
                    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
                }
            }
//            replaceParagraph(xWPFParagraph, parametersMap);
        }

    }


    /**
     * 复制表格行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格式
     *
     * @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格式
     *
     * @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
     *
     * @param newRun      新创建的的文本节点
     * @param templateRun 模板文本节点
     */
    private void CopyRun(XWPFRun newRun, XWPFRun templateRun) {
        newRun.getCTR().setRPr(templateRun.getCTR().getRPr());
        // 设置文本
        newRun.setText(templateRun.text());
    }


    /**
     * 根据参数parametersMap对表格的一行进行标签的替换
     *
     * @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}标签
     *
     * @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;
    }


}