需求如题。首先我们选用alibaba开源的easyExcel 开源框架。
官方文档: EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel
引入依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.1</version>
</dependency>
然后引入一个exel的模板,放到rescouces/template路径下: excel的模板最好使用英文的名字(没专门搞中文名,因涉及编码,不确定是否是否有问题)
excel模板中的大致内容如图:
由于涉及敏感信息,部分表头做了马赛克处理。大家重点关注第三行用大括号括起来的内容,这里就是要用代码进行填充的地方,大括号中的变量前面有一个固定的点(.) 代表是一个集合。
接下来我们就是要用一个集合来填充这个模板。
后端代码:
@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.
首先用到这如下组件:
然后在代码中开发导出方法
// 导出
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的下载了。下载出来的数据格式如下: