根据现有代码进行M种分类组合使用N个模板的方式生成Excel文档
Opened this issue · 0 comments
qq272936993 commented
ExcelHelper不能继承的情况下,当然可以有修改源码的方式,我使用了以下方式,不知道有没什么更好的办法
`
public class ExcelExpandHelper {
private static volatile ExcelExpandHelper mExcelExpandHelper;
//实现单模板,多sheet的方式
private ExcelExpandHelper() {
}
public static ExcelExpandHelper getInstance() {
if (null == mExcelExpandHelper) {
synchronized(ExcelExpandHelper.class) {
if (null == mExcelExpandHelper) {
mExcelExpandHelper = new ExcelExpandHelper();
}
}
}
return mExcelExpandHelper;
}
public void normalSheet2Excel(List<NormalSheetExpandWrapper> sheetWrappers, String templatePath, OutputStream os ) throws Excel4JException {
try {
SheetTemplate sheetTemplate = this.exportExcelByModuleHandler(templatePath, sheetWrappers);
Throwable var5 = null;
try {
sheetTemplate.write2Stream(os);
} catch (Throwable var15) {
var5 = var15;
throw var15;
} finally {
if (sheetTemplate != null) {
if (var5 != null) {
try {
sheetTemplate.close();
} catch (Throwable var14) {
var5.addSuppressed(var14);
}
} else {
sheetTemplate.close();
}
}
}
} catch (IOException | Excel4JException var17) {
throw new Excel4JException(var17);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
private SheetTemplate exportExcelByModuleHandler(String templatePath, List<NormalSheetExpandWrapper> sheets) throws Excel4JException, NoSuchFieldException {
//读取模板文件
SheetTemplate template = SheetTemplateHandler.sheetTemplateBuilder(templatePath);
//克隆模板
cloneSheet(template , sheets);
//这是用户配置的有多少sheet
Iterator var4 = sheets.iterator();
while(var4.hasNext()) {
NormalSheetExpandWrapper sheet = (NormalSheetExpandWrapper)var4.next();
//生成sheet
this.generateSheet(sheet.getSheetIndex() , sheet.getData(), sheet.getExtendMap(), sheet.getClazz(), sheet.isWriteHeader(), template);
}
return template;
}
private void generateSheet(int sheetIndex ,List<?> data, Map<String, String> extendMap, Class clazz, boolean isWriteHeader, SheetTemplate template) throws Excel4JException, NoSuchFieldException {
//加载模板
SheetTemplateHandler.loadTemplate(template, sheetIndex);
//将值设置到模板中
SheetTemplateHandler.extendData(template, extendMap);
//设置标题
List<ExcelHeader> headers = Utils.getHeaderList(clazz);
Iterator var8;
//如果需要重新构建header
if (isWriteHeader) {
SheetTemplateHandler.createNewRow(template);
var8 = headers.iterator();
while(var8.hasNext()) {
ExcelHeader header = (ExcelHeader)var8.next();
SheetTemplateHandler.createCell(template, header.getTitle(), (String)null);
}
}
var8 = data.iterator();
while(var8.hasNext()) {
Object object = var8.next();
SheetTemplateHandler.createNewRow(template);
SheetTemplateHandler.insertSerial(template, (String)null);
Iterator var10 = headers.iterator();
while(var10.hasNext()) {
ExcelHeader header = (ExcelHeader)var10.next();
SheetTemplateHandler.createCell(template, Utils.getProperty(object, header.getFiled(), header.getWriteConverter()), (String)null);
}
}
}
/***
* 使用反射的原理
* */
private void cloneSheet(SheetTemplate template , List<NormalSheetExpandWrapper> sheets) throws NoSuchFieldException {
Class cls = template.getClass();
Field field = cls.getDeclaredField("workbook");
try {
field.setAccessible(true);
Workbook workbook = (Workbook) field.get(template);
Iterator<Sheet> it = workbook.sheetIterator();
int len = 0;
Sheet defSheet = null;
while(it.hasNext()){
Sheet sheet = it.next();
if(len == 0){
defSheet = sheet;
}
len ++;
}
int sheetSize = sheets.size();
//有模板文件后,进行克隆
if(defSheet != null){
Set<Integer> usedIndexSet = new HashSet<>();
for(int i = 0; i < sheetSize ; i++){
NormalSheetExpandWrapper normalSheetExpandWrapper = sheets.get(i);
//这里需要判断是getSheet还是cloneSheet(第一次使用为get,否则为clone)
Integer cloneIndexSheet = normalSheetExpandWrapper.getCloneIndexSheet();
Sheet sheet = null;
if(usedIndexSet.contains(cloneIndexSheet)){
sheet = workbook.cloneSheet(cloneIndexSheet);
}else{
sheet = workbook.getSheetAt(cloneIndexSheet);
usedIndexSet.add(cloneIndexSheet);
}
workbook.setSheetOrder(sheet.getSheetName() , i);
String sheetName = normalSheetExpandWrapper.getSheetName();
workbook.setSheetName(i , sheetName);
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
`