目的
根据业务需求对数据进行导出excel操作,该excel包括4个模版(sheet),每一个模板代表一个实体对象。如图:
开始
本项目使用的是springboot + vue +elementUI 实现,由于需要使用导出excel功能,所以浅入了easyExcel模块。
1、导入easyExcel坐标依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
easyExcel官方文档:https://www.yuque.com/easyexcel/doc/quickstart
2、实体类编写
在这里使用了lombok插件,使用easyExcel只需要设置导出的excel表列名,使用@ExcelProperty(value="")注解。具体配置列名、数据转换,日期格式,自定义excel表格样式,请去官网查看。
3、controller编写
/**
* 导出档案
*/
@RequestMapping("/export")
public void export(@RequestParam Map<String, Object> params, HttpServletResponse response) throws IOException {
OutputStream outputStream = response.getOutputStream();
// 获取数据
PageUtils page = archService.getStatistics(params);
// 获取农合档案信息
List<ArchEntity> archEntityList = (List<ArchEntity>) page.getList();
// 遍历设置List
if (archEntityList.size() > 0) {
List<FamilyEntity> familyEntityList = new ArrayList<>();
List<CardEntity> cardEntityList = new ArrayList<>();
List<PayEntity> payEntityList = new ArrayList<>();
for (int i = 0; i < archEntityList.size(); i++) {
// 获取家庭档案
familyEntityList.add(i, archEntityList.get(i).getFamilyEntity());
// 获取慢性病卡档案
cardEntityList.add(i, archEntityList.get(i).getCardEntity());
// 获取慢性病报销信息
payEntityList.add(i, archEntityList.get(i).getPayEntity());
}
try {
// 设置response
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("统计信息", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
//新建ExcelWriter
ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
//获取archSheet对象
WriteSheet archSheet = EasyExcel.writerSheet(0, "农合信息档案").head(ArchEntity.class).build();
//获取参合人员信息,向archSheet写入数据
excelWriter.write(archEntityList, archSheet);
//获取archSheet对象
WriteSheet familySheet = EasyExcel.writerSheet(1, "参合家庭档案").head(FamilyEntity.class).build();
//获取家庭参合信息,向familySheet写入数据
excelWriter.write(familyEntityList, familySheet);
//获取cardSheet对象
WriteSheet cardSheet = EasyExcel.writerSheet(2, "慢性病卡信息").head(CardEntity.class).build();
//获取家庭参合信息,向cardSheett写入数据
excelWriter.write(cardEntityList, cardSheet);
//获取paySheet对象
WriteSheet paySheet = EasyExcel.writerSheet(3, "报销记录").head(PayEntity.class).build();
//获取家庭参合信息,向paySheet写入数据
excelWriter.write(payEntityList, paySheet);
//关闭流
excelWriter.finish();
outputStream.flush();
} catch (IOException e) {
log.error("导出异常{}", e.getMessage());
}
}
}
- 1、创建OutputStream对象
OutputStream outputStream = response.getOutputStream();
- 2、设置头、类型、编码格式
// 设置response
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("统计信息", "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
- 3、创建ExcelWriter对象
//新建ExcelWriter
ExcelWriter excelWriter = EasyExcel.write(outputStream).build();
- 4、创建WriteSheet对象,调用EasyExcel.writerSheet()方法写入参数
//获取archSheet对象
WriteSheet archSheet = EasyExcel.writerSheet(0, "农合信息档案").head(ArchEntity.class).build();
0为第一个模板(sheet),名称是农合信息档案。head()中传入的参数为实体类
- 5、调用excelWriter.write()向sheet模板写入参数
//获取参合人员信息,向archSheet写入数据
excelWriter.write(archEntityList, archSheet);
向excelWriter.write()方法中传入List数据与WriteSheet对象
- 6、关闭excelWriter.finish()
//关闭流
excelWriter.finish();
- 7 、关闭outputStream.flush();
outputStream.flush();
3、前端界面编写
// 导出档案
exportHandle () {
this.$nextTick(() => {
this.$http({
url: this.$http.adornUrl('/mxbbx/arch/export'),
method: 'get',
responseType: 'blob',
params: this.$http.adornParams({
'page': this.pageIndex,
'limit': this.pageSize,
'groupId': this.dataForm.groupId,
'apName': this.dataForm.apName,
'areaTime': this.dataForm.areaTime,
'drName': this.dataForm.drName
})
}).then(({data}) => {
// 创建Blob对象
let blob = new Blob([data], { type: 'application/vnd.ms-excel;charset=utf-8' })
// 获取路径
let url = window.URL.createObjectURL(blob)
// 创建a标签
const link = document.createElement('a')
// 设置a标签链接参数
link.href = url
// 重命名文件
link.download = '报销信息.xlsx'
link.click()
// 下载完成释放URL 对象
URL.revokeObjectURL(url)
// 移除a标签
document.body.removeChild(link)
})
})
},
注意事项
1、这里我使用的axios异步调用处理(和ajax没啥大区别)
2、请求参数中设置:responseType: 'blob',将返回响应类型设置为blob
3、在返回成功then()中,创建a标签,并为a标签设置超链接,并设置点击下载文件流。如果不使用创建a标签的方式,将不会显示下载弹窗!!!(大坑,后端成功了,前端一直没有出现下载文件的弹窗,可能是vue的原因,在html中无需设置)