Poi按模板导出word,替换文本,插入图片

wylc123 2月前 ⋅ 36 阅读

模板样式:

生成效果:

上代码:

package kbaseSync.Base;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import kbaseSync.config.ChromeDriverConf;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.util.Units;
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.util.ResourceUtils;

/**
 * 通过word模板生成新的word工具类
 * @author SongBin on 2019/9/5.
 */

public class WorderToNewWordUtils {

    /**
     * 根据模板生成新word文档
     * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
     * @param inputUrl 模板存放地址
     * @param outputUrl 新文档存放地址
     * @param textMap 需要替换的信息集合
     * @param tableList 需要插入的表格信息集合
     * @return 成功返回true,失败返回false
     */
    public static boolean changWord(String inputUrl, String outputUrl,
                                    Map<String, String> textMap, List<String[]> tableList, Map<String ,String> imgMap) {

        //模板转换默认成功
        boolean changeFlag = true;
        try {
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //解析替换文本段落对象
            WorderToNewWordUtils.changeText(document, textMap,imgMap);
            //解析替换表格对象
            WorderToNewWordUtils.changeTable(document, textMap, tableList);

            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();

        } catch (IOException e) {
            e.printStackTrace();
            changeFlag = false;
        }

        return changeFlag;

    }

    /**
     * 根据无表格模板生成新word文档
     * @param inputUrl 模板存放地址
     * @param outputUrl 新文档存放地址
     * @param textMap 需要替换的信息集合
     * @return 成功返回true,失败返回false
     */
    public static boolean changWord(String inputUrl, String outputUrl,
                                    Map<String, String> textMap, Map<String ,String> imgMap) {
        //模板转换默认成功
        boolean changeFlag = true;
        try {
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //解析替换文本段落对象
            WorderToNewWordUtils.changeText(document, textMap,imgMap);
            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();
        } catch (IOException e) {
            e.printStackTrace();
            changeFlag = false;
        }
        return changeFlag;
    }

    /**
     * 遍历word获取每种农产品需要统计的菜品类型
     * @param inputUrl 模板地址
     * @return
     */
    public static Map<String,String> getClassifyObj(String inputUrl){
        Map<String,String> map = new HashMap<>();
        try {
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //获取段落集合
            List<XWPFParagraph> paragraphs = document.getParagraphs();
            int i = 1;
            for (XWPFParagraph paragraph : paragraphs) {
                //判断此段落时候需要进行替换
                String text = paragraph.getText();
                Matcher m = Pattern.compile("(?d)——(.+?))$").matcher(text);
                if (m.find()) {
                    Matcher matcher=Pattern.compile("(?d)((.+?))$").matcher(text);
                    if (matcher.find()){
                        String objstr = matcher.group(1).replace('、',',');
                        map.put("obj0"+i,objstr);
                        i++;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }
    /**
     * 替换段落文本
     * @param document docx解析对象
     * @param textMap 需要替换的信息集合
     */
    public static void changeText(XWPFDocument document, Map<String, String> textMap, Map<String ,String> imgMap){
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();

        for (XWPFParagraph paragraph : paragraphs) {
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            if(checkText(text)){
                List<XWPFRun> runs = paragraph.getRuns();
                XWPFRun run0 = runs.get(0);
                if(text.matches("(?d)^\\$img0[1-5]")){//插入图片
                    for (XWPFRun run : runs) {
                        //替换模板原来位置
                        run.setText("",0);
                    }
                    changeParagraphImg(run0,imgMap.get(text));
                }else{
                    if (text.indexOf(":")!= -1&&runs.size()>1){
                        run0.setText(text.substring(0,text.indexOf(":")+1),0);
                        XWPFRun run1 = runs.get(1);
                        for (int i=1;i<runs.size();i++) {
                            //替换模板原来位置
                            XWPFRun run = runs.get(i);
                            run.setText("",0);
                        }
                        text = text.replaceAll("(?d)^(.+?):","");
                        //替换模板原来位置
                        run1.setText(changeValue(text, textMap),0);
                        run1.setBold(false);
                    }else{
                        for (XWPFRun run : runs) {
                            //替换模板原来位置
                            run.setText("",0);
                        }
                        //替换模板原来位置
                        run0.setText(changeValue(text, textMap),0);
                    }
                }
            }
        }

    }
    /**
     * 插入图片
     * @param run
     * @param imgGuid
     */
    public static void changeParagraphImg(XWPFRun run, String imgGuid){
        try {
            String basePath =StringUtil.isBlank(ChromeDriverConf.picSavePath)?"D:/imgupload/":ChromeDriverConf.picSavePath;
            String imgFile = basePath + imgGuid +".jpg";
            System.out.println("插入图表图片:" + imgFile);
            FileInputStream is = new FileInputStream(imgFile);
            run.addPicture(is, XWPFDocument.PICTURE_TYPE_JPEG, imgFile, Units.toEMU(400), Units.toEMU(300)); // 100x100 pixels
            is.close();
            run.setText("",0);
        } catch (Exception e) {
            System.out.println("Error: ========  插入单个图片时出错了:可能是图片路径不存在。不影响主流程");
            e.printStackTrace();
        }
    }

    /**
     * 替换表格对象方法
     * @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()+"}";
            String regexstr = "(?d)\\$\\{"+textSet.getKey()+"\\}";
            if(value.indexOf(key)!= -1){
                value = value.replaceAll(regexstr,textSet.getValue());
            }
        }
        //模板未匹配到区域替换为空
        if(checkText(value)){
            value = value.replaceAll("(?d)\\$\\{(.+?)\\}","");
        }
        return value;
    }




    public static void main(String[] args) {
//        测试1
        //模板文件地址
        /*String inputUrl = "C:\\Users\\SongBin\\Desktop\\demo\\001.docx";
        //新生产的模板文件
        String outputUrl = "C:\\Users\\SongBin\\Desktop\\demo\\test.docx";

        Map<String, String> testMap = new HashMap<String, String>();
        testMap.put("name", "小明");
        testMap.put("sex", "男");
        testMap.put("age", "30");
        testMap.put("like", "IT");
        testMap.put("birthday", "2019-02-18");
        testMap.put("address", "软件园");
        testMap.put("phone", "18612100611");
        testMap.put("email", "1370811553@qq.com");

        List<String[]> testList = new ArrayList<String[]>();
        testList.add(new String[]{"1","1AA","1BB","1CC"});
        testList.add(new String[]{"2","2AA","2BB","2CC"});
        testList.add(new String[]{"3","3AA","3BB","3CC"});
        testList.add(new String[]{"4","4AA","4BB","4CC"});

        WorderToNewWordUtils.changWord(inputUrl, outputUrl, testMap, testList);*/



//        测试2
        //模板文件地址
        String inputUrl2 = "C:\\Users\\SongBin\\Desktop\\demo\\报告模板-价格.docx";
        //新生产的模板文件
        String outputUrl2 = "C:\\Users\\SongBin\\Desktop\\demo\\test.docx";

        Map<String, String> testMap2 = new HashMap<String, String>();
        testMap2.put("datetime", "2019-02-06");
        testMap2.put("粳米(普通)","粳米(普通)25元/公斤;");
        testMap2.put("大米","大米25元/公斤;");
        testMap2.put("week","07.16-7-22 ");
        Map<String ,String> imgMap = new HashMap<>();
        imgMap.put("$img01","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img02","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img03","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img04","3f956a32-f236-4baa-a8be-f465fa844580");
        imgMap.put("$img05","3f956a32-f236-4baa-a8be-f465fa844580");
        WorderToNewWordUtils.changWord(inputUrl2, outputUrl2, testMap2,imgMap);

        String content = "在一些字里面放进去高中这两个字";

        Matcher matcher = Pattern.compile("高中").matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(1));
        }
        //判断此段落时候需要进行替换
        /*String text = "近一周09.05-09.11农产品价格走势图——蔬菜(大白菜、小白菜、油菜、白萝卜、西红柿、黄瓜、茄子、香菇、平菇)";
        Matcher m = Pattern.compile("(?d)——(.+?))$").matcher(text);
        if (m.find()) {
            Matcher matcher=Pattern.compile("(?d)((.+?))$").matcher(text);
            if (matcher.find()){
                String objstr = matcher.group(1).replace('、',',');
                System.out.println(objstr);
            }
        }*/

        //测试但斜杠转转双斜杠
        //模板文件地址
        /*String inputUrl = null;
        try {
            inputUrl = ResourceUtils.getURL("classpath:static/wordmodel/报告模板-价格.docx").getPath().substring(1);
            inputUrl = inputUrl.replaceAll("/", "\\\\\\\\");
            try {
                inputUrl = java.net.URLDecoder.decode(inputUrl,"utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            System.out.println(inputUrl);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }*/
    }
}
更多内容请访问:IT源点

相关文章推荐

全部评论: 0

    我有话说: