使用easypoi导出word模板

官方文档: http://easypoi.mydoc.io/

pom.xml

<dependency>
   <groupId>cn.afterturn</groupId>
   <artifactId>easypoi-spring-boot-starter</artifactId>
   <version>4.0.0</version>
</dependency>

工具类

import cn.afterturn.easypoi.word.WordExportUtil;
import org.apache.poi.xwpf.usermodel.*;
import org.springframework.util.Assert;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;

public class ExportWordUtils {

    /**
     * 导出word
     * <p>
     * 第一步生成替换后的word文件,只支持docx
     * </p>
     * <p>
     * 第二步下载生成的文件
     * </p>
     * <p>
     * 第三步删除生成的临时文件
     * </p>
     * 模版变量中变量格式:{{foo}}
     *
     * @param templatePath word模板地址
     * @param fileName     文件名
     * @param params       替换的参数
     * @param request      HttpServletRequest
     * @param response     HttpServletResponse
     */
    public static void exportWord(String templatePath, String fileName, Map<String, Object> params,
                                  HttpServletRequest request, HttpServletResponse response) {
        Assert.notNull(templatePath, "模板路径不能为空");
        Assert.notNull(fileName, "导出文件名不能为空");
        Assert.isTrue(fileName.endsWith(".docx"), "word导出请使用docx格式");
        try {
            String userAgent = request.getHeader("user-agent").toLowerCase();
            if (userAgent.contains("msie") || userAgent.contains("like gecko")) {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else {
                fileName = new String(fileName.getBytes("utf-8"), "ISO-8859-1");
            }
            XWPFDocument doc = WordExportUtil.exportWord07(templatePath, params);
            //文本换行
            for(XWPFTable table : doc.getTables()) {//表格
                for(XWPFTableRow row : table.getRows()) {//
                    for(XWPFTableCell cell : row.getTableCells()) {//单元格 : 直接cell.setText()只会把文字加在原有的后面,删除不了文字
                        addBreakInCell(cell);
                    }
                }
            }
            // 设置强制下载不打开
            response.setContentType("application/force-download");
            // 设置文件名
            response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
            OutputStream out = response.getOutputStream();
            doc.write(out);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // delAllFile(temDir);// 这一步看具体需求,要不要删
        }

    }

    public static boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                // 先删除文件夹里面的文件
                delAllFile(path + File.separator + tempList[i]);
                // 再删除空文件夹
                delFolder(path + File.separator + tempList[i]);
                flag = true;
            }
        }
        return flag;
    }

    public static void delFolder(String folderPath) {
        try {
            // 删除完里面所有内容
            delAllFile(folderPath);
            String filePath = folderPath;
            File myFilePath = new File(filePath);
            myFilePath.delete(); // 删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 设置换行
     *
     * @param value     需要换行的内容
     * @param paragraph 当前段落
     * @param run
     */
    private static void setWrap(Object value, XWPFParagraph paragraph, XWPFRun run) {
        if (((String) value).indexOf("\n") > 0) {
            //设置换行
            String[] text = value.toString().split("\n");
            run = paragraph.insertNewRun(0);
            for (int f = 0; f < text.length; f++) {
                if (f == 0) {
                    run.setText(text[f].trim());
                } else {
//                    run.addCarriageReturn();//硬回车
                    // 换行
                    run.addBreak();
                    run.setText(text[f].trim());
                }
            }
        } else {
            run.setText((String) value);
        }
    }

    /**
     * 文本换行
     * @param cell
     */
    private static  void addBreakInCell(XWPFTableCell cell) {
        if(cell.getText() != null && cell.getText().contains("\n")) {
            for (XWPFParagraph p : cell.getParagraphs()) {
                for (XWPFRun run : p.getRuns()) {//XWPFRun对象定义具有一组公共属性的文本区域
                    if(run.getText(0)!= null && run.getText(0).contains("\n")) {
                        String[] lines = run.getText(0).split("\n");
                        if(lines.length > 0) {
                            run.setText(lines[0], 0); // set first line into XWPFRun
                            for(int i=1;i<lines.length;i++){
                                // add break and insert new text
                                run.addBreak();//中断
//                                    run.addCarriageReturn();//回车符,但是不起作用
                                run.setText(lines[i]);
                            }
                        }
                    }
                }
            }
        }
    }

}

添加word模板

前端

html

<el-button type="primary" size="mini" :loading="exportLoading" @click="exportData()">导出</el-button>

js

    exportData() {
      this.exportLoading = true
      api.exportWordBook(this.query).then(res => {
        const currentdate = '党支部工作手册-' + this.orgName + '.docx'
        const blob = new Blob([res.data]) // 创建一个类文件对象:Blob对象表示一个不可变的、原始数据的类文件对象
        const url = window.URL.createObjectURL(blob) // URL.createObjectURL(object)表示生成一个File对象或Blob对象
        const dom = document.createElement('a') // 设置一个隐藏的a标签,href为输出流,设置download
        dom.style.display = 'none'
        dom.href = url
        dom.setAttribute('download', currentdate) // 指示浏览器下载url,而不是导航到它;因此将提示用户将其保存为本地文件
        document.body.appendChild(dom)
        dom.click()
      }).finally(() => {
        this.exportLoading = false
      })
    }

后端

    @GetResource(name = "导出world", path = "/branchWorkBook/exportWordBook")
    public ResponseData exportBranchWordBook(BranchWorkBookRequest branchWorkBook) {
        HttpServletResponse response = HttpServletUtil.getResponse();
        HttpServletRequest request = HttpServletUtil.getRequest();
        Map<String, Object> params = new HashMap<>();
        String templatePath = "template/branchWorkBookTemplate.docx"; //模板路径
        HrOrganizationExpand org = this.hrOrganizationExpandService.getHrOrganizationExpandByOrgId(branchWorkBook.getOrgId());
        params.put("orgName",org.getFullName());
        params.put("branchSecretaryEmploymentRecord1","学习工作经历相关内容。。。。");//生成文件名
        Long time = System.currentTimeMillis();
        // 生成的word格式
        String formatSuffix = ".docx";
        // 拼接后的文件名
        String fileName = time + formatSuffix;//文件名  带后缀
        //导出word
        ExportWordUtils.exportWord(templatePath, fileName, params, request, response);
        return new SuccessResponseData();
    }

 

posted @ 2022-09-21 10:44  Ning-  阅读(3172)  评论(0编辑  收藏  举报