最近看了阿里的开源项目EasyExcel,发现它是个很强大的工具,但是官方介绍中大部分都是使用对象,变量增加注解的方式,下面主要是在代码中实现相关样式的调整
本文介绍一下SpringBoot中,简单通过List生成excel并下载的方法,大家可以直接CV大法。还可以实现通过自己写样式策略来自由调整行高、自由合并。
一、将List直接导出为Excel下载
1.controller内接口写法:
@PostMapping("export")
public void export(@RequestBody Map<String,Object> param, HttpServletResponse response){
String[] head = {"用户账户名称","版本","购买时间","购买时长(天)","支付金额"};
List<Map<String,Object>> dataList = userPayDetailService.selectExportList(param);
EasyExcelUtils.write(head,dataList,"用户支付明细","用户支付明细",response);
}
此处head变量为excel的一行表头。dataList 为整理好的表格内容
2.EasyExcelUtils.write 方法如下:
public static void write(String[] head, List<Map<String,Object>> dataList, String sheetName, String fileName, HttpServletResponse response){
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
try {
fileName = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
EasyExcel.write(response.getOutputStream()).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).head(getHeadList(head)).autoCloseStream(Boolean.FALSE)
.sheet(sheetName).doWrite(getDataList(dataList));
} catch (Exception e) {
// 重置response
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
MsgResponse msgResponse = new MsgResponse();
msgResponse.setEnum(CodeEnum.EXPORT_ERROR);
try {
response.getWriter().println(JSON.toJSONString(msgResponse));
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
这里核心就是EasyExcel.write方法,此处我使用了easyExcel中默认的 LongestMatchColumnWidthStyleStrategy()方法,即自动设置列宽。也可以不加。
若不需要表头,就不用加.head()
以上就可以快速将查询结果写入excel并下载了。
二、设置合并、行高等样式
要知道,EasyExcel中的写,不仅可以使用EasyExcel.write方法,直接创建一个ExcelWriter对象也一样,代码如下:
OutputStream out = response.getOutputStream();
ExcelWriter writer = EasyExcelFactory.write(out)
.registerWriteHandler(new MyMergeStrategy(mergeMap))
.registerWriteHandler(new MySimpleRowHeightStyleStrategy((short)20, (short)73))
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.build();
WriteSheet writeSheet = EasyExcel.writerSheet(1, "sheet1").needHead(false).build();
writer.write(retBody, writeSheet);
writer.finish();
out.close();
这里我把Excel文件写入了输出流中,浏览器可以直接下载文件。
其中MyMergeStrategy、MySimpleRowHeightStyleStrategy、LongestMatchColumnWidthStyleStrategy为EasyExcel原本默认的写入策略,这些我们自己都可以重写。
这里我的My开头的是根据自己的需要重写的。
例如MyMergeStrategy,可以合并很多个单元格,将要合并的单元格变成一个Map。官方的合并策略为:OnceAbsoluteMergeStrategy(),只能传输一组合并信息,显然是不够的,需要改造成多组合并单元格的信息。
MyMergeStrategy代码如下:
public class MyMergeStrategy extends AbstractSheetWriteHandler {
private List<Map<String, Integer>> rowColumnIndex;
public MyMergeStrategy(List<Map<String, Integer>> index) {
if (index == null || index.size() == 0){
throw new IllegalArgumentException("All parameters must be greater than 0");
}
this.rowColumnIndex = index;
}
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
//这里循环将每组合并信息插入
for (Map<String, Integer> map : rowColumnIndex){
if (map.get("firstRowIndex") < 0 || map.get("lastRowIndex") < 0 || map.get("firstColumnIndex") < 0 || map.get("lastColumnIndex") < 0){
throw new IllegalArgumentException("All parameters must be greater than 0");
}
CellRangeAddress cellRangeAddress =
new CellRangeAddress(map.get("firstRowIndex"), map.get("lastRowIndex"), map.get("firstColumnIndex"), map.get("lastColumnIndex"));
writeSheetHolder.getSheet().addMergedRegionUnsafe(cellRangeAddress);
}
}
}