直接使用word模板生成word文件

  1. 导入相关jar

由于升级过版本导致其他模板不能正常生成,所以jar包保持在这个版本

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.13</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.15</version>
        </dependency>
  1. 工具类

package com.xinke.sunshine_ebid.common.utils;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.xwpf.usermodel.*;

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

public class WordUtil {

    public void addBreakInCell(XWPFTableCell cell) {

        if (cell.getText() != null && cell.getText().contains("\n")) {
            for (XWPFParagraph paragraph : cell.getParagraphs()) {
                paragraph.setAlignment(ParagraphAlignment.LEFT);
                for (XWPFRun run : paragraph.getRuns()) {
                    if (run.getText(0) != null && run.getText(0).contains("\n")) {
                        String[] lines = run.getText(0).split("\n");
                        if (lines.length > 0) {
                            // set first line into XWPFRun
                            run.setText(lines[0], 0);
                            for (int i = 1; i < lines.length; i++) {
                                // add break and insert new text
                                run.addBreak();
                                run.setText(lines[i]);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 替换段落里面的变量
     *
     * @param doc    要替换的文档
     * @param params 参数
     * @throws FileNotFoundException
     * @throws InvalidFormatException
     */
    public void replaceInPara(CustomXWPFDocument doc, Map<String, Object> params) throws InvalidFormatException, FileNotFoundException {
        Iterator<XWPFParagraph> iterator = doc.getParagraphsIterator();
        XWPFParagraph para;

        while (iterator.hasNext()) {
            para = iterator.next();
            this.replaceInPara(para, params,doc);
        }
    }

    /**
     * 替换段落里面的变量
     *
     * @param para   要替换的段落
     * @param params 参数 
     * @throws FileNotFoundException
     * @throws InvalidFormatException
     */
    public void replaceInPara(XWPFParagraph para, Map<String, Object> params, CustomXWPFDocument doc) throws InvalidFormatException, FileNotFoundException {
        List<XWPFRun> runs;
        Matcher matcher;
        if (this.matcher(para.getParagraphText()).find()) {
            runs = para.getRuns();

            int start = -1;
            int end = -1;
            String str = "";
            String text= "";
            for (int i = 0; i < runs.size(); i++) {
                text += runs.get(i).toString();
            }
            for (int i = 0; i < runs.size(); i++) {
                XWPFRun run = runs.get(i);
                System.out.println("------>>>>>>>>>" + text);
                if (text.contains("$")) {
                    start = text.indexOf("$");
                }
                if ((start != -1)) {
                    str += text.substring(text.indexOf("$"), text.length()).trim();
                    String paraList=runs.toString();
                    System.out.println("未删除前"+paraList);
                    Object[] runArr = runs.toArray();
                    int size=runs.size();
                    int $Index=0;
                    for (int j = 0; j < runArr.length; j++) {
                        if (runArr[j].toString().contains("$")) {
                            $Index=j;
                            break;
                        }
                    }
                    int startIn=$Index;
                    while (startIn<runs.size()) {
                        para.removeRun(startIn);
                        System.out.println("删除中"+para.getRuns());
                    }
                    System.out.println("删除后"+para.getRuns());
                }
                if ('}' == text.charAt(text.length() - 1)) {
                    if (start != -1) {
                        end = text.length() - 1;
                        break;
                    }
                }
            }
            System.out.println("start--->"+start);
            System.out.println("end--->"+end);
            System.out.println("str---->>>" + str);

            for (String key : params.keySet()) {
                if (str.equals(key)) {
                    if(str.indexOf("@")==-1){
                        String value= params.get(key).toString();
                        para.createRun().setText(value);
                        break;
                    }else{
                        String value= params.get(key).toString();
                        int length = para.getRuns().size();
                        if (length > 0) {
                            for (int i = (length - 1); i >= 0; i--) {
                                para.removeRun(i);
                            }
                        }
                        String blipId = doc.addPictureData(new FileInputStream(new File(value)), CustomXWPFDocument.PICTURE_TYPE_PNG);
                        doc.createPicture(blipId,doc.getNextPicNameNumber(CustomXWPFDocument.PICTURE_TYPE_PNG), 550, 250,para);
                        break;
                    }
                }
            }


        }
    }

    /**
     * 替换表格里面的变量 
     *
     * @param doc    要替换的文档 
     * @param params 参数 
     * @throws FileNotFoundException
     * @throws InvalidFormatException
     */
    public void replaceInTable(CustomXWPFDocument doc, Map<String, Object> params) throws InvalidFormatException, FileNotFoundException {
        Iterator<XWPFTable> iterator = doc.getTablesIterator();
        XWPFTable table;
        List<XWPFTableRow> rows;
        List<XWPFTableCell> cells;
        List<XWPFParagraph> paras;
        while (iterator.hasNext()) {
            table = iterator.next();
            rows = table.getRows();
            for (XWPFTableRow row : rows) {
                cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    paras = cell.getParagraphs();
                    for (XWPFParagraph para : paras) {
                        this.replaceInPara(para, params,doc);
                    }
                }
            }
        }
    }

    /**
     * 正则匹配字符串 
     *
     * @param str
     * @return
     */
    private Matcher matcher(String str) {
        Pattern pattern = Pattern.compile("\\$\\{(.+?)\\}", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        return matcher;
    }

    /**
     * 关闭输入流 
     *
     * @param is
     */
    public void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭输出流 
     *
     * @param os
     */
    public void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public boolean checkText(String text) {
        boolean check = false;
        if (text.indexOf("$") != -1) {
            check = true;
        }
        return check;

    }


    public String changeValue(String value, Map<String, Object> textMap) {
        Set<Map.Entry<String, Object>> textSets = textMap.entrySet();
        for (Map.Entry<String, Object> textSet : textSets) {
            // 匹配模板与替换值 格式${key}
            String key = "${" + textSet.getKey() + "}";
            if (value.indexOf(key) != -1) {
                value = textSet.getValue().toString();
            }
        }
        // 模板未匹配到区域替换为空
        if (checkText(value)) {
            value = "";
        }
        return value;
    }
}
  1. 代码应用

控制层

    @GetMapping("/test")
    public void recordSheetWord(HttpServletResponse response) throws Exception{
        testService.test(response);
    }   

业务层,需要换行的话追加/n

package com.xinke.sunshine_ebid.service;

import com.xinke.sunshine_ebid.common.utils.CustomXWPFDocument;
import com.xinke.sunshine_ebid.common.utils.WordUtil;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;

@Service
public class TestService {

    public void test(HttpServletResponse response) throws Exception{
        Map<String, Object> params = new HashMap<>();
        params.put("${test1}","参数111");
        params.put("${test2}","参数222");

        // 导出word的设置
        InputStream is;
        CustomXWPFDocument doc;
        // spring项目使用此方法获取创建文件   
        is = Files.newInputStream(new File("fileRecord/template/word/test.docx").toPath());
        // springboot项目使用次方法
//        is = FileUtil.class.getClassLoader().getResourceAsStream(ConfigConstant.JD_RECTIFICATION_RECORD);
        doc = new CustomXWPFDocument(is);

        WordUtil xwpfTUtil = new WordUtil();
        xwpfTUtil.replaceInPara(doc, params);
        xwpfTUtil.replaceInTable(doc, params);
        for (XWPFTable table : doc.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    //单元格 : 直接cell.setText()只会把文字加在原有的后面,删除不了文字
                    xwpfTUtil.addBreakInCell(cell);
                }
            }
        }
        //此处不指定下载目录,默认到用户本地的下载文件下
        OutputStream os = response.getOutputStream();
        response.setContentType("application/vnd.ms-excel");
        // 文件名
        String fileName = "文件名";
        response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        response.setContentType("application/x-zip-compressed");
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") +
                ".docx");
        doc.write(os);
        xwpfTUtil.close(os);
        xwpfTUtil.close(is);
        os.flush();
        os.close();
    }
}

模板位置

  1. 输出结果

链接调用

localhost:本地端口/Test/test

有问题可咨询

猜你喜欢

转载自blog.csdn.net/GuaGea/article/details/129306468