✨ Introducing new features. close #4311 common-excel 支持JDK17

This commit is contained in:
lbw committed 2022-09-03 16:30:09 +08:00
1 parent 39aee6dffe
commit 86dfea85ac
27 files changed
+162 -1048

No files matched your search

+8 -17
View File
@@ -33,8 +33,8 @@
<description>pigx excel 操作</description>
<properties>
<poi.version>4.1.2</poi.version>
<easypoi.version>2.2.10</easypoi.version>
<commons-compress>1.21</commons-compress>
<easyexcel.version>3.1.1</easyexcel.version>
</properties>
<dependencies>
@@ -55,27 +55,18 @@
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${easypoi.version}</version>
<version>${easyexcel.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 使用 POI 4.x 解决 issue #1 支持java11-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>${commons-compress}</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
@@ -1,526 +0,0 @@
package com.alibaba.excel.context;
import com.alibaba.excel.enums.WriteTypeEnum;
import com.alibaba.excel.exception.ExcelGenerateException;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.*;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.alibaba.excel.write.metadata.WriteWorkbook;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import com.alibaba.excel.write.property.ExcelWriteHeadProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.record.crypto.Biff8EncryptionKey;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.poifs.crypt.EncryptionInfo;
import org.apache.poi.poifs.crypt.EncryptionMode;
import org.apache.poi.poifs.crypt.Encryptor;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.UUID;
/**
* A context is the main anchorage point of a excel writer.
*
* @author jipengfei
*/
@Slf4j
public class WriteContextImpl implements WriteContext {
static {
log.debug("======[WriteContextImpl] 修复版被加载了=======");
}
private static final Logger LOGGER = LoggerFactory.getLogger(WriteContextImpl.class);
/**
* The Workbook currently written
*/
private WriteWorkbookHolder writeWorkbookHolder;
/**
* Current sheet holder
*/
private WriteSheetHolder writeSheetHolder;
/**
* The table currently written
*/
private WriteTableHolder writeTableHolder;
/**
* Configuration of currently operated cell
*/
private WriteHolder currentWriteHolder;
/**
* Prevent multiple shutdowns
*/
private boolean finished = false;
public WriteContextImpl(WriteWorkbook writeWorkbook) {
if (writeWorkbook == null) {
throw new IllegalArgumentException("Workbook argument cannot be null");
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Begin to Initialization 'WriteContextImpl'");
}
initCurrentWorkbookHolder(writeWorkbook);
WriteHandlerUtils.beforeWorkbookCreate(this);
try {
WorkBookUtil.createWorkBook(writeWorkbookHolder);
}
catch (Exception e) {
throw new ExcelGenerateException("Create workbook failure", e);
}
WriteHandlerUtils.afterWorkbookCreate(this);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Initialization 'WriteContextImpl' complete");
}
}
private void initCurrentWorkbookHolder(WriteWorkbook writeWorkbook) {
writeWorkbookHolder = new WriteWorkbookHolder(writeWorkbook);
currentWriteHolder = writeWorkbookHolder;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("CurrentConfiguration is writeWorkbookHolder");
}
}
/**
* @param writeSheet
*/
@Override
public void currentSheet(WriteSheet writeSheet, WriteTypeEnum writeType) {
if (writeSheet == null) {
throw new IllegalArgumentException("Sheet argument cannot be null");
}
if (selectSheetFromCache(writeSheet)) {
return;
}
initCurrentSheetHolder(writeSheet);
// Workbook handler need to supplementary execution
WriteHandlerUtils.beforeWorkbookCreate(this, true);
WriteHandlerUtils.afterWorkbookCreate(this, true);
// Initialization current sheet
initSheet(writeType);
}
private boolean selectSheetFromCache(WriteSheet writeSheet) {
writeSheetHolder = null;
Integer sheetNo = writeSheet.getSheetNo();
if (sheetNo == null && StringUtils.isEmpty(writeSheet.getSheetName())) {
sheetNo = 0;
}
if (sheetNo != null) {
writeSheetHolder = writeWorkbookHolder.getHasBeenInitializedSheetIndexMap().get(sheetNo);
}
if (writeSheetHolder == null && !StringUtils.isEmpty(writeSheet.getSheetName())) {
writeSheetHolder = writeWorkbookHolder.getHasBeenInitializedSheetNameMap().get(writeSheet.getSheetName());
}
if (writeSheetHolder == null) {
return false;
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Sheet:{} is already existed", writeSheet.getSheetNo());
}
writeSheetHolder.setNewInitialization(Boolean.FALSE);
writeTableHolder = null;
currentWriteHolder = writeSheetHolder;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("CurrentConfiguration is writeSheetHolder");
}
return true;
}
private void initCurrentSheetHolder(WriteSheet writeSheet) {
writeSheetHolder = new WriteSheetHolder(writeSheet, writeWorkbookHolder);
writeTableHolder = null;
currentWriteHolder = writeSheetHolder;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("CurrentConfiguration is writeSheetHolder");
}
}
private void initSheet(WriteTypeEnum writeType) {
WriteHandlerUtils.beforeSheetCreate(this);
Sheet currentSheet;
try {
if (writeSheetHolder.getSheetNo() != null) {
// When the add default sort order of appearance
if (WriteTypeEnum.ADD.equals(writeType) && writeWorkbookHolder.getTempTemplateInputStream() == null) {
currentSheet = createSheet();
}
else {
currentSheet = writeWorkbookHolder.getWorkbook().getSheetAt(writeSheetHolder.getSheetNo());
writeSheetHolder.setCachedSheet(
writeWorkbookHolder.getCachedWorkbook().getSheetAt(writeSheetHolder.getSheetNo()));
}
}
else {
// sheet name must not null
currentSheet = writeWorkbookHolder.getWorkbook().getSheet(writeSheetHolder.getSheetName());
writeSheetHolder.setCachedSheet(
writeWorkbookHolder.getCachedWorkbook().getSheet(writeSheetHolder.getSheetName()));
}
}
catch (Exception e) {
currentSheet = createSheet();
}
if (currentSheet == null) {
currentSheet = createSheet();
}
writeSheetHolder.setSheet(currentSheet);
WriteHandlerUtils.afterSheetCreate(this);
if (WriteTypeEnum.ADD.equals(writeType)) {
// Initialization head
initHead(writeSheetHolder.excelWriteHeadProperty());
}
writeWorkbookHolder.getHasBeenInitializedSheetIndexMap().put(writeSheetHolder.getSheetNo(), writeSheetHolder);
writeWorkbookHolder.getHasBeenInitializedSheetNameMap().put(writeSheetHolder.getSheetName(), writeSheetHolder);
}
private Sheet createSheet() {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Can not find sheet:{} ,now create it", writeSheetHolder.getSheetNo());
}
if (StringUtils.isEmpty(writeSheetHolder.getSheetName())) {
writeSheetHolder.setSheetName(writeSheetHolder.getSheetNo().toString());
}
Sheet currentSheet = WorkBookUtil.createSheet(writeWorkbookHolder.getWorkbook(),
writeSheetHolder.getSheetName());
writeSheetHolder.setCachedSheet(currentSheet);
return currentSheet;
}
public void initHead(ExcelWriteHeadProperty excelWriteHeadProperty) {
if (!currentWriteHolder.needHead() || !currentWriteHolder.excelWriteHeadProperty().hasHead()) {
return;
}
int newRowIndex = writeSheetHolder.getNewRowIndexAndStartDoWrite();
newRowIndex += currentWriteHolder.relativeHeadRowIndex();
// Combined head
if (currentWriteHolder.automaticMergeHead()) {
addMergedRegionToCurrentSheet(excelWriteHeadProperty, newRowIndex);
}
for (int relativeRowIndex = 0,
i = newRowIndex; i < excelWriteHeadProperty.getHeadRowNumber() + newRowIndex; i++, relativeRowIndex++) {
WriteHandlerUtils.beforeRowCreate(this, newRowIndex, relativeRowIndex, Boolean.TRUE);
Row row = WorkBookUtil.createRow(writeSheetHolder.getSheet(), i);
WriteHandlerUtils.afterRowCreate(this, row, relativeRowIndex, Boolean.TRUE);
addOneRowOfHeadDataToExcel(row, excelWriteHeadProperty.getHeadMap(), relativeRowIndex);
WriteHandlerUtils.afterRowDispose(this, row, relativeRowIndex, Boolean.TRUE);
}
}
private void addMergedRegionToCurrentSheet(ExcelWriteHeadProperty excelWriteHeadProperty, int rowIndex) {
for (com.alibaba.excel.metadata.CellRange cellRangeModel : excelWriteHeadProperty.headCellRangeList()) {
writeSheetHolder.getSheet()
.addMergedRegionUnsafe(new CellRangeAddress(cellRangeModel.getFirstRow() + rowIndex,
cellRangeModel.getLastRow() + rowIndex, cellRangeModel.getFirstCol(),
cellRangeModel.getLastCol()));
}
}
private void addOneRowOfHeadDataToExcel(Row row, Map<Integer, Head> headMap, int relativeRowIndex) {
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
Head head = entry.getValue();
int columnIndex = entry.getKey();
WriteHandlerUtils.beforeCellCreate(this, row, head, columnIndex, relativeRowIndex, Boolean.TRUE);
Cell cell = row.createCell(columnIndex);
WriteHandlerUtils.afterCellCreate(this, cell, head, relativeRowIndex, Boolean.TRUE);
cell.setCellValue(head.getHeadNameList().get(relativeRowIndex));
WriteHandlerUtils.afterCellDispose(this, (CellData) null, cell, head, relativeRowIndex, Boolean.TRUE);
}
}
@Override
public void currentTable(WriteTable writeTable) {
if (writeTable == null) {
return;
}
if (writeTable.getTableNo() == null || writeTable.getTableNo() <= 0) {
writeTable.setTableNo(0);
}
if (writeSheetHolder.getHasBeenInitializedTable().containsKey(writeTable.getTableNo())) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Table:{} is already existed", writeTable.getTableNo());
}
writeTableHolder = writeSheetHolder.getHasBeenInitializedTable().get(writeTable.getTableNo());
writeTableHolder.setNewInitialization(Boolean.FALSE);
currentWriteHolder = writeTableHolder;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("CurrentConfiguration is writeTableHolder");
}
return;
}
initCurrentTableHolder(writeTable);
// Workbook and sheet handler need to supplementary execution
WriteHandlerUtils.beforeWorkbookCreate(this, true);
WriteHandlerUtils.afterWorkbookCreate(this, true);
WriteHandlerUtils.beforeSheetCreate(this, true);
WriteHandlerUtils.afterSheetCreate(this, true);
initHead(writeTableHolder.excelWriteHeadProperty());
}
private void initCurrentTableHolder(WriteTable writeTable) {
writeTableHolder = new WriteTableHolder(writeTable, writeSheetHolder, writeWorkbookHolder);
writeSheetHolder.getHasBeenInitializedTable().put(writeTable.getTableNo(), writeTableHolder);
currentWriteHolder = writeTableHolder;
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("CurrentConfiguration is writeTableHolder");
}
}
@Override
public WriteWorkbookHolder writeWorkbookHolder() {
return writeWorkbookHolder;
}
@Override
public WriteSheetHolder writeSheetHolder() {
return writeSheetHolder;
}
@Override
public WriteTableHolder writeTableHolder() {
return writeTableHolder;
}
@Override
public WriteHolder currentWriteHolder() {
return currentWriteHolder;
}
@Override
public void finish(boolean onException) {
if (finished) {
return;
}
finished = true;
WriteHandlerUtils.afterWorkbookDispose(this);
if (writeWorkbookHolder == null) {
return;
}
Throwable throwable = null;
boolean isOutputStreamEncrypt = false;
// Determine if you need to write excel
boolean writeExcel = !onException;
if (writeWorkbookHolder.getWriteExcelOnException()) {
writeExcel = Boolean.TRUE;
}
// No data is written if an exception is thrown
if (writeExcel) {
try {
isOutputStreamEncrypt = doOutputStreamEncrypt07();
}
catch (Throwable t) {
throwable = t;
}
}
if (!isOutputStreamEncrypt) {
try {
if (writeExcel) {
writeWorkbookHolder.getWorkbook().write(writeWorkbookHolder.getOutputStream());
}
writeWorkbookHolder.getWorkbook().close();
}
catch (Throwable t) {
throwable = t;
}
}
try {
Workbook workbook = writeWorkbookHolder.getWorkbook();
if (workbook instanceof SXSSFWorkbook) {
((SXSSFWorkbook) workbook).dispose();
}
}
catch (Throwable t) {
throwable = t;
}
try {
if (writeWorkbookHolder.getAutoCloseStream() && writeWorkbookHolder.getOutputStream() != null) {
writeWorkbookHolder.getOutputStream().close();
}
}
catch (Throwable t) {
throwable = t;
}
if (writeExcel && !isOutputStreamEncrypt) {
try {
doFileEncrypt07();
}
catch (Throwable t) {
throwable = t;
}
}
try {
if (writeWorkbookHolder.getTempTemplateInputStream() != null) {
writeWorkbookHolder.getTempTemplateInputStream().close();
}
}
catch (Throwable t) {
throwable = t;
}
clearEncrypt03();
removeThreadLocalCache();
if (throwable != null) {
throw new ExcelGenerateException("Can not close IO.", throwable);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Finished write.");
}
}
private void removeThreadLocalCache() {
NumberDataFormatterUtils.removeThreadLocalCache();
DateUtils.removeThreadLocalCache();
}
@Override
public Sheet getCurrentSheet() {
return writeSheetHolder.getSheet();
}
@Override
public boolean needHead() {
return writeSheetHolder.needHead();
}
@Override
public OutputStream getOutputStream() {
return writeWorkbookHolder.getOutputStream();
}
@Override
public Workbook getWorkbook() {
return writeWorkbookHolder.getWorkbook();
}
private void clearEncrypt03() {
if (StringUtils.isEmpty(writeWorkbookHolder.getPassword())
|| !ExcelTypeEnum.XLS.equals(writeWorkbookHolder.getExcelType())) {
return;
}
Biff8EncryptionKey.setCurrentUserPassword(null);
}
/**
* To encrypt
*/
private boolean doOutputStreamEncrypt07() throws Exception {
if (StringUtils.isEmpty(writeWorkbookHolder.getPassword())
|| !ExcelTypeEnum.XLSX.equals(writeWorkbookHolder.getExcelType())) {
return false;
}
if (writeWorkbookHolder.getFile() != null) {
return false;
}
File tempXlsx = FileUtils.createTmpFile(UUID.randomUUID().toString() + ".xlsx");
FileOutputStream tempFileOutputStream = new FileOutputStream(tempXlsx);
try {
writeWorkbookHolder.getWorkbook().write(tempFileOutputStream);
}
finally {
try {
writeWorkbookHolder.getWorkbook().close();
tempFileOutputStream.close();
}
catch (Exception e) {
if (!tempXlsx.delete()) {
throw new ExcelGenerateException("Can not delete temp File!");
}
throw e;
}
}
POIFSFileSystem fileSystem = null;
try {
fileSystem = openFileSystemAndEncrypt(tempXlsx);
fileSystem.writeFilesystem(writeWorkbookHolder.getOutputStream());
}
finally {
if (fileSystem != null) {
fileSystem.close();
}
if (!tempXlsx.delete()) {
throw new ExcelGenerateException("Can not delete temp File!");
}
}
return true;
}
/**
* To encrypt
*/
private void doFileEncrypt07() throws Exception {
if (StringUtils.isEmpty(writeWorkbookHolder.getPassword())
|| !ExcelTypeEnum.XLSX.equals(writeWorkbookHolder.getExcelType())) {
return;
}
if (writeWorkbookHolder.getFile() == null) {
return;
}
FileOutputStream fileOutputStream = null;
POIFSFileSystem fileSystem = null;
try {
fileSystem = openFileSystemAndEncrypt(writeWorkbookHolder.getFile());
fileOutputStream = new FileOutputStream(writeWorkbookHolder.getFile());
fileSystem.writeFilesystem(fileOutputStream);
}
finally {
if (fileOutputStream != null) {
fileOutputStream.close();
}
if (fileSystem != null) {
fileSystem.close();
}
}
}
private POIFSFileSystem openFileSystemAndEncrypt(File file) throws Exception {
POIFSFileSystem fileSystem = new POIFSFileSystem();
Encryptor encryptor = new EncryptionInfo(EncryptionMode.standard).getEncryptor();
encryptor.confirmPassword(writeWorkbookHolder.getPassword());
OPCPackage opcPackage = null;
OutputStream outputStream = null;
try {
opcPackage = OPCPackage.open(file, PackageAccess.READ_WRITE);
outputStream = encryptor.getDataStream(fileSystem);
opcPackage.save(outputStream);
}
finally {
if (opcPackage != null) {
opcPackage.close();
}
if (outputStream != null) {
outputStream.close();
}
}
return fileSystem;
}
}
@@ -1,221 +0,0 @@
package com.alibaba.excel.util;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.exception.ExcelCommonException;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Holder;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
import lombok.extern.slf4j.Slf4j;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Class utils
*
* @author Jiaju Zhuang
**/
@Slf4j
public class ClassUtils {
static {
log.debug("======[ClassUtils] 修复版被加载了=======");
}
private static final Map<Class, SoftReference<FieldCache>> FIELD_CACHE = new ConcurrentHashMap<Class, SoftReference<FieldCache>>();
public static void declaredFields(Class clazz, Map<Integer, Field> sortedAllFiledMap,
Map<Integer, Field> indexFiledMap, Map<String, Field> ignoreMap, Boolean convertAllFiled,
Boolean needIgnore, Holder holder) {
FieldCache fieldCache = getFieldCache(clazz, convertAllFiled);
if (fieldCache == null) {
return;
}
if (ignoreMap != null) {
ignoreMap.putAll(fieldCache.getIgnoreMap());
}
Map<Integer, Field> tempIndexFildMap = indexFiledMap;
if (tempIndexFildMap == null) {
tempIndexFildMap = new TreeMap<Integer, Field>();
}
tempIndexFildMap.putAll(fieldCache.getIndexFiledMap());
Map<Integer, Field> originSortedAllFiledMap = fieldCache.getSortedAllFiledMap();
if (!needIgnore) {
sortedAllFiledMap.putAll(originSortedAllFiledMap);
return;
}
// 获取到属性字段的最大index
int maxIndex = -1;
for (Integer filedIndex : originSortedAllFiledMap.keySet()) {
maxIndex = Math.max(filedIndex, maxIndex);
}
// 被忽略的属性数量
int ignoreNum = 0;
// 当有属性被忽略时,需要将其后面的所有属性 index 前移
for (int index = 0; index <= maxIndex; index++) {
Field field = originSortedAllFiledMap.get(index);
String name = field == null ? null : field.getName();
if (((WriteHolder) holder).ignore(name, index)) {
if (ignoreMap != null && name != null) {
ignoreMap.put(name, field);
}
tempIndexFildMap.remove(index);
ignoreNum++;
}
else if (field != null) {
int finalIndex = index - ignoreNum;
sortedAllFiledMap.put(finalIndex, field);
}
}
}
public static void declaredFields(Class clazz, Map<Integer, Field> sortedAllFiledMap, Boolean convertAllFiled,
Boolean needIgnore, WriteHolder writeHolder) {
declaredFields(clazz, sortedAllFiledMap, null, null, convertAllFiled, needIgnore, writeHolder);
}
private static FieldCache getFieldCache(Class clazz, Boolean convertAllFiled) {
if (clazz == null) {
return null;
}
SoftReference<FieldCache> fieldCacheSoftReference = FIELD_CACHE.get(clazz);
if (fieldCacheSoftReference != null && fieldCacheSoftReference.get() != null) {
return fieldCacheSoftReference.get();
}
synchronized (clazz) {
fieldCacheSoftReference = FIELD_CACHE.get(clazz);
if (fieldCacheSoftReference != null && fieldCacheSoftReference.get() != null) {
return fieldCacheSoftReference.get();
}
declaredFields(clazz, convertAllFiled);
}
return FIELD_CACHE.get(clazz).get();
}
private static void declaredFields(Class clazz, Boolean convertAllFiled) {
List<Field> tempFieldList = new ArrayList<Field>();
Class tempClass = clazz;
// When the parent class is null, it indicates that the parent class (Object
// class) has reached the top
// level.
while (tempClass != null && tempClass != BaseRowModel.class) {
Collections.addAll(tempFieldList, tempClass.getDeclaredFields());
// Get the parent class and give it to yourself
tempClass = tempClass.getSuperclass();
}
// Screening of field
Map<Integer, List<Field>> orderFiledMap = new TreeMap<Integer, List<Field>>();
Map<Integer, Field> indexFiledMap = new TreeMap<Integer, Field>();
Map<String, Field> ignoreMap = new HashMap<String, Field>(16);
ExcelIgnoreUnannotated excelIgnoreUnannotated = (ExcelIgnoreUnannotated) clazz
.getAnnotation(ExcelIgnoreUnannotated.class);
for (Field field : tempFieldList) {
declaredOneField(field, orderFiledMap, indexFiledMap, ignoreMap, excelIgnoreUnannotated, convertAllFiled);
}
FIELD_CACHE.put(clazz, new SoftReference<FieldCache>(
new FieldCache(buildSortedAllFiledMap(orderFiledMap, indexFiledMap), indexFiledMap, ignoreMap)));
}
private static Map<Integer, Field> buildSortedAllFiledMap(Map<Integer, List<Field>> orderFiledMap,
Map<Integer, Field> indexFiledMap) {
Map<Integer, Field> sortedAllFiledMap = new HashMap<Integer, Field>(
(orderFiledMap.size() + indexFiledMap.size()) * 4 / 3 + 1);
Map<Integer, Field> tempIndexFiledMap = new HashMap<Integer, Field>(indexFiledMap);
int index = 0;
for (List<Field> fieldList : orderFiledMap.values()) {
for (Field field : fieldList) {
while (tempIndexFiledMap.containsKey(index)) {
sortedAllFiledMap.put(index, tempIndexFiledMap.get(index));
tempIndexFiledMap.remove(index);
index++;
}
sortedAllFiledMap.put(index, field);
index++;
}
}
sortedAllFiledMap.putAll(tempIndexFiledMap);
return sortedAllFiledMap;
}
private static void declaredOneField(Field field, Map<Integer, List<Field>> orderFiledMap,
Map<Integer, Field> indexFiledMap, Map<String, Field> ignoreMap,
ExcelIgnoreUnannotated excelIgnoreUnannotated, Boolean convertAllFiled) {
ExcelIgnore excelIgnore = field.getAnnotation(ExcelIgnore.class);
if (excelIgnore != null) {
ignoreMap.put(field.getName(), field);
return;
}
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
boolean noExcelProperty = excelProperty == null
&& ((convertAllFiled != null && !convertAllFiled) || excelIgnoreUnannotated != null);
if (noExcelProperty) {
ignoreMap.put(field.getName(), field);
return;
}
boolean isStaticFinalOrTransient = (Modifier.isStatic(field.getModifiers())
&& Modifier.isFinal(field.getModifiers())) || Modifier.isTransient(field.getModifiers());
if (excelProperty == null && isStaticFinalOrTransient) {
ignoreMap.put(field.getName(), field);
return;
}
if (excelProperty != null && excelProperty.index() >= 0) {
if (indexFiledMap.containsKey(excelProperty.index())) {
throw new ExcelCommonException("The index of '" + indexFiledMap.get(excelProperty.index()).getName()
+ "' and '" + field.getName() + "' must be inconsistent");
}
indexFiledMap.put(excelProperty.index(), field);
return;
}
int order = Integer.MAX_VALUE;
if (excelProperty != null) {
order = excelProperty.order();
}
List<Field> orderFiledList = orderFiledMap.get(order);
if (orderFiledList == null) {
orderFiledList = new ArrayList<Field>();
orderFiledMap.put(order, orderFiledList);
}
orderFiledList.add(field);
}
private static class FieldCache {
private Map<Integer, Field> sortedAllFiledMap;
private Map<Integer, Field> indexFiledMap;
private Map<String, Field> ignoreMap;
public FieldCache(Map<Integer, Field> sortedAllFiledMap, Map<Integer, Field> indexFiledMap,
Map<String, Field> ignoreMap) {
this.sortedAllFiledMap = sortedAllFiledMap;
this.indexFiledMap = indexFiledMap;
this.ignoreMap = ignoreMap;
}
public Map<Integer, Field> getSortedAllFiledMap() {
return sortedAllFiledMap;
}
public Map<Integer, Field> getIndexFiledMap() {
return indexFiledMap;
}
public Map<String, Field> getIgnoreMap() {
return ignoreMap;
}
}
}
@@ -1,185 +0,0 @@
package com.alibaba.excel.write.executor;
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.enums.HeadKindEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.ClassUtils;
import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.excel.util.WorkBookUtil;
import com.alibaba.excel.util.WriteHandlerUtils;
import com.alibaba.excel.write.metadata.holder.AbstractWriteHolder;
import com.alibaba.excel.write.metadata.holder.WriteHolder;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.beans.BeanMap;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import java.lang.reflect.Field;
import java.util.*;
/**
* Add the data into excel
*
* @author Jiaju Zhuang
*/
@Slf4j
public class ExcelWriteAddExecutor extends AbstractExcelWriteExecutor {
static {
log.debug("======[ExcelWriteAddExecutor] 修复版被加载了=======");
}
public ExcelWriteAddExecutor(WriteContext writeContext) {
super(writeContext);
}
public void add(List data) {
if (CollectionUtils.isEmpty(data)) {
data = new ArrayList();
}
WriteSheetHolder writeSheetHolder = writeContext.writeSheetHolder();
int newRowIndex = writeSheetHolder.getNewRowIndexAndStartDoWrite();
if (writeSheetHolder.isNew() && !writeSheetHolder.getExcelWriteHeadProperty().hasHead()) {
newRowIndex += writeContext.currentWriteHolder().relativeHeadRowIndex();
}
// BeanMap is out of order,so use sortedAllFiledMap
Map<Integer, Field> sortedAllFiledMap = new TreeMap<Integer, Field>();
int relativeRowIndex = 0;
for (Object oneRowData : data) {
int n = relativeRowIndex + newRowIndex;
addOneRowOfDataToExcel(oneRowData, n, relativeRowIndex, sortedAllFiledMap);
relativeRowIndex++;
}
}
private void addOneRowOfDataToExcel(Object oneRowData, int n, int relativeRowIndex,
Map<Integer, Field> sortedAllFiledMap) {
if (oneRowData == null) {
return;
}
WriteHandlerUtils.beforeRowCreate(writeContext, n, relativeRowIndex, Boolean.FALSE);
Row row = WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(), n);
WriteHandlerUtils.afterRowCreate(writeContext, row, relativeRowIndex, Boolean.FALSE);
if (oneRowData instanceof List) {
addBasicTypeToExcel((List) oneRowData, row, relativeRowIndex);
}
else {
addJavaObjectToExcel(oneRowData, row, relativeRowIndex, sortedAllFiledMap);
}
WriteHandlerUtils.afterRowDispose(writeContext, row, relativeRowIndex, Boolean.FALSE);
}
private void addBasicTypeToExcel(List<Object> oneRowData, Row row, int relativeRowIndex) {
if (CollectionUtils.isEmpty(oneRowData)) {
return;
}
Map<Integer, Head> headMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap();
int dataIndex = 0;
int cellIndex = 0;
for (Map.Entry<Integer, Head> entry : headMap.entrySet()) {
if (dataIndex >= oneRowData.size()) {
return;
}
cellIndex = entry.getKey();
Head head = entry.getValue();
doAddBasicTypeToExcel(oneRowData, head, row, relativeRowIndex, dataIndex++, cellIndex);
}
// Finish
if (dataIndex >= oneRowData.size()) {
return;
}
if (cellIndex != 0) {
cellIndex++;
}
int size = oneRowData.size() - dataIndex;
for (int i = 0; i < size; i++) {
doAddBasicTypeToExcel(oneRowData, null, row, relativeRowIndex, dataIndex++, cellIndex++);
}
}
private void doAddBasicTypeToExcel(List<Object> oneRowData, Head head, Row row, int relativeRowIndex, int dataIndex,
int cellIndex) {
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE);
Cell cell = WorkBookUtil.createCell(row, cellIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE);
Object value = oneRowData.get(dataIndex);
CellData cellData = converterAndSet(writeContext.currentWriteHolder(), value == null ? null : value.getClass(),
cell, value, null, head, relativeRowIndex);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE);
}
private void addJavaObjectToExcel(Object oneRowData, Row row, int relativeRowIndex,
Map<Integer, Field> sortedAllFiledMap) {
WriteHolder currentWriteHolder = writeContext.currentWriteHolder();
BeanMap beanMap = BeanMap.create(oneRowData);
Set<String> beanMapHandledSet = new HashSet<String>();
int cellIndex = 0;
// If it's a class it needs to be cast by type
if (HeadKindEnum.CLASS.equals(writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadKind())) {
Map<Integer, Head> headMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap();
Map<Integer, ExcelContentProperty> contentPropertyMap = writeContext.currentWriteHolder()
.excelWriteHeadProperty().getContentPropertyMap();
for (Map.Entry<Integer, ExcelContentProperty> entry : contentPropertyMap.entrySet()) {
cellIndex = entry.getKey();
ExcelContentProperty excelContentProperty = entry.getValue();
String name = excelContentProperty.getField().getName();
if (!beanMap.containsKey(name)) {
continue;
}
Head head = headMap.get(cellIndex);
WriteHandlerUtils.beforeCellCreate(writeContext, row, head, cellIndex, relativeRowIndex, Boolean.FALSE);
Cell cell = WorkBookUtil.createCell(row, cellIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, head, relativeRowIndex, Boolean.FALSE);
Object value = beanMap.get(name);
CellData cellData = converterAndSet(currentWriteHolder, excelContentProperty.getField().getType(), cell,
value, excelContentProperty, head, relativeRowIndex);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, head, relativeRowIndex, Boolean.FALSE);
beanMapHandledSet.add(name);
}
}
// Finish
if (beanMapHandledSet.size() == beanMap.size()) {
return;
}
Map<String, Field> ignoreMap = writeContext.currentWriteHolder().excelWriteHeadProperty().getIgnoreMap();
initSortedAllFiledMapFieldList(oneRowData.getClass(), sortedAllFiledMap);
for (Map.Entry<Integer, Field> entry : sortedAllFiledMap.entrySet()) {
cellIndex = entry.getKey();
Field field = entry.getValue();
String filedName = field.getName();
boolean uselessData = !beanMap.containsKey(filedName) || beanMapHandledSet.contains(filedName)
|| ignoreMap.containsKey(filedName);
if (uselessData) {
continue;
}
Object value = beanMap.get(filedName);
WriteHandlerUtils.beforeCellCreate(writeContext, row, null, cellIndex, relativeRowIndex, Boolean.FALSE);
Cell cell = WorkBookUtil.createCell(row, cellIndex);
WriteHandlerUtils.afterCellCreate(writeContext, cell, null, relativeRowIndex, Boolean.FALSE);
CellData cellData = converterAndSet(currentWriteHolder, value == null ? null : value.getClass(), cell,
value, null, null, relativeRowIndex);
WriteHandlerUtils.afterCellDispose(writeContext, cellData, cell, null, relativeRowIndex, Boolean.FALSE);
}
}
private void initSortedAllFiledMapFieldList(Class clazz, Map<Integer, Field> sortedAllFiledMap) {
if (!sortedAllFiledMap.isEmpty()) {
return;
}
// 获取当前的使用的 holder
WriteHolder holder = writeContext.currentWriteHolder();
boolean needIgnore = (holder instanceof AbstractWriteHolder)
&& (!CollectionUtils.isEmpty(((AbstractWriteHolder) holder).getExcludeColumnFiledNames())
|| !CollectionUtils.isEmpty(((AbstractWriteHolder) holder).getExcludeColumnIndexes())
|| !CollectionUtils.isEmpty(((AbstractWriteHolder) holder).getIncludeColumnFiledNames())
|| !CollectionUtils.isEmpty(((AbstractWriteHolder) holder).getIncludeColumnIndexes()));
ClassUtils.declaredFields(clazz, sortedAllFiledMap,
writeContext.writeWorkbookHolder().getWriteWorkbook().getConvertAllFiled(), needIgnore, holder);
}
}
@@ -15,7 +15,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
@@ -24,7 +23,6 @@ import java.util.List;
* @version 1.0
*/
@RequiredArgsConstructor
@Configuration
public class ExcelHandlerConfiguration {
private final ExcelConfigProperties configProperties;
@@ -1,16 +1,16 @@
package com.pig4cloud.pigx.common.excel;
import com.pig4cloud.pigx.common.excel.aop.DynamicNameAspect;
import com.pig4cloud.pigx.common.excel.aop.RequestExcelArgumentResolver;
import com.pig4cloud.pigx.common.excel.aop.ResponseExcelReturnValueHandler;
import com.pig4cloud.pigx.common.excel.config.ExcelConfigProperties;
import com.pig4cloud.pigx.common.excel.processor.NameProcessor;
import com.pig4cloud.pigx.common.excel.processor.NameSpelExpressionProcessor;
import com.pig4cloud.pigx.common.excel.aop.DynamicNameAspect;
import com.pig4cloud.pigx.common.excel.aop.RequestExcelArgumentResolver;
import com.pig4cloud.pigx.common.excel.aop.ResponseExcelReturnValueHandler;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
@@ -26,9 +26,9 @@ import java.util.List;
* <p>
* 配置初始化
*/
@Import(ExcelHandlerConfiguration.class)
@AutoConfiguration
@RequiredArgsConstructor
@Configuration(proxyBeanMethods = false)
@Import(ExcelHandlerConfiguration.class)
@EnableConfigurationProperties(ExcelConfigProperties.class)
public class ResponseExcelAutoConfiguration {
@@ -0,0 +1,10 @@
package com.pig4cloud.pigx.common.excel.annotation;
import java.lang.annotation.*;
@Documented
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelLine {
}
@@ -89,4 +89,10 @@ public @interface ResponseExcel {
*/
boolean i18nHeader() default false;
/**
* 填充模式
* @return
*/
boolean fill() default false;
}
@@ -1,7 +1,7 @@
package com.pig4cloud.pigx.common.excel.aop;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.excel.processor.NameProcessor;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
@@ -40,7 +40,7 @@ public class RequestExcelArgumentResolver implements HandlerMethodArgumentResolv
}
@Override
@SneakyThrows
@SneakyThrows(Exception.class)
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer modelAndViewContainer,
NativeWebRequest webRequest, WebDataBinderFactory webDataBinderFactory) {
Class<?> parameterType = parameter.getParameterType();
@@ -1,7 +1,7 @@
package com.pig4cloud.pigx.common.excel.aop;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.excel.handler.SheetWriteHandler;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
@@ -40,11 +40,10 @@ public class ResponseExcelReturnValueHandler implements HandlerMethodReturnValue
* @param parameter 方法签名
* @param mavContainer 上下文容器
* @param nativeWebRequest 上下文
* @throws Exception 处理异常
*/
@Override
public void handleReturnValue(Object o, MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest nativeWebRequest) throws Exception {
NativeWebRequest nativeWebRequest) {
/* check */
HttpServletResponse response = nativeWebRequest.getNativeResponse(HttpServletResponse.class);
Assert.state(response != null, "No HttpServletResponse");
@@ -2,8 +2,9 @@ package com.pig4cloud.pigx.common.excel.converters;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.text.ParseException;
@@ -33,7 +34,7 @@ public enum LocalDateStringConverter implements Converter<LocalDate> {
}
@Override
public LocalDate convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,
public LocalDate convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) throws ParseException {
if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) {
return LocalDate.parse(cellData.getStringValue());
@@ -46,7 +47,7 @@ public enum LocalDateStringConverter implements Converter<LocalDate> {
}
@Override
public CellData<String> convertToExcelData(LocalDate value, ExcelContentProperty contentProperty,
public WriteCellData<String> convertToExcelData(LocalDate value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
DateTimeFormatter formatter;
if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) {
@@ -55,7 +56,7 @@ public enum LocalDateStringConverter implements Converter<LocalDate> {
else {
formatter = DateTimeFormatter.ofPattern(contentProperty.getDateTimeFormatProperty().getFormat());
}
return new CellData<>(value.format(formatter));
return new WriteCellData<>(value.format(formatter));
}
}
@@ -2,8 +2,9 @@ package com.pig4cloud.pigx.common.excel.converters;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import com.alibaba.excel.util.DateUtils;
@@ -36,7 +37,7 @@ public enum LocalDateTimeStringConverter implements Converter<LocalDateTime> {
}
@Override
public LocalDateTime convertToJavaData(CellData cellData, ExcelContentProperty contentProperty,
public LocalDateTime convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) throws ParseException {
String stringValue = cellData.getStringValue();
String pattern;
@@ -51,7 +52,7 @@ public enum LocalDateTimeStringConverter implements Converter<LocalDateTime> {
}
@Override
public CellData<String> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty,
public WriteCellData<String> convertToExcelData(LocalDateTime value, ExcelContentProperty contentProperty,
GlobalConfiguration globalConfiguration) {
String pattern;
if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) {
@@ -61,7 +62,7 @@ public enum LocalDateTimeStringConverter implements Converter<LocalDateTime> {
pattern = contentProperty.getDateTimeFormatProperty().getFormat();
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return new CellData<>(value.format(formatter));
return new WriteCellData<>(value.format(formatter));
}
/**
@@ -72,21 +73,21 @@ public enum LocalDateTimeStringConverter implements Converter<LocalDateTime> {
private static String switchDateFormat(String dateString) {
int length = dateString.length();
switch (length) {
case 19:
if (dateString.contains(MINUS)) {
return DateUtils.DATE_FORMAT_19;
}
else {
return DateUtils.DATE_FORMAT_19_FORWARD_SLASH;
}
case 17:
return DateUtils.DATE_FORMAT_17;
case 14:
return DateUtils.DATE_FORMAT_14;
case 10:
return DateUtils.DATE_FORMAT_10;
default:
throw new IllegalArgumentException("can not find date format for:" + dateString);
case 19:
if (dateString.contains(MINUS)) {
return DateUtils.DATE_FORMAT_19;
}
else {
return DateUtils.DATE_FORMAT_19_FORWARD_SLASH;
}
case 17:
return DateUtils.DATE_FORMAT_17;
case 14:
return DateUtils.DATE_FORMAT_14;
case 10:
return DateUtils.DATE_FORMAT_10;
default:
throw new IllegalArgumentException("can not find date format for:" + dateString);
}
}
@@ -2,8 +2,8 @@ package com.pig4cloud.pigx.common.excel.enhance;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.excel.head.HeadGenerator;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import javax.servlet.http.HttpServletResponse;
@@ -11,13 +11,13 @@ import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.excel.annotation.Sheet;
import com.pig4cloud.pigx.common.excel.aop.DynamicNameAspect;
import com.pig4cloud.pigx.common.excel.config.ExcelConfigProperties;
import com.pig4cloud.pigx.common.excel.converters.LocalDateStringConverter;
import com.pig4cloud.pigx.common.excel.converters.LocalDateTimeStringConverter;
import com.pig4cloud.pigx.common.excel.enhance.WriterBuilderEnhancer;
import com.pig4cloud.pigx.common.excel.head.HeadGenerator;
import com.pig4cloud.pigx.common.excel.head.HeadMeta;
import com.pig4cloud.pigx.common.excel.head.I18nHeaderCellWriteHandler;
import com.pig4cloud.pigx.common.excel.kit.ExcelException;
import com.pig4cloud.pigx.common.excel.converters.LocalDateStringConverter;
import com.pig4cloud.pigx.common.excel.converters.LocalDateTimeStringConverter;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
@@ -39,12 +39,15 @@ import org.springframework.web.context.request.RequestContextHolder;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Modifier;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
/**
* @author lengleng
@@ -75,12 +78,15 @@ public abstract class AbstractSheetWriteHandler implements SheetWriteHandler, Ap
}
@Override
@SneakyThrows
@SneakyThrows(UnsupportedEncodingException.class)
public void export(Object o, HttpServletResponse response, ResponseExcel responseExcel) {
check(responseExcel);
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
String name = (String) Objects.requireNonNull(requestAttributes).getAttribute(DynamicNameAspect.EXCEL_NAME_KEY,
RequestAttributes.SCOPE_REQUEST);
if (name == null) {
name = UUID.randomUUID().toString();
}
String fileName = String.format("%s%s", URLEncoder.encode(name, "UTF-8"), responseExcel.suffix().getValue());
// 根据实际的文件类型找到对应的 contentType
String contentType = MediaTypeFactory.getMediaType(fileName).map(MediaType::toString)
@@ -97,7 +103,7 @@ public abstract class AbstractSheetWriteHandler implements SheetWriteHandler, Ap
* @param responseExcel ResponseExcel注解
* @return ExcelWriter
*/
@SneakyThrows
@SneakyThrows(IOException.class)
public ExcelWriter getExcelWriter(HttpServletResponse response, ResponseExcel responseExcel) {
ExcelWriterBuilder writerBuilder = EasyExcel.write(response.getOutputStream())
.registerConverter(LocalDateStringConverter.INSTANCE)
@@ -166,7 +172,7 @@ public abstract class AbstractSheetWriteHandler implements SheetWriteHandler, Ap
* @return WriteSheet
*/
public WriteSheet sheet(Sheet sheet, Class<?> dataClass, String template,
Class<? extends HeadGenerator> bookHeadEnhancerClass) {
Class<? extends HeadGenerator> bookHeadEnhancerClass) {
// Sheet 编号和名称
Integer sheetNo = sheet.sheetNo() >= 0 ? sheet.sheetNo() : null;
@@ -216,7 +222,7 @@ public abstract class AbstractSheetWriteHandler implements SheetWriteHandler, Ap
/**
* 是否为Null Head Generator
* @param headGeneratorClass
* @param headGeneratorClass 头生成器类型
* @return true 已指定 false 未指定(默认值)
*/
private boolean isNotInterface(Class<? extends HeadGenerator> headGeneratorClass) {
@@ -1,11 +1,13 @@
package com.pig4cloud.pigx.common.excel.handler;
import com.alibaba.excel.context.AnalysisContext;
import com.pig4cloud.pigx.common.excel.annotation.ExcelLine;
import com.pig4cloud.pigx.common.excel.kit.Validators;
import com.pig4cloud.pigx.common.excel.vo.ErrorMessage;
import lombok.extern.slf4j.Slf4j;
import javax.validation.ConstraintViolation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@@ -38,6 +40,18 @@ public class DefaultAnalysisEventListener extends ListAnalysisEventListener<Obje
errorMessageList.add(new ErrorMessage(lineNum, messageSet));
}
else {
Field[] fields = o.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(ExcelLine.class) && field.getType() == Long.class) {
try {
field.setAccessible(true);
field.set(o, lineNum);
}
catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
list.add(o);
}
}
@@ -3,12 +3,11 @@ package com.pig4cloud.pigx.common.excel.handler;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.excel.annotation.Sheet;
import com.pig4cloud.pigx.common.excel.config.ExcelConfigProperties;
import com.pig4cloud.pigx.common.excel.enhance.WriterBuilderEnhancer;
import com.pig4cloud.pigx.common.excel.kit.ExcelException;
import lombok.SneakyThrows;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.excel.annotation.Sheet;
import org.springframework.beans.factory.ObjectProvider;
import javax.servlet.http.HttpServletResponse;
@@ -22,19 +21,19 @@ import java.util.List;
public class ManySheetWriteHandler extends AbstractSheetWriteHandler {
public ManySheetWriteHandler(ExcelConfigProperties configProperties,
ObjectProvider<List<Converter<?>>> converterProvider, WriterBuilderEnhancer excelWriterBuilderEnhance) {
ObjectProvider<List<Converter<?>>> converterProvider, WriterBuilderEnhancer excelWriterBuilderEnhance) {
super(configProperties, converterProvider, excelWriterBuilderEnhance);
}
/**
* 当且仅当List不为空且List中的元素也是List 才返回true
* @param obj 返回对象
* @return
* @return boolean
*/
@Override
public boolean support(Object obj) {
if (obj instanceof List) {
List objList = (List) obj;
List<?> objList = (List<?>) obj;
return !objList.isEmpty() && objList.get(0) instanceof List;
}
else {
@@ -43,20 +42,25 @@ public class ManySheetWriteHandler extends AbstractSheetWriteHandler {
}
@Override
@SneakyThrows
public void write(Object obj, HttpServletResponse response, ResponseExcel responseExcel) {
List objList = (List) obj;
List<?> objList = (List<?>) obj;
ExcelWriter excelWriter = getExcelWriter(response, responseExcel);
Sheet[] sheets = responseExcel.sheets();
WriteSheet sheet;
for (int i = 0; i < sheets.length; i++) {
List eleList = (List) objList.get(i);
List<?> eleList = (List<?>) objList.get(i);
Class<?> dataClass = eleList.get(0).getClass();
// 创建sheet
sheet = this.sheet(sheets[i], dataClass, responseExcel.template(), responseExcel.headGenerator());
// 写入sheet
excelWriter.write(eleList, sheet);
// 填充 sheet
if (responseExcel.fill()) {
excelWriter.fill(eleList, sheet);
}
else {
// 写入sheet
excelWriter.write(eleList, sheet);
}
}
excelWriter.finish();
}
@@ -3,11 +3,10 @@ package com.pig4cloud.pigx.common.excel.handler;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import com.pig4cloud.pigx.common.excel.config.ExcelConfigProperties;
import com.pig4cloud.pigx.common.excel.enhance.WriterBuilderEnhancer;
import com.pig4cloud.pigx.common.excel.kit.ExcelException;
import lombok.SneakyThrows;
import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel;
import org.springframework.beans.factory.ObjectProvider;
import javax.servlet.http.HttpServletResponse;
@@ -23,19 +22,19 @@ import java.util.List;
public class SingleSheetWriteHandler extends AbstractSheetWriteHandler {
public SingleSheetWriteHandler(ExcelConfigProperties configProperties,
ObjectProvider<List<Converter<?>>> converterProvider, WriterBuilderEnhancer excelWriterBuilderEnhance) {
ObjectProvider<List<Converter<?>>> converterProvider, WriterBuilderEnhancer excelWriterBuilderEnhance) {
super(configProperties, converterProvider, excelWriterBuilderEnhance);
}
/**
* obj 是List 且list不为空同时list中的元素不是是List 才返回true
* @param obj 返回对象
* @return
* @return boolean
*/
@Override
public boolean support(Object obj) {
if (obj instanceof List) {
List objList = (List) obj;
List<?> objList = (List<?>) obj;
return !objList.isEmpty() && !(objList.get(0) instanceof List);
}
else {
@@ -44,16 +43,23 @@ public class SingleSheetWriteHandler extends AbstractSheetWriteHandler {
}
@Override
@SneakyThrows
public void write(Object obj, HttpServletResponse response, ResponseExcel responseExcel) {
List list = (List) obj;
List<?> list = (List<?>) obj;
ExcelWriter excelWriter = getExcelWriter(response, responseExcel);
// 有模板则不指定sheet名
Class<?> dataClass = list.get(0).getClass();
WriteSheet sheet = this.sheet(responseExcel.sheets()[0], dataClass, responseExcel.template(),
responseExcel.headGenerator());
excelWriter.write(list, sheet);
// 填充 sheet
if (responseExcel.fill()) {
excelWriter.fill(list, sheet);
}
else {
// 写入sheet
excelWriter.write(list, sheet);
}
excelWriter.finish();
}
@@ -1,13 +1,11 @@
package com.pig4cloud.pigx.common.excel.head;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
@@ -36,7 +34,7 @@ public class I18nHeaderCellWriteHandler implements CellWriteHandler {
public I18nHeaderCellWriteHandler(MessageSource messageSource) {
this.messageSource = messageSource;
this.placeholderResolver = placeholderName -> messageSource.getMessage(placeholderName, null,
this.placeholderResolver = placeholderName -> this.messageSource.getMessage(placeholderName, null,
LocaleContextHolder.getLocale());
}
@@ -48,7 +46,7 @@ public class I18nHeaderCellWriteHandler implements CellWriteHandler {
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
if (isHead) {
if (isHead != null && isHead) {
List<String> originHeadNameList = head.getHeadNameList();
if (CollectionUtils.isNotEmpty(originHeadNameList)) {
// 国际化处理
@@ -60,22 +58,4 @@ public class I18nHeaderCellWriteHandler implements CellWriteHandler {
}
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,
Head head, Integer relativeRowIndex, Boolean isHead) {
}
@Override
public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
}
@Override
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
}
}
@@ -8,13 +8,16 @@ import java.util.Set;
*
* @author L.cm
*/
public class Validators {
public final class Validators {
private static final Validator validator;
private Validators() {
}
private static final Validator VALIDATOR;
static {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
VALIDATOR = factory.getValidator();
}
/**
@@ -28,7 +31,7 @@ public class Validators {
* validation process
*/
public static <T> Set<ConstraintViolation<T>> validate(T object) {
return validator.validate(object);
return VALIDATOR.validate(object);
}
}
@@ -1,7 +1,9 @@
package com.pig4cloud.pigx.admin.api.vo;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.pig4cloud.pigx.common.excel.annotation.ExcelLine;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@@ -21,6 +23,13 @@ public class PostExcelVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 导入时候回显行号
*/
@ExcelLine
@ExcelIgnore
private Long lineNum;
/**
* 主键ID
*/
@@ -1,7 +1,9 @@
package com.pig4cloud.pigx.admin.api.vo;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.pig4cloud.pigx.common.excel.annotation.ExcelLine;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@@ -20,6 +22,13 @@ public class RoleExcelVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 导入时候回显行号
*/
@ExcelLine
@ExcelIgnore
private Long lineNum;
/**
* 主键ID
*/
@@ -1,7 +1,9 @@
package com.pig4cloud.pigx.admin.api.vo;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.pig4cloud.pigx.common.excel.annotation.ExcelLine;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@@ -20,6 +22,13 @@ public class UserExcelVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 导入时候回显行号
*/
@ExcelLine
@ExcelIgnore
private Long lineNum;
/**
* 主键ID
*/
@@ -60,8 +60,7 @@ public class SysPostServiceImpl extends ServiceImpl<SysPostMapper, SysPost> impl
List<SysPost> postList = this.list();
// 执行数据插入操作 组装 PostDto
for (int i = 0; i < excelVOList.size(); i++) {
PostExcelVO excel = excelVOList.get(i);
for (PostExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验岗位名称或者岗位编码是否存在
boolean existPost = postList.stream().anyMatch(post -> excel.getPostName().equals(post.getPostName())
@@ -78,7 +77,7 @@ public class SysPostServiceImpl extends ServiceImpl<SysPostMapper, SysPost> impl
}
else {
// 数据不合法
errorMessageList.add(new ErrorMessage((long) (i + 2), errorMsg));
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
@@ -118,9 +118,11 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
// 个性化校验逻辑
List<SysRole> roleList = this.list();
for (RoleExcelVO excel : excelVOList) {
}
// 执行数据插入操作 组装 RoleDto
for (int i = 0; i < excelVOList.size(); i++) {
RoleExcelVO excel = excelVOList.get(i);
for (RoleExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验角色名称或者角色编码是否存在
boolean existRole = roleList.stream().anyMatch(sysRole -> excel.getRoleName().equals(sysRole.getRoleName())
@@ -137,7 +139,7 @@ public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> impl
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage((long) (i + 2), errorMsg));
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
@@ -288,8 +288,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
List<SysRole> roleList = sysRoleService.list();
// 执行数据插入操作 组装 UserDto
for (int i = 0; i < excelVOList.size(); i++) {
UserExcelVO excel = excelVOList.get(i);
for (UserExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 校验用户名是否存在
boolean exsitUserName = userList.stream()
@@ -322,7 +321,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage((long) (i + 2), errorMsg));
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
@@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
@@ -48,8 +49,7 @@ public class CustomMagicDesignerAuthorizationInterceptor implements Authorizatio
public boolean allowVisit(MagicUser magicUser, HttpServletRequest request, Authorization authorization) {
String accessToken = extractHeaderToken(request);
if (StrUtil.isBlank(accessToken)) {
return true;
// throw new AccessDeniedException("权限不足");
throw new AccessDeniedException("权限不足");
}
OAuth2Authentication oAuth2Authentication = tokenServices.loadAuthentication(accessToken);