需求
自定义导出模板表头入参map集合、出参数据为:List Map 渲染到excel当中
整体代码如下
//列名
List<ExcelExportEntity> headList = new ArrayList<>();
// 自定义样式
ExportParams params = new ExportParams();
params.setType(ExcelType.XSSF);
// 表头map集合
List<Map<String, Object>> listmap = userDao.findListMap();
// 遍历表头
for (Map<String, Object> objectMap : listmap) {
String name =(String) objectMap.get("name");
Object key = objectMap.get("index");
ExcelExportEntity exportEntity = new ExcelExportEntity(name,key);
headList.add(exportEntity);
}
// 工作薄
Workbook workbook = BigDataExcelUtil.exportBigExcel(params, headList, poolAssetDetailExcelExportServer, dto);
ServletOutputStream outputStream = response.getOutputStream();
//导出
MyWebUtils.setDownloadResponse(absAssetPool.getAssetPoolName()+"资产池详细.xlsx", response);
workbook.write(outputStream);//将数据输出
//关闭流
workbook.close();
outputStream.close();
分析代码过程
自定义表头
来装excel每一列表头对象
List<ExcelExportEntity> headList = new ArrayList<>();
数据库查询过来的表头对象
List<Map<String, Object>> listmap = userDao.findListMap();
渲染每一个表头列的中文名与对应的code(方便再导出数据的时候做字段映射)
for (Map<String, Object> objectMap : listmap) {
String name =(String) objectMap.get("name");
Object key = objectMap.get("index");
ExcelExportEntity exportEntity = new ExcelExportEntity(name,key);
// 放入列明
headList.add(exportEntity);
}
ExcelExportUtil
/**
* 大数据量导出
*
* @param entity
* @param excelParams
* @param server 查询数据的接口
* @param queryParams 查询数据的参数
* @return
*/
public static Workbook exportBigExcel(ExportParams entity, List<ExcelExportEntity> excelParams,
IExcelExportServer server, Object queryParams) {
ExcelBatchExportService batchServer = new ExcelBatchExportService();
batchServer.init(entity, excelParams);
return batchServer.exportBigExcel(server, queryParams);
}
public Workbook exportBigExcel(IExcelExportServer server, Object queryParams) {
int page = 1;
List<Object> list = server
.selectListForExcelExport(queryParams, page++);
while (list != null && list.size() > 0) {
write(list);
list = server.selectListForExcelExport(queryParams, page++);
}
return close();
}
以上开源源码很明显不满足出参为ListMap格式数据。我们需要重写cn.afterturn.easypoi.excel.export.ExcelBatchExportService#exportBigExcel 。一旦不支持我们也需要重写:cn.afterturn.easypoi.excel.ExcelExportUtil#exportBigExcel(cn.afterturn.easypoi.excel.entity.ExportParams, java.util.List<cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity>, cn.afterturn.easypoi.handler.inter.IExcelExportServer, java.lang.Object)
重写代码如下
ExcelExportUtil------>BigDataExcelUtil
/**
* 功能描述:
*
* @author Songxianyang
* @date 2023-06-02 15:01
*/
public final class BigDataExcelUtil {
/**
* 大数据量导出
*
* @param entity
* @param excelParams
* @param server 查询数据的接口
* @param queryParams 查询数据的参数
* @return
*/
public static Workbook exportBigExcel(ExportParams entity, List<ExcelExportEntity> excelParams,
IExcelExportServer server, Object queryParams) {
AssetExcelBatchExportService batchServer = new AssetExcelBatchExportService();
batchServer.init(entity, excelParams);
return batchServer.exportBigExcel(server, queryParams);
}
}
ExcelBatchExportService ------> UserExcelBatchExportService
/**
* 功能描述: 资产大数据导出服务
* 提供批次插入服务
*
* @author Songxianyang
* @date 2023-06-02 15:04
*/
public class UserExcelBatchExportService extends ExcelBatchExportService {
public Workbook exportBigExcel(IExcelExportServer server, Object queryParams) {
int page = 1;
List<Object> list = server
.selectListForExcelExport(queryParams, page++);
while (list != null && list.size() > 0) {
//获取元素第一条数据
write((Collection) list.get(0));
list = server.selectListForExcelExport(queryParams, page++);
}
return close();
}
}
查询出来的数据如何渲染到excel当中(关键代码)
思想就是:分批处理 一批一批的写入。如果为null 及跳出循环
/**
* 功能描述:
*
* @author Songxianyang
* @date 2023-06-02 10:17
*/
@Component
public class UserDetailExcelExportServer implements IExcelExportServer {
@Autowired
private UserDetailService userDetailService;
@Override
public List<Object> selectListForExcelExport(Object queryParams, int page) {
// 外界查询数据库入参
UserDetailDto params = (UserDetailDto) queryParams;
Page pageTemp = new Page(page, 10000);
List<Map> rows = userDetailService.selectList();
// 这个地方 注意一下欧 (可以这么写)如果没查到 就不在往excel写入
if (CommUtil.isEmpty(rows)) {
return null;
}
// 他会把查询出来的数据放在 一个子集里面做返回。举个例子:
// List= [1,2,3,4] Collections.singletonList 转换成 List=List(0): [1,2,3,4] 。变成第一个元素的子集。
return Collections.singletonList(rows);
}
}
这个地方 注意一下欧 (可以这么写)如果没查到 就不在往excel写入 看一下官方源码怎么写的
while (list != null && list.size() > 0) {
//获取元素第一条数据
write((Collection) list.get(0));
list = server.selectListForExcelExport(queryParams, page++);
}