通过word模板生成文档的工具类(poi改写可插入图片)

package me.zhengjie.modules.system.util;

import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.Map;
import java.util.Set;

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

        //模板转换默认成功
        boolean changeFlag = true;
        try {
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //解析替换文本段落对象
            changeText(document, textMap);
            //解析替换表格对象
            changeTable(document, textMap);
            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();

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

        return changeFlag;

    }
    /**
     * 根据模板生成新word文档
     * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
     *前端直接弹出下载
     * @param inputUrl  模板存放地址
     * @param textMap   需要替换的信息集合
     */
    public static void changWord2(String inputUrl,
                                  Map<String, Object> textMap, HttpServletResponse response) {

        try {
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //解析替换文本段落对象
            changeText(document, textMap);
            //解析替换表格对象
            changeTable(document, textMap);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();//二进制OutputStream
            document.write(baos);//文档写入流
            ByteArrayInputStream in = new ByteArrayInputStream(baos.toByteArray());//OutputStream写入InputStream二进制流
            BufferedInputStream bis = new BufferedInputStream(in);
            ServletOutputStream outputStream = response.getOutputStream();
            BufferedOutputStream bos = new BufferedOutputStream(outputStream);
            byte[] buff = new byte[8192];
            int bytesRead;
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
            bis.close();
            bos.close();
            outputStream.flush();
            outputStream.close();
        } catch (IOException | InvalidFormatException e) {
            e.printStackTrace();
        }
    }
    /**
     * 替换段落文本
     *
     * @param document docx解析对象
     * @param textMap  需要替换的信息集合
     */
    private static void changeText(XWPFDocument document, Map<String, Object> textMap) throws IOException, InvalidFormatException {
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();

        for (XWPFParagraph paragraph : paragraphs) {
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            List<XWPFRun> runs = paragraph.getRuns();
            for (XWPFRun run : runs) {
                //替换模板原来位置
                changeValue(run, textMap);
            }
        }

    }
    /**
     * 替换表格对象方法
     *
     * @param document  docx解析对象
     * @param textMap   需要替换的信息集合
     */
    private static void changeTable(XWPFDocument document, Map<String, Object> textMap) throws IOException, InvalidFormatException {
        //获取表格对象集合
        List<XWPFTable> tables = document.getTables();
        for (XWPFTable table : tables) {
            //只处理行数大于等于2的表格,且不循环表头
            if (table.getRows().size() > 1) {
                //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
                List<XWPFTableRow> rows = table.getRows();
                //遍历表格,并替换模板
                eachTable(rows, textMap);

            }
        }
    }


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

            }
        }
    }

    /**
     * 匹配传入信息集合与模板
     *
     * @param run   模板需要替换的区域
     * @param textMap 传入信息集合
     * @return 模板需要替换区域信息集合对应值
     */
    private static String changeValue(XWPFRun run, Map<String, Object> textMap) throws IOException, InvalidFormatException {
        Set<Map.Entry<String, Object>> textSets = textMap.entrySet();
        String value=run.toString();
        for (Map.Entry<String, Object> textSet : textSets) {
            //匹配模板与替换值 格式${key}
            String key = "${" + textSet.getKey() + "}";
            if (null!=value&&value.contains(key)) {
                if(textSet.getValue() instanceof String){
                    value = String.valueOf(textSet.getValue());
                    run.setText(value, 0);
                }else if(textSet.getValue() instanceof List){
                    value = value.replace(key, "");
                    List<Map<String,Object>> pic = (List) textSet.getValue();
                    for(Map<String,Object> imageList : pic) {
                        int format;
                        if(null!=imageList.get("img")&&!"".equals(imageList.get("img"))){
                            String[] imgFile=imageList.get("img").toString().split(";");
                            run.setText(imageList.get("name").toString());
                            for (int i=0;i<imgFile.length;i++){
                                if(imgFile[i].endsWith(".emf")) format = XWPFDocument.PICTURE_TYPE_EMF;
                                else if(imgFile[i].endsWith(".wmf")) format = XWPFDocument.PICTURE_TYPE_WMF;
                                else if(imgFile[i].endsWith(".pict")) format = XWPFDocument.PICTURE_TYPE_PICT;
                                else if(imgFile[i].endsWith(".jpeg") || imgFile[i].endsWith(".jpg")) format = XWPFDocument.PICTURE_TYPE_JPEG;
                                else if(imgFile[i].endsWith(".png")) format = XWPFDocument.PICTURE_TYPE_PNG;
                                else if(imgFile[i].endsWith(".dib")) format = XWPFDocument.PICTURE_TYPE_DIB;
                                else if(imgFile[i].endsWith(".gif")) format = XWPFDocument.PICTURE_TYPE_GIF;
                                else if(imgFile[i].endsWith(".tiff")) format = XWPFDocument.PICTURE_TYPE_TIFF;
                                else if(imgFile[i].endsWith(".eps")) format = XWPFDocument.PICTURE_TYPE_EPS;
                                else if(imgFile[i].endsWith(".bmp")) format = XWPFDocument.PICTURE_TYPE_BMP;
                                else if(imgFile[i].endsWith(".wpg")) format = XWPFDocument.PICTURE_TYPE_WPG;
                                else {
                                    System.err.println("Unsupported picture: " + imgFile +
                                            ". Expected emf|wmf|pict|jpeg|png|dib|gif|tiff|eps|bmp|wpg");
                                    continue;
                                }
                                run.addBreak();
                                run.addPicture(new FileInputStream(imgFile[i]), format, imgFile[i], Units.toEMU(200), Units.toEMU(200)); // 200x200 pixels
                                run.addBreak();
//                                run.addBreak(BreakType.PAGE);
                            }
                        }
                    }
                    run.setText(value, 0);
                }
            }
        }
        return value;
    }


}

前端

   const blob = new Blob([res])
          const fileName = '文章.docx'
          const link = document.createElement('a')
          link.download = fileName
          link.style.display = 'none'
          link.href = URL.createObjectURL(blob)
          document.body.appendChild(link)
          link.click()
          URL.revokeObjectURL(link.href)
          document.body.removeChild(link)

记得设置responseType: ‘blob’

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值