6
版本号:1.1.2-beta5 主要问题:
- 写同一个excel文件,若使用不同的writer分次写,会报出IO Exception;
- 通过同一个writer,向不同的sheet对象写数据,结果全写到第一个sheet中去了。
我的场景有点复杂:
- 写入的表单数据会分成好几种类别,不同的类别使用不同的样式,写到不同的表单;同一个样式的数据超过行数后也需要写到下一个表单。
- 流程: 1)实现WriteHandler,将所有种类表单样式传入handler。 2)在整个程序的上下文中,只通过上述handler创建一次ExcelWriter。根据业务场景,当写到不同种类表单时,切换handler中的样式模板; 3)当数据超过限制,以及切换不同种类表单时,new出新的sheet,使用步骤2的ExcelWriter写入; 4) 得到的excel文件只在同一个表单
部分代码:
/**
* 按照种类写入excel,一个种类可能会写入多个sheet表单
*
* @param filePath excel文件路径
* @param kindModels 表单种类
* @throws FileNotFoundException 异常信息
*/
private void writeExcel(String filePath, List<SheetKindModel> kindModels) throws FileNotFoundException {
List<List<ExcelFieldVo>> excelFieldVos = getDiffKindSheet(kindModels);
OutputStream outputStream = new FileOutputStream(filePath);
StringExcelHandler handler = new StringExcelHandler(excelFieldVos);
ExcelWriter writer = new ExcelWriter(null, outputStream, ExcelTypeEnum.XLSX, true, handler);
int kindIndex = 0;
int sheetNum = 0;
for (SheetKindModel sheetKindModel : kindModels) {
if (CollectionUtils.isNotEmpty(sheetKindModel.getData())) {
// 切换sheet种类
handler.switchSheetKind(kindIndex);
// 分batchNum次批量插入excel
int batchNum = batchWriteExcel(excelFieldVos, writer, kindIndex, sheetNum, sheetKindModel);
sheetNum += batchNum;
kindIndex++;
}
}
writer.finish();
}
private int batchWriteExcel(List<List<ExcelFieldVo>> excelFieldVos, ExcelWriter writer, int kindIndex, int sheetNum, SheetKindModel sheetKindModel) {
List<JSONObject> rowData = sheetKindModel.getData();
int size = rowData.size();
// excel单张表单最多1048576行,去掉零头,1048570
int batchNum = (int) Math.ceil((double) size / GalaxyConstant.MAX_EXCEL_NUM);
List<List<String>> header = Lists.newArrayListWithExpectedSize(excelFieldVos.size());
for (ExcelFieldVo excelFieldVo : excelFieldVos.get(kindIndex)) {
header.add(Collections.singletonList(excelFieldVo.getHeaderName()));
}
for (int i = 0; i < batchNum; i++) {
int startIndex = GalaxyConstant.MAX_EXCEL_NUM * i;
int endIndex = i == (batchNum - 1) ? size : GalaxyConstant.MAX_EXCEL_NUM * (i + 1);
List<JSONObject> batchRowData = rowData.subList(startIndex, endIndex);
Sheet oneSheet = new Sheet(sheetNum + i, 1);
oneSheet.setSheetName(sheetKindModel.getPrefix() + (i + 1));
oneSheet.setHead(header);
List<List<String>> data = Lists.newArrayListWithExpectedSize(batchRowData.size());
for (JSONObject jsonObject : batchRowData) {
List<String> oneRow = Lists.newArrayListWithExpectedSize(excelFieldVos.size());
for (ExcelFieldVo excelFieldVo : excelFieldVos.get(kindIndex)) {
oneRow.add(jsonObject.getString(excelFieldVo.getFieldAlias()));
}
data.add(oneRow);
}
writer.write0(data, oneSheet);
}
return batchNum;
}
结果: