package com.qianwen.core.excel.extend.handler;
|
|
import com.alibaba.excel.EasyExcel;
|
import com.alibaba.excel.ExcelWriter;
|
import com.alibaba.excel.converters.Converter;
|
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
|
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
|
import com.alibaba.excel.write.handler.WriteHandler;
|
import com.alibaba.excel.write.metadata.WriteSheet;
|
import java.io.File;
|
import java.io.InputStream;
|
import java.lang.reflect.Modifier;
|
import java.net.URLEncoder;
|
import java.util.Arrays;
|
import java.util.List;
|
import java.util.Objects;
|
import javax.servlet.http.HttpServletResponse;
|
import com.qianwen.core.excel.extend.annotation.ResponseExcel;
|
import com.qianwen.core.excel.extend.annotation.Sheet;
|
import com.qianwen.core.excel.extend.aop.DynamicNameAspect;
|
import com.qianwen.core.excel.extend.config.ExcelConfigProperties;
|
import com.qianwen.core.excel.extend.converters.LocalDateStringConverter;
|
import com.qianwen.core.excel.extend.converters.LocalDateTimeStringConverter;
|
import com.qianwen.core.excel.extend.enhance.WriterBuilderEnhancer;
|
import com.qianwen.core.excel.extend.head.HeadGenerator;
|
import com.qianwen.core.excel.extend.head.HeadMeta;
|
import com.qianwen.core.excel.extend.head.I18nHeaderCellWriteHandler;
|
import com.qianwen.core.excel.extend.kit.ExcelException;
|
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeansException;
|
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.http.MediaTypeFactory;
|
import org.springframework.util.Assert;
|
import org.springframework.util.StringUtils;
|
import org.springframework.web.context.request.RequestAttributes;
|
import org.springframework.web.context.request.RequestContextHolder;
|
import org.springframework.util.MimeType;
|
|
|
public abstract class AbstractSheetWriteHandler implements SheetWriteHandler, ApplicationContextAware {
|
private final ExcelConfigProperties configProperties;
|
private final ObjectProvider<List<Converter<?>>> converterProvider;
|
private final WriterBuilderEnhancer excelWriterBuilderEnhance;
|
private ApplicationContext applicationContext;
|
@Autowired(required = false)
|
private I18nHeaderCellWriteHandler i18nHeaderCellWriteHandler;
|
|
public AbstractSheetWriteHandler(final ExcelConfigProperties configProperties, final ObjectProvider<List<Converter<?>>> converterProvider, final WriterBuilderEnhancer excelWriterBuilderEnhance) {
|
this.configProperties = configProperties;
|
this.converterProvider = converterProvider;
|
this.excelWriterBuilderEnhance = excelWriterBuilderEnhance;
|
}
|
|
public I18nHeaderCellWriteHandler getI18nHeaderCellWriteHandler() {
|
return this.i18nHeaderCellWriteHandler;
|
}
|
|
public void setI18nHeaderCellWriteHandler(final I18nHeaderCellWriteHandler i18nHeaderCellWriteHandler) {
|
this.i18nHeaderCellWriteHandler = i18nHeaderCellWriteHandler;
|
}
|
|
@Override // org.springblade.core.excel.extend.handler.SheetWriteHandler
|
public void check(ResponseExcel responseExcel) {
|
if (responseExcel.sheets().length == 0) {
|
throw new ExcelException("@ResponseExcel sheet 配置不合法");
|
}
|
}
|
|
@Override // org.springblade.core.excel.extend.handler.SheetWriteHandler
|
public void export(Object o, HttpServletResponse response, ResponseExcel responseExcel) {
|
try {
|
check(responseExcel);
|
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
|
String name = (String) ((RequestAttributes) Objects.requireNonNull(requestAttributes)).getAttribute(DynamicNameAspect.EXCEL_NAME_KEY, 0);
|
|
String fileName = String.format("%s%s", URLEncoder.encode(name, "UTF-8"), responseExcel.suffix().getValue());
|
|
String contentType = MediaTypeFactory.getMediaType(fileName).map(MimeType::toString).orElse("application/vnd.ms-excel");
|
|
response.setContentType(contentType);
|
response.setCharacterEncoding("utf-8");
|
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
|
write(o, response, responseExcel);
|
}catch(Exception e) {
|
throw new RuntimeException(e);
|
}
|
}
|
|
public ExcelWriter getExcelWriter(HttpServletResponse response, ResponseExcel responseExcel) {
|
try {
|
Class<? extends Converter>[] converter;
|
Class<? extends WriteHandler>[] writeHandler;
|
ExcelWriterBuilder writerBuilder = EasyExcel.write(response.getOutputStream()).registerConverter(LocalDateStringConverter.INSTANCE).registerConverter(LocalDateTimeStringConverter.INSTANCE).autoCloseStream(true).excelType(responseExcel.suffix()).inMemory(Boolean.valueOf(responseExcel.inMemory()));
|
if (StringUtils.hasText(responseExcel.password())) {
|
writerBuilder.password(responseExcel.password());
|
}
|
if (responseExcel.include().length != 0) {
|
writerBuilder.includeColumnFiledNames(Arrays.asList(responseExcel.include()));
|
}
|
if (responseExcel.exclude().length != 0) {
|
writerBuilder.excludeColumnFiledNames(Arrays.asList(responseExcel.exclude()));
|
}
|
if (responseExcel.writeHandler().length != 0) {
|
for (Class<? extends WriteHandler> clazz : responseExcel.writeHandler()) {
|
writerBuilder.registerWriteHandler((WriteHandler) BeanUtils.instantiateClass(clazz));
|
}
|
}
|
if (responseExcel.i18nHeader() && this.i18nHeaderCellWriteHandler != null) {
|
writerBuilder.registerWriteHandler(this.i18nHeaderCellWriteHandler);
|
}
|
registerCustomConverter(writerBuilder);
|
if (responseExcel.converter().length != 0) {
|
for (Class<? extends Converter> clazz2 : responseExcel.converter()) {
|
writerBuilder.registerConverter((Converter) BeanUtils.instantiateClass(clazz2));
|
}
|
}
|
String templatePath = this.configProperties.getTemplatePath();
|
if (StringUtils.hasText(responseExcel.template())) {
|
ClassPathResource classPathResource = new ClassPathResource(templatePath + File.separator + responseExcel.template());
|
InputStream inputStream = classPathResource.getInputStream();
|
writerBuilder.withTemplate(inputStream);
|
}
|
return this.excelWriterBuilderEnhance.enhanceExcel(writerBuilder, response, responseExcel, templatePath).build();
|
}catch(Exception e) {
|
throw new RuntimeException(e);
|
}
|
}
|
|
public void registerCustomConverter(ExcelWriterBuilder builder) {
|
|
this.converterProvider.ifAvailable(converters -> converters.forEach(builder::registerConverter));
|
}
|
|
public WriteSheet sheet(Sheet sheet, Class<?> dataClass, String template, Class<? extends HeadGenerator> bookHeadEnhancerClass) {
|
Integer sheetNo = sheet.sheetNo() >= 0 ? Integer.valueOf(sheet.sheetNo()) : null;
|
String sheetName = sheet.sheetName();
|
ExcelWriterSheetBuilder writerSheetBuilder = StringUtils.hasText(template) ? EasyExcel.writerSheet(sheetNo) : EasyExcel.writerSheet(sheetNo, sheetName);
|
Class<? extends HeadGenerator> headGenerateClass = null;
|
if (isNotInterface(sheet.headGenerateClass())) {
|
headGenerateClass = sheet.headGenerateClass();
|
} else if (isNotInterface(bookHeadEnhancerClass)) {
|
headGenerateClass = bookHeadEnhancerClass;
|
}
|
if (headGenerateClass != null) {
|
fillCustomHeadInfo(dataClass, bookHeadEnhancerClass, writerSheetBuilder);
|
} else if (dataClass != null) {
|
writerSheetBuilder.head(dataClass);
|
if (sheet.excludes().length > 0) {
|
writerSheetBuilder.excludeColumnFiledNames(Arrays.asList(sheet.excludes()));
|
}
|
if (sheet.includes().length > 0) {
|
writerSheetBuilder.includeColumnFiledNames(Arrays.asList(sheet.includes()));
|
}
|
}
|
return this.excelWriterBuilderEnhance.enhanceSheet(writerSheetBuilder, sheetNo, sheetName, dataClass, template, headGenerateClass).build();
|
}
|
|
private void fillCustomHeadInfo(Class<?> dataClass, Class<? extends HeadGenerator> headEnhancerClass, ExcelWriterSheetBuilder writerSheetBuilder) {
|
HeadGenerator headGenerator = (HeadGenerator) this.applicationContext.getBean(headEnhancerClass);
|
Assert.notNull(headGenerator, "The header generated bean does not exist.");
|
HeadMeta head = headGenerator.head(dataClass);
|
writerSheetBuilder.head(head.getHead());
|
writerSheetBuilder.excludeColumnFiledNames(head.getIgnoreHeadFields());
|
}
|
|
private boolean isNotInterface(Class<? extends HeadGenerator> headGeneratorClass) {
|
return !Modifier.isInterface(headGeneratorClass.getModifiers());
|
}
|
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
this.applicationContext = applicationContext;
|
}
|
}
|