package com.walker.di.excel;
|
|
import com.alibaba.excel.EasyExcelFactory;
|
import com.alibaba.excel.ExcelWriter;
|
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
|
import com.alibaba.excel.write.metadata.WriteSheet;
|
import com.walker.di.AbstractTemplateGenerator;
|
import com.walker.di.Constants;
|
import com.walker.di.TemplateException;
|
import com.walker.infrastructure.utils.FileCopyUtils;
|
import com.walker.infrastructure.utils.StringUtils;
|
|
import java.io.BufferedOutputStream;
|
import java.io.File;
|
import java.io.FileOutputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.io.OutputStream;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Map;
|
|
/**
|
* EasyExcel 实现的(导入)模板生成器对象。
|
* @author 时克英
|
* @date 2023-02-10
|
*/
|
public abstract class ExcelTemplateGenerator extends AbstractTemplateGenerator<File> {
|
|
@Override
|
protected File writeContent(List<Map<String, String>> data, Object option) throws TemplateException {
|
logger.debug(data.toString());
|
logger.debug(option.toString());
|
String templatePath = this.acquireWriteFilePath(option);
|
if(StringUtils.isEmpty(templatePath)){
|
throw new TemplateException("无法获取模板写入路径: acquireWriteFilePath() = null!", null);
|
}
|
File templateFile = new File(templatePath);
|
logger.info("生成的模板文件:" + templateFile.getAbsolutePath());
|
|
InputStream templateFileStream = this.getClass().getClassLoader().getResourceAsStream(Constants.IMPORT_ERROR_FILE_TEMPLATE);
|
OutputStream outputStream = null;
|
try {
|
outputStream = new BufferedOutputStream(new FileOutputStream(templateFile));
|
// 根据已有 Excel 模板文件,生成一个新导入模板,这样单元格都是已设置为文本。
|
FileCopyUtils.copy(templateFileStream, outputStream);
|
// 这里拷贝完模板后,outputStream 已自动关闭,所以需要重新创建新输出流供写入
|
outputStream = new BufferedOutputStream(new FileOutputStream(templateFile));
|
ExcelWriterBuilder writer = EasyExcelFactory.write(outputStream);
|
|
WriteSheet writeSheet = new WriteSheet();
|
writeSheet.setSheetName(Constants.EXCEL_SHEET_NAME);
|
|
// 仅写入标题头,没有其他内容,data中只有一行数据
|
List<List<String>> header = this.getHeader(data);
|
writer.head(header);
|
|
ExcelWriter excelWriter = writer.build();
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// List<List<String>> content = new ArrayList<>();
|
// List<String> testRow = new ArrayList<>();
|
// // 2023-02-07 data集合是每个字段信息,map中只有一个字段:字段id -> 描述
|
// for(int i=0; i< data.size(); i++){
|
// testRow.add(StringUtils.EMPTY_STRING);
|
// logger.debug("写入空列一次:");
|
// }
|
// logger.debug("data.get(0) = {}", data.get(0));
|
// content.add(testRow);
|
//// content.add(StringUtils.asList(new String[]{"123","shikeying","1233889746596"}));
|
// 写入测试数据,否则文档为空。
|
excelWriter.write(this.getEmptyRow(data), writeSheet);
|
|
// 关闭文件
|
excelWriter.finish();
|
excelWriter.close();
|
|
return templateFile;
|
|
} catch (Exception ex){
|
throw new TemplateException("写入模板内容错误:" + ex.getMessage() + ", templatePath=" + templatePath, ex);
|
} finally {
|
if(outputStream != null){
|
try {
|
outputStream.close();
|
logger.debug("outputStream 已关闭");
|
} catch (IOException e) {}
|
}
|
}
|
|
}
|
|
/**
|
* 写入一行空数据,否则不能触发Excel写入动作,会导致生成的Excel文件是空的。
|
* @param headers
|
* @date 2023-02-08
|
* @return
|
*/
|
private List<List<String>> getEmptyRow(List<Map<String, String>> headers){
|
List<List<String>> content = new ArrayList<>();
|
List<String> testRow = new ArrayList<>();
|
// 2023-02-07 data集合是每个字段信息,map中只有一个字段:字段id -> 描述
|
for(int i=0; i< headers.size(); i++){
|
testRow.add(StringUtils.EMPTY_STRING);
|
// logger.debug("写入空列一次:");
|
}
|
// logger.debug("data.get(0) = {}", headers.get(0));
|
content.add(testRow);
|
return content;
|
}
|
|
/**
|
* 目前仅支持list中第一条数据写入表头,其他行暂不支持。
|
* <pre>
|
* 1)List 中是多个字段集合
|
* 2)Map 中只有一个字段信息,如: id --> 人员编号
|
* </pre>
|
* @param headers 提供的原始列名称集合
|
* @return 返回 EasyExcel 需要用的列集合格式
|
*/
|
private List<List<String>> getHeader(List<Map<String, String>> headers){
|
// Map<String, String> map = headers.get(0);
|
List<List<String>> headerList = new ArrayList<>();
|
// for(Map.Entry<String, String> entry : map.entrySet()){
|
// headers.add(StringUtils.asList(new String[]{entry.getValue(), entry.getKey()}));
|
// }
|
for(Map<String, String> oneFieldInfo : headers){
|
// 每个map中只有一个字段
|
for(Map.Entry<String, String> entry : oneFieldInfo.entrySet()){
|
headerList.add(StringUtils.asList(new String[]{entry.getValue(), entry.getKey()}));
|
}
|
}
|
return headerList;
|
}
|
|
/**
|
* 获取要写入模板文件的具体路径,如: d:/demo/template/123.xlsx
|
* @param option
|
* @return
|
*/
|
protected abstract String acquireWriteFilePath(Object option);
|
}
|