为什么要使用easyexcel
EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。
他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。
java解析excel的框架有很多poi jxl,存在问题:非常的消耗内存,
easyexcel 我们遇到再大的excel都不会出现内存溢出的问题能够将一个原本3M excel文件,poi来操作将会占用内存100MB,使用easyexcel减低到几Mb,使用起来更加简单
easyEcel的版本:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.10</version>
</dependency>
先将数据查询出来,动态数据字段格式:
{
"code":"mock", //类型:String 必有字段 备注:无
"msg":"mock", //类型:String 必有字段 备注:无
"data": { //类型:Object 必有字段 备注:无
"paginator": { //类型:Object 必有字段 备注:无
"pageLength":"mock", //类型:String 必有字段 备注:无
"pageNo":"mock", //类型:String 必有字段 备注:无
"totalCount":"mock" //类型:String 必有字段 备注:无
},
"columnList": [ //类型:Array 必有字段 备注:动态字段列表
{ //类型:Object 必有字段 备注:无
"title":"客服", //类型:String 必有字段 备注:字段名称
"dataIndex":"110" //类型:String 必有字段 备注:字段值
}
],
"resultList": [ //类型:Array 必有字段 备注:无
{ //类型:Object 必有字段 备注:无
"aaa":"11", //类型:String 必有字段 备注:其它字段
"bbb":"22", //类型:String 必有字段 备注:其它字段
"Station*":"3", //类型:String 必有字段 备注:动态字段+值
"Station220":"1", //类型:String 必有字段 备注:动态字段+值
}
]
}
}
获取head全量的数据
/**
* 配置导出列表的动态配置
* 这里是全量,根据方法"动态表头的处理",进行动态匹配
*
* @return list
*/
private List<ColumnConfig> createTestListColumnConfig(List<Column> columns) {
List<ColumnConfig> columnConfigList = new ArrayList<>();
columnConfigList.add(new ColumnConfig(0, "其他字段1", "aa"));
columnConfigList.add(new ColumnConfig(1, "其他字段2", "bb"));
columnConfigList.add(new ColumnConfig(2, "其他字段3", "cc"));
columnConfigList.add(new ColumnConfig(3, "其他字段4", "dd"));
columnConfigList.add(new ColumnConfig(4, "其他字段5", "ee"));
columnConfigList.add(new ColumnConfig(5, "其他字段6", "ff"));
int a=5;
for(Column column:columns){
columnConfigList.add(new ColumnConfig(a+=1, column.getTitle()+"次数", "Station"+column.getDataIndex()));
}
return columnConfigList;
}
获取表头:
/**
* 获取标头
* @param columns
* @return
*/
private List<List<String>> head(List<Column> columns) {
List<List<String>> list = new ArrayList<>();
List<ColumnConfig> config = this.createTestListColumnConfig(columns);
List<ColumnConfig> sourtColumn = config.stream().sorted(Comparator.comparing(ColumnConfig::getRank)).collect(Collectors.toList());
logger.debug("报表导出:排序后表头heads:{}",JSON.toJSONString(sourtColumn));
sourtColumn.forEach(s->{
List<String> headColumn=new ArrayList<>();
//这里有个需求,需要将动态字段上方合并了
if(s.getRank()>=4&&s.getRank()<=(9+columns.size())){//从第4列开始然后加上动态的数目,形成单独的列
headColumn=new ArrayList<>();
headColumn.add("合并字段");//将第4列-第9列合并
headColumn.add(s.getDisplayName());
}else{
headColumn.add(s.getDisplayName());
}
list.add(headColumn);
});
logger.debug("报表导出:排序后表头list:{}",list);
return list;
}
处理数据:
/**
* 处理数据
* @param reportDataList
* @return
*/
public List getData(List<Map<String, String>> reportDataList,List<String> headList) {
logger.debug("报表导出:reportDataList:{}",reportDataList);
logger.debug("报表导出:headList:{}",headList);
ArrayList<List<Object>> result = Lists.newArrayList();
for (Map<String, String> recordData: reportDataList) {
ArrayList<Object> data = new ArrayList<>();
for (String fieldName : headList) {
try {
for(String key:recordData.keySet()){
if(key.equals(fieldName)){
data.add(recordData.get(key));
}
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
result.add(data);
}
return result;
}
设置格式样式:
private HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);//细实线
contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
//设计内容居中
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); //设置内容自动换行
contentWriteCellStyle.setWrapped(true);
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
HorizontalCellStyleStrategy horizontalCellStyleStrategy =
new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
return horizontalCellStyleStrategy;
}
导出数据:
HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizontalCellStyleStrategy();
//获取数据的动态列
List<Column> column = rsp.getColumn();
logger.debug("报表导出:column:{}",JSON.toJSONString(column));
List<List<String>> heads = head(column);
logger.debug("报表导出:heads:{}",heads);
//获取所有动态配置字段
List<ColumnConfig> config = this.createTestListColumnConfig(column);
List<String> headList = config.stream().map(ColumnConfig::getValueName).collect(Collectors.toList());
//需要导出的数据,数据格式在上面json中可以找到
List<Map<String, String>> reportDataList = rsp.getReportDataList();
String filename = "导出的名称"+ String.valueOf(System.currentTimeMillis());
String outFile = URLEncoder.encode(filename + ".xlsx", "UTF-8");
response.setHeader("Content-disposition", "attachment; filename=" + outFile);
response.setContentType("application/octet-stream");
response.setHeader("FileName", outFile);
response.setCharacterEncoding("utf-8");
EasyExcel.write(response.getOutputStream())
.sheet("导出的名称")
.registerWriteHandler(new SimpleColumnWidthStyleStrategy(17))//设计列格式大小
.registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 30, (short) 20))//设计行格式大小
.head(heads)
.registerWriteHandler(horizontalCellStyleStrategy)//自定义格式
.doWrite(this.getData(reportDataList,headList));