SpringBoot集成easyExcel实现按模板导出

2022-07-28 08:44:41 浏览数 (1)

需求如题。首先我们选用alibaba开源的easyExcel 开源框架。

官方文档: EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel

引入依赖:

代码语言:javascript复制
<dependency>
       <groupId>com.alibaba</groupId>
       <artifactId>easyexcel</artifactId>
       <version>3.1.1</version>
</dependency>

然后引入一个exel的模板,放到rescouces/template路径下: excel的模板最好使用英文的名字(没专门搞中文名,因涉及编码,不确定是否是否有问题)

 excel模板中的大致内容如图:

由于涉及敏感信息,部分表头做了马赛克处理。大家重点关注第三行用大括号括起来的内容,这里就是要用代码进行填充的地方,大括号中的变量前面有一个固定的点(.) 代表是一个集合。

接下来我们就是要用一个集合来填充这个模板。

后端代码:

代码语言:javascript复制
@PostMapping("export")
@ApiOperation("重大项目导出")
public void export(@RequestBody MajorProjectPageReqVO reqVO, HttpServletResponse resp) throws IOException {
        // 设置日期格式化,用于生成文件名称
        String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分"));
        // 文件模板
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("template/majorProjectTemplate.xlsx");
        // 生成文件名称
        String fileName = dateStr   "重大项目信息.xlsx";

        // 查询数据:
        List<MajorProjectInfoDO> list = majorProjectInfoService.list(new LambdaQueryWrapper<MajorProjectInfoDO>()
                .like(!StringUtils.isEmpty(reqVO.getProjectName()), MajorProjectInfoDO::getProjectName, "%"   reqVO.getProjectName()   "%")
                .like(!StringUtils.isEmpty(reqVO.getMainInvestor()), MajorProjectInfoDO::getMainInvestor, "%"   reqVO.getMainInvestor()   "%")
                .like(!StringUtils.isEmpty(reqVO.getResponsibleUnit()), MajorProjectInfoDO::getResponsibleUnit, "%"   reqVO.getResponsibleUnit()   "%")
                .orderByDesc(MajorProjectInfoDO::getCreateTime)
        );

        List<MajorProjectPageResVO> resList = new ArrayList<>();
        if (list != null && list.size() >0) {
            for (int i=0; i< list.size(); i  ) {
                MajorProjectPageResVO res = ModelMapperUtils.map(list.get(i), MajorProjectPageResVO.class);
                res.setIndex(i 1);
                resList.add(res);
            }
        }

        resp.setCharacterEncoding("UTF-8");
        resp.setHeader("Content-Type", "application/vnd.ms-excel");
        resp.setHeader("Content-Disposition",
                "attachment;filename="   URLEncoder.encode(fileName, "UTF-8"));

        // 导出:
        EasyExcel.write(resp.getOutputStream())
                .withTemplate(inputStream)
                .sheet()
                .doFill(resList);
}

这样后端的代码就结束了,会返回给前端一个io流,并且在header中设置了导出的excel的文档名称。

再给出一个前端vue的参考代码,用于下载这个excel.

首先用到这如下组件:

然后在代码中开发导出方法

代码语言:javascript复制
 // 导出
    exportData() {
      this.$confirm(
        '请确认是否按照搜索条件,导出全部信息?',
        '提示',
        {
          cancelButtonText: '取消',
          confirmButtonText: '确定',
          type: 'warning', iconClass: 'c-ioc-icon-warning'
        }
      ).then(() => {
          this.exportMajorProject(
        baseURL   `/admin/majorProject/export`,
        this.form
      )
      });
    },
    // 下载流文件
    exportMajorProject(url, data = {}) {
      return new Promise((resolve, reject) => {
        const tokenInfo = getToken()
        this.uploading = true
        axios({
          url: url,
          data: data,
          method: 'post',
          headers: {
            token: tokenInfo,
            'Content-Type': 'application/json;charset=utf-8',
          },
          responseType: 'arraybuffer'
        })
          .then(res => {
            console.log('下载完成', res)
            this.uploading = false
            // resolve(res)
            // 以下fileName是取后台的文件名,如果没有'content-disposition',可以直接略过这一步,自己定:如fileName="xxx.xlsx"。
            const fileName = res.headers['content-disposition']; // res.headers['content-disposition'].match(/fushun(S*)xls/)[0];
            const filename2 = fileName.split("=")[1];

            const file = decodeURIComponent(filename2);

            fileDownload(res.data, file)
          })
          .catch(error => {
            this.$message.error('系统异常')
            reject(null, error)
          })
      })
    },

这样点击导出按钮后就可以实现excel的下载了。下载出来的数据格式如下:

0 人点赞