java通过word模板生成导出word

java通过word模板生成导出word


#生成word方法类

public class BokeWordUtils {
    
    
    /**
     * 根据模板生成新word文档
     * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
     *
     * @param inputUrl  模板存放地址
     * @param outputUrl 新文档存放地址
     * @param textMap   需要替换的信息集合
     * @param tableList 需要插入的表格信息集合
     */
    public static boolean changWord(String inputUrl, String outputUrl,
                                    Map<String, String> textMap, List<String[]> tableList) {
    
    
        //模板转换默认成功
        boolean changeFlag = true;
        try {
    
    
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl.trim()));
            //解析替换文本段落对象
            BokeWordUtils.changeText(document, textMap);
            //解析替换表格对象
            BokeWordUtils.changeTable(document, textMap, tableList);
            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();
            System.out.println("成功生成!");
        } catch (IOException e) {
    
    
            e.printStackTrace();
            changeFlag = false;
        }

        return changeFlag;

    }

    /**
     * 根据模板生成新word文档
     * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
     *
     * @param inputStream  模板存放地址
     * @param outputUrl 新文档存放地址
     * @param textMap   需要替换的信息集合
     * @param tableList 需要插入的表格信息集合
     */
    public static boolean changWord(InputStream inputStream, String outputUrl,
                                    Map<String, String> textMap, List<String[]> tableList) {
    
    
        //模板转换默认成功
        boolean changeFlag = true;
        try {
    
    
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(inputStream);
            //解析替换文本段落对象
            BokeWordUtils.changeText(document, textMap);
            //解析替换表格对象
            BokeWordUtils.changeTable(document, textMap, tableList);
            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();
            inputStream.close();
            System.out.println("成功生成!");
        } catch (IOException e) {
    
    
            e.printStackTrace();
            changeFlag = false;
        }

        return changeFlag;

    }

    /**
     * 替换段落文本
     *
     * @param document docx解析对象
     * @param textMap  需要替换的信息集合
     */
    public static void changeText(XWPFDocument document, Map<String, String> textMap) {
    
    
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
    
    
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            if (checkText(text)) {
    
    
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
    
    
                    //替换模板原来位置
                    // run.setText(changeValue(run.toString(), textMap),0);
                    String textValue = changeValue(run.toString(), textMap);
                    run.setText(textValue, 0);
                }
            }
        }
    }

    /**
     * 替换表格对象方法
     *
     * @param document  docx解析对象
     * @param textMap   需要替换的信息集合
     * @param tableList 需要插入的表格信息集合
     */
    public static void changeTable(XWPFDocument document, Map<String, String> textMap,
                                   List<String[]> tableList) {
    
    
        //获取表格对象集合
        List<XWPFTable> tables = document.getTables();
        for (int i = 0; i < tables.size(); i++) {
    
    
            //只处理行数大于等于2的表格,且不循环表头
            XWPFTable table = tables.get(i);
            if (table.getRows().size() > 1) {
    
    
                //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
                if (checkText(table.getText())) {
    
    
                    List<XWPFTableRow> rows = table.getRows();
                    //遍历表格,并替换模板
                    eachTable(rows, textMap);
                } else {
    
    
//                  System.out.println("插入"+table.getText());
                    insertTable(table, tableList);
                }
            }
        }
    }


    /**
     * 遍历表格
     *
     * @param rows    表格行对象
     * @param textMap 需要替换的信息集合
     */
    public static void eachTable(List<XWPFTableRow> rows, Map<String, String> textMap) {
    
    
        for (XWPFTableRow row : rows) {
    
    
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
    
    
                //判断单元格是否需要替换
                if (checkText(cell.getText())) {
    
    
                    List<XWPFParagraph> paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
    
    
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (XWPFRun run : runs) {
    
    
                            run.setText(changeValue(run.toString(), textMap), 0);
                        }
                    }
                }
            }
        }
    }

    /**
     * 为表格插入数据,行数不够添加新行
     *
     * @param table     需要插入数据的表格
     * @param tableList 插入数据集合
     */
    public static void insertTable(XWPFTable table, List<String[]> tableList) {
    
    
        //创建行,根据需要插入的数据添加新行,不处理表头
        for (int i = 1; i < tableList.size(); i++) {
    
    
            XWPFTableRow row = table.createRow();
        }
        //遍历表格插入数据
        List<XWPFTableRow> rows = table.getRows();
        for (int i = 1; i < rows.size(); i++) {
    
    
            XWPFTableRow newRow = table.getRow(i);
            List<XWPFTableCell> cells = newRow.getTableCells();
            for (int j = 0; j < cells.size(); j++) {
    
    
                XWPFTableCell cell = cells.get(j);
                cell.setText(tableList.get(i - 1)[j]);
            }
        }
    }

    /**
     * 判断文本中时候包含$
     *
     * @param text 文本
     * @return 包含返回true, 不包含返回false
     */
    public static boolean checkText(String text) {
    
    
        boolean check = false;
        if (text.indexOf("$") != -1) {
    
    
            check = true;
        }
        return check;
    }

    /**
     * 匹配传入信息集合与模板
     *
     * @param value   模板需要替换的区域
     * @param textMap 传入信息集合
     * @return 模板需要替换区域信息集合对应值
     */
    public static String changeValue(String value, Map<String, String> textMap) {
    
    
        Set<Entry<String, String>> textSets = textMap.entrySet();
        for (Entry<String, String> textSet : textSets) {
    
    
            //匹配模板与替换值 格式${key}
            String key = "${" + textSet.getKey() + "}";
            if (value.indexOf(key) != -1) {
    
    
                // value = textSet.getValue();//全部参数替换
                value = value.replace(key, textSet.getValue());//仅替换参数
            }
        }
        //模板未匹配到区域替换为空
        if (checkText(value)) {
    
    
            value = "";
        }
        return value;
    }
    /**
     * 合并docx文件
     *
     * @param srcDocxs 需要合并的目标docx文件
     * @param destDocx 合并后的docx输出文件
     */
    public static void mergeDoc(List<String> srcDocxs, String destDocx) {
    
    
        OutputStream dest = null;
        List<OPCPackage> opcpList = new ArrayList<OPCPackage>();
        int length = null == srcDocxs ? 0 : srcDocxs.size();
        /**
         * 循环获取每个docx文件的OPCPackage对象
         */
        for (int i = 0; i < length; i++) {
    
    
            String doc = srcDocxs.get(i);
            OPCPackage srcPackage = null;
            try {
    
    
                srcPackage = OPCPackage.open(doc);
            } catch (Exception e) {
    
    
                e.printStackTrace();
            }
            if (null != srcPackage) {
    
    
                opcpList.add(srcPackage);
            }
        }
        int opcpSize = opcpList.size();
        //获取的OPCPackage对象大于0时,执行合并操作
        if (opcpSize > 0) {
    
    
            try {
    
    
                dest = new FileOutputStream(destDocx);
                XWPFDocument src1Document = new XWPFDocument(opcpList.get(0));
                CTBody src1Body = src1Document.getDocument().getBody();
                //OPCPackage大于1的部分执行合并操作
                if (opcpSize > 1) {
    
    
                    for (int i = 1; i < opcpSize; i++) {
    
    
                        OPCPackage src2Package = opcpList.get(i);
                        XWPFDocument src2Document = new XWPFDocument(src2Package);
                        CTBody src2Body = src2Document.getDocument().getBody();
                        appendBody(src1Body, src2Body);
                    }
                }
                //将合并的文档写入目标文件中
                src1Document.write(dest);
            } catch (FileNotFoundException e) {
    
    
                e.printStackTrace();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            } catch (Exception e) {
    
    
                e.printStackTrace();
            } finally {
    
    
                //关闭流
                IOUtils.closeQuietly(dest);
            }
        }
    }

    /**
     * 合并文档内容
     *
     * @param src    目标文档
     * @param append 要合并的文档
     * @throws Exception
     */
    private static void appendBody(CTBody src, CTBody append) throws Exception {
    
    
        XmlOptions optionsOuter = new XmlOptions();
        optionsOuter.setSaveOuter();
        String appendString = append.xmlText(optionsOuter);
        //替换word中得空行、根据自己需求来选择需不需要
        //word文档其实是由xml文件合成得,一下替换得是作者对应得xml文件中得空行标签
        appendString = appendString.replaceAll("<w:p><w:pPr><w:spacing w:line=\\\"360\\\" w:lineRule=\\\"auto\\\"/><w:jc w:val=\\\"right\\\"/><w:rPr><w:rFonts w:ascii=\\\"仿宋\\\" w:eastAsia=\\\"仿宋\\\" w:hAnsi=\\\"仿宋\\\"/><w:sz w:val=\\\"24\\\"/></w:rPr></w:pPr></w:p>","");
        appendString = appendString.replaceAll("<w:p><w:pPr xsi:nil=\\\"true\\\" xmlns:xsi=\\\"xsi\\\"/></w:p>","");
        appendString = appendString.replaceAll("<w:p><w:pPr><w:ind w:firstLineChars=\\\"200\\\" w:firstLine=\\\"600\\\"/><w:jc w:val=\\\"right\\\"/><w:rPr><w:rFonts w:ascii=\\\"仿宋\\\" w:eastAsia=\\\"仿宋\\\" w:hAnsi=\\\"仿宋\\\"/><w:sz w:val=\\\"30\\\"/><w:szCs w:val=\\\"30\\\"/></w:rPr></w:pPr></w:p>","");
        appendString = appendString.replaceAll("<w:spacing w:line=\\\"360\\\" w:lineRule=\\\"auto\\\"/>","");;
        String srcString = src.xmlText();
        srcString = srcString.replaceAll("<w:p><w:pPr><w:ind w:firstLineChars=\\\"200\\\" w:firstLine=\\\"600\\\"/><w:jc w:val=\\\"right\\\"/><w:rPr><w:rFonts w:ascii=\\\"仿宋\\\" w:eastAsia=\\\"仿宋\\\" w:hAnsi=\\\"仿宋\\\"/><w:sz w:val=\\\"30\\\"/><w:szCs w:val=\\\"30\\\"/></w:rPr></w:pPr></w:p>","");
        srcString = srcString.replaceAll("<w:spacing w:line=\\\"360\\\" w:lineRule=\\\"auto\\\"/>","");
        srcString = srcString.replaceAll("<w:p><w:pPr><w:spacing w:line=\\\"360\\\" w:lineRule=\\\"auto\\\"/><w:jc w:val=\\\"right\\\"/><w:rPr><w:rFonts w:ascii=\\\"仿宋\\\" w:eastAsia=\\\"仿宋\\\" w:hAnsi=\\\"仿宋\\\"/><w:sz w:val=\\\"24\\\"/></w:rPr></w:pPr></w:p>","");
        srcString = srcString.replaceAll("<w:p><w:pPr xsi:nil=\\\"true\\\" xmlns:xsi=\\\"xsi\\\"/></w:p>","");
        String prefix = srcString.substring(0, srcString.indexOf(">") + 1);
        String mainPart = srcString.substring(srcString.indexOf(">") + 1,
                srcString.lastIndexOf("<"));
        String sufix = srcString.substring(srcString.lastIndexOf("<"));
        String addPart = appendString.substring(appendString.indexOf(">") + 1,
                appendString.lastIndexOf("<"));
        CTBody makeBody = CTBody.Factory.parse(prefix + mainPart + addPart
                + sufix);
        src.set(makeBody);
    }

}

#方法调用

//获取项目内模板
InputStream url = this.getClass().getClassLoader().getResourceAsStream("xxx.docx");
//生成后的文件路径
String outPutUrl = "export/xxx.docx";
//文本填充
Map<String, String> testMap = new HashMap<String, String>();
testMap.put("name", "123");
testMap.put("age", "12");
testMap.put("sex", "女");
//表格填充
List<String[]> tableList= new ArrayList<String[]>();
tableList.add(new String[]{
    
    "1","张三","12","男"});
tableList.add(new String[]{
    
    "2","李四","33","男"});
tableList.add(new String[]{
    
    "3","王麻子","22","男"});
tableList.add(new String[]{
    
    "4","孙二娘","44","女"});
//生成
BokeWordUtils.changWord(url, outPutUrl, testMap, tableList);

#文本模板配置
模板设置
#表格模板配置
表格模板配置i
#最终呈现效果
最终呈现效果

猜你喜欢

转载自blog.csdn.net/yuanbo_520/article/details/118303458
今日推荐