Browse Source

优化读写的写法,方便读写

bugfix
zhuangjiaju 5 years ago
parent
commit
0a0d8a946a
  1. 3
      pom.xml
  2. 8
      src/main/java/com/alibaba/excel/analysis/ExcelExecutor.java
  3. 4
      src/main/java/com/alibaba/excel/analysis/v03/AbstractXlsRecordHandler.java
  4. 45
      src/main/java/com/alibaba/excel/analysis/v03/XlsRecordHandler.java
  5. 12
      src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java
  6. 10
      src/main/java/com/alibaba/excel/analysis/v03/handlers/BlankOrErrorRecordHandler.java
  7. 19
      src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java
  8. 14
      src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java
  9. 8
      src/main/java/com/alibaba/excel/analysis/v03/handlers/LabelRecordHandler.java
  10. 8
      src/main/java/com/alibaba/excel/analysis/v03/handlers/MissingCellDummyRecordHandler.java
  11. 9
      src/main/java/com/alibaba/excel/analysis/v03/handlers/NoteRecordHandler.java
  12. 10
      src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java
  13. 10
      src/main/java/com/alibaba/excel/analysis/v03/handlers/RkRecordHandler.java
  14. 13
      src/main/java/com/alibaba/excel/analysis/v03/handlers/SstRecordHandler.java
  15. 1
      src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java
  16. 22
      src/main/java/com/alibaba/excel/analysis/v07/XlsxCellHandler.java
  17. 23
      src/main/java/com/alibaba/excel/analysis/v07/XlsxRowResultHolder.java
  18. 5
      src/main/java/com/alibaba/excel/analysis/v07/handlers/CountRowCellHandler.java
  19. 6
      src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java
  20. 5
      src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java
  21. 6
      src/main/java/com/alibaba/excel/cache/ReadCache.java
  22. 2
      src/main/java/com/alibaba/excel/context/AnalysisContext.java
  23. 4
      src/main/java/com/alibaba/excel/context/WriteContext.java
  24. 4
      src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java
  25. 39
      src/main/java/com/alibaba/excel/metadata/IndexValue.java
  26. 11
      src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java
  27. 330
      src/main/java/com/alibaba/excel/util/CollectionUtils.java
  28. 9
      src/main/java/com/alibaba/excel/util/FileUtils.java
  29. 945
      src/main/java/com/alibaba/excel/util/ObjectUtils.java
  30. 1310
      src/main/java/com/alibaba/excel/util/StringUtils.java

3
pom.xml

@ -146,6 +146,9 @@
<ruleset>rulesets/java/ali-other.xml</ruleset> <ruleset>rulesets/java/ali-other.xml</ruleset>
<ruleset>rulesets/java/ali-set.xml</ruleset> <ruleset>rulesets/java/ali-set.xml</ruleset>
</rulesets> </rulesets>
<excludes>
<exclude>com/alibaba/excel/event/AnalysisEventListener.java</exclude>
</excludes>
</configuration> </configuration>
<executions> <executions>
<!-- 绑定pmd:check到verify生命周期 --> <!-- 绑定pmd:check到verify生命周期 -->

8
src/main/java/com/alibaba/excel/analysis/ExcelExecutor.java

@ -11,8 +11,16 @@ import com.alibaba.excel.read.metadata.ReadSheet;
*/ */
public interface ExcelExecutor { public interface ExcelExecutor {
/**
* Returns the actual sheet in excel
*
* @return
*/
List<ReadSheet> sheetList(); List<ReadSheet> sheetList();
/**
* Read sheet
*/
void execute(); void execute();
} }

4
src/main/java/com/alibaba/excel/analysis/v03/AbstractXlsRecordHandler.java

@ -1,5 +1,9 @@
package com.alibaba.excel.analysis.v03; package com.alibaba.excel.analysis.v03;
/**
*
* @author Dan Zheng
*/
public abstract class AbstractXlsRecordHandler implements XlsRecordHandler { public abstract class AbstractXlsRecordHandler implements XlsRecordHandler {
protected int row = -1; protected int row = -1;
protected int column = -1; protected int column = -1;

45
src/main/java/com/alibaba/excel/analysis/v03/XlsRecordHandler.java

@ -2,12 +2,57 @@ package com.alibaba.excel.analysis.v03;
import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.Record;
/**
* Intercepts handle xls reads.
*
* @author Dan Zheng
*/
public interface XlsRecordHandler extends Comparable<XlsRecordHandler> { public interface XlsRecordHandler extends Comparable<XlsRecordHandler> {
/**
* Which tags are supported
*
* @param record
* @return
*/
boolean support(Record record); boolean support(Record record);
/**
* Initialize
*/
void init(); void init();
/**
* Processing record
*
* @param record
*/
void processRecord(Record record); void processRecord(Record record);
/**
* Get row
*
* @return
*/
int getRow(); int getRow();
/**
* Get column
*
* @return
*/
int getColumn(); int getColumn();
/**
* Get value
*
* @return
*/
String getValue(); String getValue();
/**
* Get order
*
* @return
*/
int getOrder(); int getOrder();
} }

12
src/main/java/com/alibaba/excel/analysis/v03/XlsSaxAnalyser.java

@ -17,15 +17,15 @@ import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import com.alibaba.excel.analysis.ExcelExecutor; import com.alibaba.excel.analysis.ExcelExecutor;
import com.alibaba.excel.analysis.v03.handlers.BOFRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.BlankOrErrorRecordHandler; import com.alibaba.excel.analysis.v03.handlers.BlankOrErrorRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.BofRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.FormulaRecordHandler; import com.alibaba.excel.analysis.v03.handlers.FormulaRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.LabelRecordHandler; import com.alibaba.excel.analysis.v03.handlers.LabelRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.MissingCellDummyRecordHandler; import com.alibaba.excel.analysis.v03.handlers.MissingCellDummyRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.NoteRecordHandler; import com.alibaba.excel.analysis.v03.handlers.NoteRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.NumberRecordHandler; import com.alibaba.excel.analysis.v03.handlers.NumberRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.RKRecordHandler; import com.alibaba.excel.analysis.v03.handlers.RkRecordHandler;
import com.alibaba.excel.analysis.v03.handlers.SSTRecordHandler; import com.alibaba.excel.analysis.v03.handlers.SstRecordHandler;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.read.listener.event.EachRowAnalysisFinishEvent; import com.alibaba.excel.read.listener.event.EachRowAnalysisFinishEvent;
@ -178,13 +178,13 @@ public class XlsSaxAnalyser implements HSSFListener, ExcelExecutor {
private void buildXlsRecordHandlers() { private void buildXlsRecordHandlers() {
if (CollectionUtils.isEmpty(recordHandlers)) { if (CollectionUtils.isEmpty(recordHandlers)) {
recordHandlers.add(new BlankOrErrorRecordHandler()); recordHandlers.add(new BlankOrErrorRecordHandler());
recordHandlers.add(new BOFRecordHandler(workbookBuildingListener, analysisContext, sheets)); recordHandlers.add(new BofRecordHandler(workbookBuildingListener, analysisContext, sheets));
recordHandlers.add(new FormulaRecordHandler(stubWorkbook, formatListener)); recordHandlers.add(new FormulaRecordHandler(stubWorkbook, formatListener));
recordHandlers.add(new LabelRecordHandler()); recordHandlers.add(new LabelRecordHandler());
recordHandlers.add(new NoteRecordHandler()); recordHandlers.add(new NoteRecordHandler());
recordHandlers.add(new NumberRecordHandler(formatListener)); recordHandlers.add(new NumberRecordHandler(formatListener));
recordHandlers.add(new RKRecordHandler()); recordHandlers.add(new RkRecordHandler());
recordHandlers.add(new SSTRecordHandler()); recordHandlers.add(new SstRecordHandler());
recordHandlers.add(new MissingCellDummyRecordHandler()); recordHandlers.add(new MissingCellDummyRecordHandler());
Collections.sort(recordHandlers); Collections.sort(recordHandlers);
} }

10
src/main/java/com/alibaba/excel/analysis/v03/handlers/BlankOrErrorRecordHandler.java

@ -1,8 +1,16 @@
package com.alibaba.excel.analysis.v03.handlers; package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.BlankRecord;
import org.apache.poi.hssf.record.BoolErrRecord;
import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler; import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import org.apache.poi.hssf.record.*;
/**
* Record handler
*
* @author Dan Zheng
*/
public class BlankOrErrorRecordHandler extends AbstractXlsRecordHandler { public class BlankOrErrorRecordHandler extends AbstractXlsRecordHandler {
@Override @Override

19
src/main/java/com/alibaba/excel/analysis/v03/handlers/BOFRecordHandler.java → src/main/java/com/alibaba/excel/analysis/v03/handlers/BofRecordHandler.java

@ -12,16 +12,21 @@ import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.metadata.ReadSheet; import com.alibaba.excel.read.metadata.ReadSheet;
public class BOFRecordHandler extends AbstractXlsRecordHandler { /**
* Record handler
*
* @author Dan Zheng
*/
public class BofRecordHandler extends AbstractXlsRecordHandler {
private List<BoundSheetRecord> boundSheetRecords = new ArrayList<BoundSheetRecord>(); private List<BoundSheetRecord> boundSheetRecords = new ArrayList<BoundSheetRecord>();
private BoundSheetRecord[] orderedBSRs; private BoundSheetRecord[] orderedBsrs;
private int sheetIndex; private int sheetIndex;
private List<ReadSheet> sheets; private List<ReadSheet> sheets;
private AnalysisContext context; private AnalysisContext context;
private boolean analyAllSheet; private boolean analyAllSheet;
private EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener; private EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener;
public BOFRecordHandler(EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener, public BofRecordHandler(EventWorkbookBuilder.SheetRecordCollectingListener workbookBuildingListener,
AnalysisContext context, List<ReadSheet> sheets) { AnalysisContext context, List<ReadSheet> sheets) {
this.context = context; this.context = context;
this.workbookBuildingListener = workbookBuildingListener; this.workbookBuildingListener = workbookBuildingListener;
@ -40,11 +45,11 @@ public class BOFRecordHandler extends AbstractXlsRecordHandler {
} else if (record.getSid() == BOFRecord.sid) { } else if (record.getSid() == BOFRecord.sid) {
BOFRecord br = (BOFRecord)record; BOFRecord br = (BOFRecord)record;
if (br.getType() == BOFRecord.TYPE_WORKSHEET) { if (br.getType() == BOFRecord.TYPE_WORKSHEET) {
if (orderedBSRs == null) { if (orderedBsrs == null) {
orderedBSRs = BoundSheetRecord.orderByBofPosition(boundSheetRecords); orderedBsrs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);
} }
sheetIndex++; sheetIndex++;
ReadSheet readSheet = new ReadSheet(sheetIndex, orderedBSRs[sheetIndex - 1].getSheetname()); ReadSheet readSheet = new ReadSheet(sheetIndex, orderedBsrs[sheetIndex - 1].getSheetname());
sheets.add(readSheet); sheets.add(readSheet);
if (this.analyAllSheet) { if (this.analyAllSheet) {
context.currentSheet(null, readSheet); context.currentSheet(null, readSheet);
@ -59,7 +64,7 @@ public class BOFRecordHandler extends AbstractXlsRecordHandler {
this.analyAllSheet = true; this.analyAllSheet = true;
} }
sheetIndex = 0; sheetIndex = 0;
orderedBSRs = null; orderedBsrs = null;
boundSheetRecords.clear(); boundSheetRecords.clear();
sheets.clear(); sheets.clear();
} }

14
src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java

@ -1,11 +1,19 @@
package com.alibaba.excel.analysis.v03.handlers; package com.alibaba.excel.analysis.v03.handlers;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
import org.apache.poi.hssf.model.HSSFFormulaParser; import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.record.*; import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.StringRecord;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
/**
* Record handler
*
* @author Dan Zheng
*/
public class FormulaRecordHandler extends AbstractXlsRecordHandler { public class FormulaRecordHandler extends AbstractXlsRecordHandler {
private int nextRow; private int nextRow;
private int nextColumn; private int nextColumn;
@ -16,10 +24,12 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler {
private boolean outputNextStringRecord; private boolean outputNextStringRecord;
private FormatTrackingHSSFListener formatListener; private FormatTrackingHSSFListener formatListener;
private HSSFWorkbook stubWorkbook; private HSSFWorkbook stubWorkbook;
public FormulaRecordHandler(HSSFWorkbook stubWorkbook, FormatTrackingHSSFListener formatListener) { public FormulaRecordHandler(HSSFWorkbook stubWorkbook, FormatTrackingHSSFListener formatListener) {
this.stubWorkbook = stubWorkbook; this.stubWorkbook = stubWorkbook;
this.formatListener = formatListener; this.formatListener = formatListener;
} }
@Override @Override
public boolean support(Record record) { public boolean support(Record record) {
return FormulaRecord.sid == record.getSid() || StringRecord.sid == record.getSid(); return FormulaRecord.sid == record.getSid() || StringRecord.sid == record.getSid();

8
src/main/java/com/alibaba/excel/analysis/v03/handlers/LabelRecordHandler.java

@ -1,9 +1,15 @@
package com.alibaba.excel.analysis.v03.handlers; package com.alibaba.excel.analysis.v03.handlers;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import org.apache.poi.hssf.record.LabelRecord; import org.apache.poi.hssf.record.LabelRecord;
import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
/**
* Record handler
*
* @author Dan Zheng
*/
public class LabelRecordHandler extends AbstractXlsRecordHandler { public class LabelRecordHandler extends AbstractXlsRecordHandler {
@Override @Override
public boolean support(Record record) { public boolean support(Record record) {

8
src/main/java/com/alibaba/excel/analysis/v03/handlers/MissingCellDummyRecordHandler.java

@ -1,9 +1,15 @@
package com.alibaba.excel.analysis.v03.handlers; package com.alibaba.excel.analysis.v03.handlers;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord; import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
/**
* Record handler
*
* @author Dan Zheng
*/
public class MissingCellDummyRecordHandler extends AbstractXlsRecordHandler { public class MissingCellDummyRecordHandler extends AbstractXlsRecordHandler {
@Override @Override
public boolean support(Record record) { public boolean support(Record record) {

9
src/main/java/com/alibaba/excel/analysis/v03/handlers/NoteRecordHandler.java

@ -1,9 +1,15 @@
package com.alibaba.excel.analysis.v03.handlers; package com.alibaba.excel.analysis.v03.handlers;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import org.apache.poi.hssf.record.NoteRecord; import org.apache.poi.hssf.record.NoteRecord;
import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
/**
* Record handler
*
* @author Dan Zheng
*/
public class NoteRecordHandler extends AbstractXlsRecordHandler { public class NoteRecordHandler extends AbstractXlsRecordHandler {
@Override @Override
public boolean support(Record record) { public boolean support(Record record) {
@ -16,7 +22,6 @@ public class NoteRecordHandler extends AbstractXlsRecordHandler {
this.row = nrec.getRow(); this.row = nrec.getRow();
this.column = nrec.getColumn(); this.column = nrec.getColumn();
// TODO: Find object to match nrec.getShapeId()
this.value = "(TODO)"; this.value = "(TODO)";
} }

10
src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java

@ -1,15 +1,23 @@
package com.alibaba.excel.analysis.v03.handlers; package com.alibaba.excel.analysis.v03.handlers;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
import org.apache.poi.hssf.record.NumberRecord; import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.Record;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
/**
* Record handler
*
* @author Dan Zheng
*/
public class NumberRecordHandler extends AbstractXlsRecordHandler { public class NumberRecordHandler extends AbstractXlsRecordHandler {
private FormatTrackingHSSFListener formatListener; private FormatTrackingHSSFListener formatListener;
public NumberRecordHandler(FormatTrackingHSSFListener formatListener) { public NumberRecordHandler(FormatTrackingHSSFListener formatListener) {
this.formatListener = formatListener; this.formatListener = formatListener;
} }
@Override @Override
public boolean support(Record record) { public boolean support(Record record) {
return NumberRecord.sid == record.getSid(); return NumberRecord.sid == record.getSid();

10
src/main/java/com/alibaba/excel/analysis/v03/handlers/RKRecordHandler.java → src/main/java/com/alibaba/excel/analysis/v03/handlers/RkRecordHandler.java

@ -1,10 +1,16 @@
package com.alibaba.excel.analysis.v03.handlers; package com.alibaba.excel.analysis.v03.handlers;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import org.apache.poi.hssf.record.RKRecord; import org.apache.poi.hssf.record.RKRecord;
import org.apache.poi.hssf.record.Record; import org.apache.poi.hssf.record.Record;
public class RKRecordHandler extends AbstractXlsRecordHandler { import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
/**
* Record handler
*
* @author Dan Zheng
*/
public class RkRecordHandler extends AbstractXlsRecordHandler {
@Override @Override
public boolean support(Record record) { public boolean support(Record record) {
return RKRecord.sid == record.getSid(); return RKRecord.sid == record.getSid();

13
src/main/java/com/alibaba/excel/analysis/v03/handlers/SSTRecordHandler.java → src/main/java/com/alibaba/excel/analysis/v03/handlers/SstRecordHandler.java

@ -1,10 +1,19 @@
package com.alibaba.excel.analysis.v03.handlers; package com.alibaba.excel.analysis.v03.handlers;
import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SSTRecord;
import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler; import com.alibaba.excel.analysis.v03.AbstractXlsRecordHandler;
import org.apache.poi.hssf.record.*;
public class SSTRecordHandler extends AbstractXlsRecordHandler { /**
* Record handler
*
* @author Dan Zheng
*/
public class SstRecordHandler extends AbstractXlsRecordHandler {
private SSTRecord sstRecord; private SSTRecord sstRecord;
@Override @Override
public boolean support(Record record) { public boolean support(Record record) {
return SSTRecord.sid == record.getSid() || LabelSSTRecord.sid == record.getSid(); return SSTRecord.sid == record.getSid() || LabelSSTRecord.sid == record.getSid();

1
src/main/java/com/alibaba/excel/analysis/v07/SharedStringsTableHandler.java

@ -12,7 +12,6 @@ import com.alibaba.excel.cache.ReadCache;
public class SharedStringsTableHandler extends DefaultHandler { public class SharedStringsTableHandler extends DefaultHandler {
private static final String T_TAG = "t"; private static final String T_TAG = "t";
private String currentData; private String currentData;
private boolean isT;
private ReadCache readCache; private ReadCache readCache;
public SharedStringsTableHandler(ReadCache readCache) { public SharedStringsTableHandler(ReadCache readCache) {

22
src/main/java/com/alibaba/excel/analysis/v07/XlsxCellHandler.java

@ -2,10 +2,32 @@ package com.alibaba.excel.analysis.v07;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
/**
* Cell handler
*
* @author Dan Zheng
*/
public interface XlsxCellHandler { public interface XlsxCellHandler {
/**
* Which tags are supported
*
* @param name
* @return
*/
boolean support(String name); boolean support(String name);
/**
* Start handle
*
* @param name
* @param attributes
*/
void startHandle(String name, Attributes attributes); void startHandle(String name, Attributes attributes);
/**
* End handle
*
* @param name
*/
void endHandle(String name); void endHandle(String name);
} }

23
src/main/java/com/alibaba/excel/analysis/v07/XlsxRowResultHolder.java

@ -2,12 +2,35 @@ package com.alibaba.excel.analysis.v07;
import com.alibaba.excel.metadata.CellData; import com.alibaba.excel.metadata.CellData;
/**
* Result holder
*
* @author jipengfei
*/
public interface XlsxRowResultHolder { public interface XlsxRowResultHolder {
/**
* Clear Result
*/
void clearResult(); void clearResult();
/**
* Append current 'cellValue'
*
* @param currentCellValue
*/
void appendCurrentCellValue(String currentCellValue); void appendCurrentCellValue(String currentCellValue);
/**
* Get row content
*
* @return
*/
CellData[] getCurRowContent(); CellData[] getCurRowContent();
/**
* get column size
*
* @return
*/
int getColumnSize(); int getColumnSize();
} }

5
src/main/java/com/alibaba/excel/analysis/v07/handlers/CountRowCellHandler.java

@ -8,6 +8,11 @@ import org.xml.sax.Attributes;
import com.alibaba.excel.analysis.v07.XlsxCellHandler; import com.alibaba.excel.analysis.v07.XlsxCellHandler;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
/**
* Cell Handler
*
* @author jipengfei
*/
public class CountRowCellHandler implements XlsxCellHandler { public class CountRowCellHandler implements XlsxCellHandler {
private final AnalysisContext analysisContext; private final AnalysisContext analysisContext;

6
src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java

@ -21,7 +21,11 @@ import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.util.BooleanUtils; import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.util.PositionUtils; import com.alibaba.excel.util.PositionUtils;
import com.alibaba.excel.util.StringUtils; import com.alibaba.excel.util.StringUtils;
/**
* Cell Handler
*
* @author jipengfei
*/
public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder { public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder {
private final AnalysisContext analysisContext; private final AnalysisContext analysisContext;
private String currentTag; private String currentTag;

5
src/main/java/com/alibaba/excel/analysis/v07/handlers/ProcessResultCellHandler.java

@ -9,6 +9,11 @@ import com.alibaba.excel.analysis.v07.XlsxRowResultHolder;
import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.event.EachRowAnalysisFinishEvent; import com.alibaba.excel.read.listener.event.EachRowAnalysisFinishEvent;
/**
* Cell Handler
*
* @author jipengfei
*/
public class ProcessResultCellHandler implements XlsxCellHandler { public class ProcessResultCellHandler implements XlsxCellHandler {
private AnalysisContext analysisContext; private AnalysisContext analysisContext;
private XlsxRowResultHolder rowResultHandler; private XlsxRowResultHolder rowResultHandler;

6
src/main/java/com/alibaba/excel/cache/ReadCache.java vendored

@ -24,7 +24,7 @@ public interface ReadCache {
void put(String value); void put(String value);
/** /**
* Get * Get value
* *
* @param key * @param key
* @return * @return
@ -32,12 +32,12 @@ public interface ReadCache {
String get(Integer key); String get(Integer key);
/** /**
* 所有 * It's called when all the values are put in
*/ */
void putFinished(); void putFinished();
/** /**
* * Called when the excel read is complete
*/ */
void destroy(); void destroy();

2
src/main/java/com/alibaba/excel/context/AnalysisContext.java

@ -64,6 +64,8 @@ public interface AnalysisContext {
/** /**
* Custom attribute * Custom attribute
*
* @return
*/ */
Object getCustom(); Object getCustom();

4
src/main/java/com/alibaba/excel/context/WriteContext.java

@ -67,6 +67,7 @@ public interface WriteContext {
void finish(); void finish();
/** /**
* Current sheet
* *
* @return * @return
* @deprecated please us e{@link #writeSheetHolder()} * @deprecated please us e{@link #writeSheetHolder()}
@ -75,6 +76,7 @@ public interface WriteContext {
Sheet getCurrentSheet(); Sheet getCurrentSheet();
/** /**
* Need head
* *
* @return * @return
* @deprecated please us e{@link #writeSheetHolder()} * @deprecated please us e{@link #writeSheetHolder()}
@ -83,6 +85,7 @@ public interface WriteContext {
boolean needHead(); boolean needHead();
/** /**
* Get outputStream
* *
* @return * @return
* @deprecated please us e{@link #writeWorkbookHolder()} ()} * @deprecated please us e{@link #writeWorkbookHolder()} ()}
@ -91,6 +94,7 @@ public interface WriteContext {
OutputStream getOutputStream(); OutputStream getOutputStream();
/** /**
* Get workbook
* *
* @return * @return
* @deprecated please us e{@link #writeWorkbookHolder()} ()} * @deprecated please us e{@link #writeWorkbookHolder()} ()}

4
src/main/java/com/alibaba/excel/converters/DefaultConverterLoader.java

@ -40,7 +40,7 @@ public class DefaultConverterLoader {
* @return * @return
*/ */
public static Map<String, Converter> loadDefaultWriteConverter() { public static Map<String, Converter> loadDefaultWriteConverter() {
Map<String, Converter> converterMap = new HashMap<String, Converter>(); Map<String, Converter> converterMap = new HashMap<String, Converter>(16);
putWriteConverter(converterMap, new BigDecimalNumberConverter()); putWriteConverter(converterMap, new BigDecimalNumberConverter());
putWriteConverter(converterMap, new BooleanBooleanConverter()); putWriteConverter(converterMap, new BooleanBooleanConverter());
putWriteConverter(converterMap, new ByteNumberConverter()); putWriteConverter(converterMap, new ByteNumberConverter());
@ -64,7 +64,7 @@ public class DefaultConverterLoader {
* @return * @return
*/ */
public static Map<String, Converter> loadDefaultReadConverter() { public static Map<String, Converter> loadDefaultReadConverter() {
Map<String, Converter> converterMap = new HashMap<String, Converter>(); Map<String, Converter> converterMap = new HashMap<String, Converter>(64);
putReadConverter(converterMap, new BigDecimalBooleanConverter()); putReadConverter(converterMap, new BigDecimalBooleanConverter());
putReadConverter(converterMap, new BigDecimalNumberConverter()); putReadConverter(converterMap, new BigDecimalNumberConverter());
putReadConverter(converterMap, new BigDecimalStringConverter()); putReadConverter(converterMap, new BigDecimalStringConverter());

39
src/main/java/com/alibaba/excel/metadata/IndexValue.java

@ -1,39 +0,0 @@
package com.alibaba.excel.metadata;
/**
* @author jipengfei
*/
public class IndexValue {
private String v_index;
private String v_value;
public IndexValue(String v_index, String v_value) {
super();
this.v_index = v_index;
this.v_value = v_value;
}
public String getV_index() {
return v_index;
}
public void setV_index(String v_index) {
this.v_index = v_index;
}
public String getV_value() {
return v_value;
}
public void setV_value(String v_value) {
this.v_value = v_value;
}
@Override
public String toString() {
return "IndexValue [v_index=" + v_index + ", v_value=" + v_value + "]";
}
}

11
src/main/java/com/alibaba/excel/support/ExcelTypeEnum.java

@ -32,6 +32,17 @@ public enum ExcelTypeEnum {
FileMagic fileMagic = null; FileMagic fileMagic = null;
if (file != null) { if (file != null) {
fileMagic = FileMagic.valueOf(file); fileMagic = FileMagic.valueOf(file);
if (!FileMagic.OLE2.equals(fileMagic) && !FileMagic.OOXML.equals(fileMagic)) {
String fileName = file.getName();
if (fileName.endsWith(XLSX.getValue())) {
return XLSX;
} else if (fileName.endsWith(XLS.getValue())) {
return XLS;
} else {
throw new ExcelCommonException("Unknown excel type.");
}
}
} else { } else {
fileMagic = FileMagic.valueOf(inputStream); fileMagic = FileMagic.valueOf(inputStream);
} }

330
src/main/java/com/alibaba/excel/util/CollectionUtils.java

@ -1,340 +1,20 @@
package com.alibaba.excel.util; package com.alibaba.excel.util;
import java.util.*; import java.util.Collection;
import java.util.Map;
/** /**
* Miscellaneous collection utility methods. * Collection utils
* Mainly for internal use within the framework.
* *
* @author Juergen Hoeller * @author jipengfei
* @author Rob Harrop
* @author Arjen Poutsma
* @since 1.1.3
*/ */
public abstract class CollectionUtils { public class CollectionUtils {
/**
* Return {@code true} if the supplied Collection is {@code null} or empty.
* Otherwise, return {@code false}.
* @param collection the Collection to check
* @return whether the given Collection is empty
*/
public static boolean isEmpty(Collection<?> collection) { public static boolean isEmpty(Collection<?> collection) {
return (collection == null || collection.isEmpty()); return (collection == null || collection.isEmpty());
} }
/**
* Return {@code true} if the supplied Map is {@code null} or empty.
* Otherwise, return {@code false}.
* @param map the Map to check
* @return whether the given Map is empty
*/
public static boolean isEmpty(Map<?, ?> map) { public static boolean isEmpty(Map<?, ?> map) {
return (map == null || map.isEmpty()); return (map == null || map.isEmpty());
} }
/**
* Convert the supplied array into a List. A primitive array gets converted
* into a List of the appropriate wrapper type.
* <p><b>NOTE:</b> Generally prefer the standard {@link Arrays#asList} method.
* This {@code arrayToList} method is just meant to deal with an incoming Object
* value that might be an {@code Object[]} or a primitive array at runtime.
* <p>A {@code null} source value will be converted to an empty List.
* @param source the (potentially primitive) array
* @return the converted List result
* @see ObjectUtils#toObjectArray(Object)
* @see Arrays#asList(Object[])
*/
@SuppressWarnings("rawtypes")
public static List arrayToList(Object source) {
return Arrays.asList(ObjectUtils.toObjectArray(source));
}
/**
* Merge the given array into the given Collection.
* @param array the array to merge (may be {@code null})
* @param collection the target Collection to merge the array into
*/
@SuppressWarnings("unchecked")
public static <E> void mergeArrayIntoCollection(Object array, Collection<E> collection) {
if (collection == null) {
throw new IllegalArgumentException("Collection must not be null");
}
Object[] arr = ObjectUtils.toObjectArray(array);
for (Object elem : arr) {
collection.add((E) elem);
}
}
/**
* Merge the given Properties instance into the given Map,
* copying all properties (key-value pairs) over.
* <p>Uses {@code Properties.propertyNames()} to even catch
* default properties linked into the original Properties instance.
* @param props the Properties instance to merge (may be {@code null})
* @param map the target Map to merge the properties into
*/
@SuppressWarnings("unchecked")
public static <K, V> void mergePropertiesIntoMap(Properties props, Map<K, V> map) {
if (map == null) {
throw new IllegalArgumentException("Map must not be null");
}
if (props != null) {
for (Enumeration<?> en = props.propertyNames(); en.hasMoreElements();) {
String key = (String) en.nextElement();
Object value = props.get(key);
if (value == null) {
// Allow for defaults fallback or potentially overridden accessor...
value = props.getProperty(key);
}
map.put((K) key, (V) value);
} }
}
}
/**
* Check whether the given Iterator contains the given element.
* @param iterator the Iterator to check
* @param element the element to look for
* @return {@code true} if found, {@code false} else
*/
public static boolean contains(Iterator<?> iterator, Object element) {
if (iterator != null) {
while (iterator.hasNext()) {
Object candidate = iterator.next();
if (ObjectUtils.nullSafeEquals(candidate, element)) {
return true;
}
}
}
return false;
}
/**
* Check whether the given Enumeration contains the given element.
* @param enumeration the Enumeration to check
* @param element the element to look for
* @return {@code true} if found, {@code false} else
*/
public static boolean contains(Enumeration<?> enumeration, Object element) {
if (enumeration != null) {
while (enumeration.hasMoreElements()) {
Object candidate = enumeration.nextElement();
if (ObjectUtils.nullSafeEquals(candidate, element)) {
return true;
}
}
}
return false;
}
/**
* Check whether the given Collection contains the given element instance.
* <p>Enforces the given instance to be present, rather than returning
* {@code true} for an equal element as well.
* @param collection the Collection to check
* @param element the element to look for
* @return {@code true} if found, {@code false} else
*/
public static boolean containsInstance(Collection<?> collection, Object element) {
if (collection != null) {
for (Object candidate : collection) {
if (candidate == element) {
return true;
}
}
}
return false;
}
/**
* Return {@code true} if any element in '{@code candidates}' is
* contained in '{@code source}'; otherwise returns {@code false}.
* @param source the source Collection
* @param candidates the candidates to search for
* @return whether any of the candidates has been found
*/
public static boolean containsAny(Collection<?> source, Collection<?> candidates) {
if (isEmpty(source) || isEmpty(candidates)) {
return false;
}
for (Object candidate : candidates) {
if (source.contains(candidate)) {
return true;
}
}
return false;
}
/**
* Return the first element in '{@code candidates}' that is contained in
* '{@code source}'. If no element in '{@code candidates}' is present in
* '{@code source}' returns {@code null}. Iteration order is
* {@link Collection} implementation specific.
* @param source the source Collection
* @param candidates the candidates to search for
* @return the first present object, or {@code null} if not found
*/
@SuppressWarnings("unchecked")
public static <E> E findFirstMatch(Collection<?> source, Collection<E> candidates) {
if (isEmpty(source) || isEmpty(candidates)) {
return null;
}
for (Object candidate : candidates) {
if (source.contains(candidate)) {
return (E) candidate;
}
}
return null;
}
/**
* Find a single value of the given type in the given Collection.
* @param collection the Collection to search
* @param type the type to look for
* @return a value of the given type found if there is a clear match,
* or {@code null} if none or more than one such value found
*/
@SuppressWarnings("unchecked")
public static <T> T findValueOfType(Collection<?> collection, Class<T> type) {
if (isEmpty(collection)) {
return null;
}
T value = null;
for (Object element : collection) {
if (type == null || type.isInstance(element)) {
if (value != null) {
// More than one value found... no clear single value.
return null;
}
value = (T) element;
}
}
return value;
}
/**
* Find a single value of one of the given types in the given Collection:
* searching the Collection for a value of the first type, then
* searching for a value of the second type, etc.
* @param collection the collection to search
* @param types the types to look for, in prioritized order
* @return a value of one of the given types found if there is a clear match,
* or {@code null} if none or more than one such value found
*/
public static Object findValueOfType(Collection<?> collection, Class<?>[] types) {
if (isEmpty(collection) || ObjectUtils.isEmpty(types)) {
return null;
}
for (Class<?> type : types) {
Object value = findValueOfType(collection, type);
if (value != null) {
return value;
}
}
return null;
}
/**
* Determine whether the given Collection only contains a single unique object.
* @param collection the Collection to check
* @return {@code true} if the collection contains a single reference or
* multiple references to the same instance, {@code false} else
*/
public static boolean hasUniqueObject(Collection<?> collection) {
if (isEmpty(collection)) {
return false;
}
boolean hasCandidate = false;
Object candidate = null;
for (Object elem : collection) {
if (!hasCandidate) {
hasCandidate = true;
candidate = elem;
}
else if (candidate != elem) {
return false;
}
}
return true;
}
/**
* Find the common element type of the given Collection, if any.
* @param collection the Collection to check
* @return the common element type, or {@code null} if no clear
* common type has been found (or the collection was empty)
*/
public static Class<?> findCommonElementType(Collection<?> collection) {
if (isEmpty(collection)) {
return null;
}
Class<?> candidate = null;
for (Object val : collection) {
if (val != null) {
if (candidate == null) {
candidate = val.getClass();
}
else if (candidate != val.getClass()) {
return null;
}
}
}
return candidate;
}
/**
* Marshal the elements from the given enumeration into an array of the given type.
* Enumeration elements must be assignable to the type of the given array. The array
* returned will be a different instance than the array given.
*/
public static <A, E extends A> A[] toArray(Enumeration<E> enumeration, A[] array) {
ArrayList<A> elements = new ArrayList<A>();
while (enumeration.hasMoreElements()) {
elements.add(enumeration.nextElement());
}
return elements.toArray(array);
}
/**
* Adapt an enumeration to an iterator.
* @param enumeration the enumeration
* @return the iterator
*/
public static <E> Iterator<E> toIterator(Enumeration<E> enumeration) {
return new EnumerationIterator<E>(enumeration);
}
/**
* Iterator wrapping an Enumeration.
*/
private static class EnumerationIterator<E> implements Iterator<E> {
private final Enumeration<E> enumeration;
public EnumerationIterator(Enumeration<E> enumeration) {
this.enumeration = enumeration;
}
@Override
public boolean hasNext() {
return this.enumeration.hasMoreElements();
}
@Override
public E next() {
return this.enumeration.nextElement();
}
@Override
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException("Not supported");
}
}
}

9
src/main/java/com/alibaba/excel/util/FileUtils.java

@ -20,6 +20,7 @@ public class FileUtils {
private static final String POIFILES = "poifiles"; private static final String POIFILES = "poifiles";
private static final String CACHE = "excache"; private static final String CACHE = "excache";
private static final int WRITE_BUFF_SIZE = 8192;
/** /**
* Write inputStream to file * Write inputStream to file
@ -32,8 +33,8 @@ public class FileUtils {
try { try {
outputStream = new FileOutputStream(file); outputStream = new FileOutputStream(file);
int bytesRead; int bytesRead;
byte[] buffer = new byte[8192]; byte[] buffer = new byte[WRITE_BUFF_SIZE];
while ((bytesRead = inputStream.read(buffer, 0, 8192)) != -1) { while ((bytesRead = inputStream.read(buffer, 0, WRITE_BUFF_SIZE)) != -1) {
outputStream.write(buffer, 0, bytesRead); outputStream.write(buffer, 0, bytesRead);
} }
} catch (Exception e) { } catch (Exception e) {
@ -98,7 +99,7 @@ public class FileUtils {
} }
File directory = new File(tmpDir, path); File directory = new File(tmpDir, path);
if (!directory.exists()) { if (!directory.exists()) {
syncCreatePOIFilesDirectory(directory); syncCreatePoiFilesDirectory(directory);
} }
return directory; return directory;
} }
@ -107,7 +108,7 @@ public class FileUtils {
* *
* @param directory * @param directory
*/ */
private static synchronized void syncCreatePOIFilesDirectory(File directory) { private static synchronized void syncCreatePoiFilesDirectory(File directory) {
if (!directory.exists()) { if (!directory.exists()) {
directory.mkdirs(); directory.mkdirs();
} }

945
src/main/java/com/alibaba/excel/util/ObjectUtils.java

@ -1,945 +0,0 @@
package com.alibaba.excel.util;
/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
/**
* Miscellaneous object utility methods.
*
* <p>Mainly for internal use within the framework.
*
* <p>Thanks to Alex Ruiz for contributing several enhancements to this class!
*
* @author Juergen Hoeller
* @author Keith Donald
* @author Rod Johnson
* @author Rob Harrop
* @author Chris Beams
* @author Sam Brannen
* @since 19.03.2004
* @see CollectionUtils
*/
public abstract class ObjectUtils {
private static final int INITIAL_HASH = 7;
private static final int MULTIPLIER = 31;
private static final String EMPTY_STRING = "";
private static final String NULL_STRING = "null";
private static final String ARRAY_START = "{";
private static final String ARRAY_END = "}";
private static final String EMPTY_ARRAY = ARRAY_START + ARRAY_END;
private static final String ARRAY_ELEMENT_SEPARATOR = ", ";
/**
* Return whether the given throwable is a checked exception:
* that is, neither a RuntimeException nor an Error.
* @param ex the throwable to check
* @return whether the throwable is a checked exception
* @see Exception
* @see RuntimeException
* @see Error
*/
public static boolean isCheckedException(Throwable ex) {
return !(ex instanceof RuntimeException || ex instanceof Error);
}
/**
* Check whether the given exception is compatible with the specified
* exception types, as declared in a throws clause.
* @param ex the exception to check
* @param declaredExceptions the exception types declared in the throws clause
* @return whether the given exception is compatible
*/
public static boolean isCompatibleWithThrowsClause(Throwable ex, Class<?>... declaredExceptions) {
if (!isCheckedException(ex)) {
return true;
}
if (declaredExceptions != null) {
for (Class<?> declaredException : declaredExceptions) {
if (declaredException.isInstance(ex)) {
return true;
}
}
}
return false;
}
/**
* Determine whether the given object is an array:
* either an Object array or a primitive array.
* @param obj the object to check
*/
public static boolean isArray(Object obj) {
return (obj != null && obj.getClass().isArray());
}
/**
* Determine whether the given array is empty:
* i.e. {@code null} or of zero length.
* @param array the array to check
* @see #isEmpty(Object)
*/
public static boolean isEmpty(Object[] array) {
return (array == null || array.length == 0);
}
/**
* Determine whether the given object is empty.
* <p>This method supports the following object types.
* <ul>
* <li>{@code Array}: considered empty if its length is zero</li>
* <li>{@link CharSequence}: considered empty if its length is zero</li>
* <li>{@link Collection}: delegates to {@link Collection#isEmpty()}</li>
* <li>{@link Map}: delegates to {@link Map#isEmpty()}</li>
* </ul>
* <p>If the given object is non-null and not one of the aforementioned
* supported types, this method returns {@code false}.
* @param obj the object to check
* @return {@code true} if the object is {@code null} or <em>empty</em>
* @since 4.2
* @see ObjectUtils#isEmpty(Object[])
* @see StringUtils#hasLength(CharSequence)
* @see StringUtils#isEmpty(Object)
* @see CollectionUtils#isEmpty(Collection)
* @see CollectionUtils#isEmpty(Map)
*/
@SuppressWarnings("rawtypes")
public static boolean isEmpty(Object obj) {
if (obj == null) {
return true;
}
if (obj instanceof CharSequence) {
return ((CharSequence) obj).length() == 0;
}
if (obj.getClass().isArray()) {
return Array.getLength(obj) == 0;
}
if (obj instanceof Collection) {
return ((Collection) obj).isEmpty();
}
if (obj instanceof Map) {
return ((Map) obj).isEmpty();
}
// else
return false;
}
/**
* Check whether the given array contains the given element.
* @param array the array to check (may be {@code null},
* in which case the return value will always be {@code false})
* @param element the element to check for
* @return whether the element has been found in the given array
*/
public static boolean containsElement(Object[] array, Object element) {
if (array == null) {
return false;
}
for (Object arrayEle : array) {
if (nullSafeEquals(arrayEle, element)) {
return true;
}
}
return false;
}
/**
* Check whether the given array of enum constants contains a constant with the given name,
* ignoring case when determining a match.
* @param enumValues the enum values to check, typically the product of a call to MyEnum.values()
* @param constant the constant name to find (must not be null or empty string)
* @return whether the constant has been found in the given array
*/
public static boolean containsConstant(Enum<?>[] enumValues, String constant) {
return containsConstant(enumValues, constant, false);
}
/**
* Check whether the given array of enum constants contains a constant with the given name.
* @param enumValues the enum values to check, typically the product of a call to MyEnum.values()
* @param constant the constant name to find (must not be null or empty string)
* @param caseSensitive whether case is significant in determining a match
* @return whether the constant has been found in the given array
*/
public static boolean containsConstant(Enum<?>[] enumValues, String constant, boolean caseSensitive) {
for (Enum<?> candidate : enumValues) {
if (caseSensitive ?
candidate.toString().equals(constant) :
candidate.toString().equalsIgnoreCase(constant)) {
return true;
}
}
return false;
}
/**
* Case insensitive alternative to {@link Enum#valueOf(Class, String)}.
* @param <E> the concrete Enum type
* @param enumValues the array of all Enum constants in question, usually per Enum.values()
* @param constant the constant to get the enum value of
* @throws IllegalArgumentException if the given constant is not found in the given array
* of enum values. Use {@link #containsConstant(Enum[], String)} as a guard to avoid this exception.
*/
public static <E extends Enum<?>> E caseInsensitiveValueOf(E[] enumValues, String constant) {
for (E candidate : enumValues) {
if (candidate.toString().equalsIgnoreCase(constant)) {
return candidate;
}
}
throw new IllegalArgumentException(
String.format("constant [%s] does not exist in enum type %s",
constant, enumValues.getClass().getComponentType().getName()));
}
/**
* Append the given object to the given array, returning a new array
* consisting of the input array contents plus the given object.
* @param array the array to append to (can be {@code null})
* @param obj the object to append
* @return the new array (of the same component type; never {@code null})
*/
public static <A, O extends A> A[] addObjectToArray(A[] array, O obj) {
Class<?> compType = Object.class;
if (array != null) {
compType = array.getClass().getComponentType();
}
else if (obj != null) {
compType = obj.getClass();
}
int newArrLength = (array != null ? array.length + 1 : 1);
@SuppressWarnings("unchecked")
A[] newArr = (A[]) Array.newInstance(compType, newArrLength);
if (array != null) {
System.arraycopy(array, 0, newArr, 0, array.length);
}
newArr[newArr.length - 1] = obj;
return newArr;
}
/**
* Convert the given array (which may be a primitive array) to an
* object array (if necessary of primitive wrapper objects).
* <p>A {@code null} source value will be converted to an
* empty Object array.
* @param source the (potentially primitive) array
* @return the corresponding object array (never {@code null})
* @throws IllegalArgumentException if the parameter is not an array
*/
public static Object[] toObjectArray(Object source) {
if (source instanceof Object[]) {
return (Object[]) source;
}
if (source == null) {
return new Object[0];
}
if (!source.getClass().isArray()) {
throw new IllegalArgumentException("Source is not an array: " + source);
}
int length = Array.getLength(source);
if (length == 0) {
return new Object[0];
}
Class<?> wrapperType = Array.get(source, 0).getClass();
Object[] newArray = (Object[]) Array.newInstance(wrapperType, length);
for (int i = 0; i < length; i++) {
newArray[i] = Array.get(source, i);
}
return newArray;
}
//---------------------------------------------------------------------
// Convenience methods for content-based equality/hash-code handling
//---------------------------------------------------------------------
/**
* Determine if the given objects are equal, returning {@code true} if
* both are {@code null} or {@code false} if only one is {@code null}.
* <p>Compares arrays with {@code Arrays.equals}, performing an equality
* check based on the array elements rather than the array reference.
* @param o1 first Object to compare
* @param o2 second Object to compare
* @return whether the given objects are equal
* @see Object#equals(Object)
* @see Arrays#equals
*/
public static boolean nullSafeEquals(Object o1, Object o2) {
if (o1 == o2) {
return true;
}
if (o1 == null || o2 == null) {
return false;
}
if (o1.equals(o2)) {
return true;
}
if (o1.getClass().isArray() && o2.getClass().isArray()) {
return arrayEquals(o1, o2);
}
return false;
}
/**
* Compare the given arrays with {@code Arrays.equals}, performing an equality
* check based on the array elements rather than the array reference.
* @param o1 first array to compare
* @param o2 second array to compare
* @return whether the given objects are equal
* @see #nullSafeEquals(Object, Object)
* @see Arrays#equals
*/
private static boolean arrayEquals(Object o1, Object o2) {
if (o1 instanceof Object[] && o2 instanceof Object[]) {
return Arrays.equals((Object[]) o1, (Object[]) o2);
}
if (o1 instanceof boolean[] && o2 instanceof boolean[]) {
return Arrays.equals((boolean[]) o1, (boolean[]) o2);
}
if (o1 instanceof byte[] && o2 instanceof byte[]) {
return Arrays.equals((byte[]) o1, (byte[]) o2);
}
if (o1 instanceof char[] && o2 instanceof char[]) {
return Arrays.equals((char[]) o1, (char[]) o2);
}
if (o1 instanceof double[] && o2 instanceof double[]) {
return Arrays.equals((double[]) o1, (double[]) o2);
}
if (o1 instanceof float[] && o2 instanceof float[]) {
return Arrays.equals((float[]) o1, (float[]) o2);
}
if (o1 instanceof int[] && o2 instanceof int[]) {
return Arrays.equals((int[]) o1, (int[]) o2);
}
if (o1 instanceof long[] && o2 instanceof long[]) {
return Arrays.equals((long[]) o1, (long[]) o2);
}
if (o1 instanceof short[] && o2 instanceof short[]) {
return Arrays.equals((short[]) o1, (short[]) o2);
}
return false;
}
/**
* Return as hash code for the given object; typically the value of
* {@code Object#hashCode()}}. If the object is an array,
* this method will delegate to any of the {@code nullSafeHashCode}
* methods for arrays in this class. If the object is {@code null},
* this method returns 0.
* @see Object#hashCode()
* @see #nullSafeHashCode(Object[])
* @see #nullSafeHashCode(boolean[])
* @see #nullSafeHashCode(byte[])
* @see #nullSafeHashCode(char[])
* @see #nullSafeHashCode(double[])
* @see #nullSafeHashCode(float[])
* @see #nullSafeHashCode(int[])
* @see #nullSafeHashCode(long[])
* @see #nullSafeHashCode(short[])
*/
public static int nullSafeHashCode(Object obj) {
if (obj == null) {
return 0;
}
if (obj.getClass().isArray()) {
if (obj instanceof Object[]) {
return nullSafeHashCode((Object[]) obj);
}
if (obj instanceof boolean[]) {
return nullSafeHashCode((boolean[]) obj);
}
if (obj instanceof byte[]) {
return nullSafeHashCode((byte[]) obj);
}
if (obj instanceof char[]) {
return nullSafeHashCode((char[]) obj);
}
if (obj instanceof double[]) {
return nullSafeHashCode((double[]) obj);
}
if (obj instanceof float[]) {
return nullSafeHashCode((float[]) obj);
}
if (obj instanceof int[]) {
return nullSafeHashCode((int[]) obj);
}
if (obj instanceof long[]) {
return nullSafeHashCode((long[]) obj);
}
if (obj instanceof short[]) {
return nullSafeHashCode((short[]) obj);
}
}
return obj.hashCode();
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(Object[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (Object element : array) {
hash = MULTIPLIER * hash + nullSafeHashCode(element);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(boolean[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (boolean element : array) {
hash = MULTIPLIER * hash + hashCode(element);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(byte[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (byte element : array) {
hash = MULTIPLIER * hash + element;
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(char[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (char element : array) {
hash = MULTIPLIER * hash + element;
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(double[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (double element : array) {
hash = MULTIPLIER * hash + hashCode(element);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(float[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (float element : array) {
hash = MULTIPLIER * hash + hashCode(element);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(int[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (int element : array) {
hash = MULTIPLIER * hash + element;
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(long[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (long element : array) {
hash = MULTIPLIER * hash + hashCode(element);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(short[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (short element : array) {
hash = MULTIPLIER * hash + element;
}
return hash;
}
/**
* Return the same value as {@link Boolean#hashCode()}}.
* @see Boolean#hashCode()
*/
public static int hashCode(boolean bool) {
return (bool ? 1231 : 1237);
}
/**
* Return the same value as {@link Double#hashCode()}}.
* @see Double#hashCode()
*/
public static int hashCode(double dbl) {
return hashCode(Double.doubleToLongBits(dbl));
}
/**
* Return the same value as {@link Float#hashCode()}}.
* @see Float#hashCode()
*/
public static int hashCode(float flt) {
return Float.floatToIntBits(flt);
}
/**
* Return the same value as {@link Long#hashCode()}}.
* @see Long#hashCode()
*/
public static int hashCode(long lng) {
return (int) (lng ^ (lng >>> 32));
}
//---------------------------------------------------------------------
// Convenience methods for toString output
//---------------------------------------------------------------------
/**
* Return a String representation of an object's overall identity.
* @param obj the object (may be {@code null})
* @return the object's identity as String representation,
* or an empty String if the object was {@code null}
*/
public static String identityToString(Object obj) {
if (obj == null) {
return EMPTY_STRING;
}
return obj.getClass().getName() + "@" + getIdentityHexString(obj);
}
/**
* Return a hex String form of an object's identity hash code.
* @param obj the object
* @return the object's identity code in hex notation
*/
public static String getIdentityHexString(Object obj) {
return Integer.toHexString(System.identityHashCode(obj));
}
/**
* Return a content-based String representation if {@code obj} is
* not {@code null}; otherwise returns an empty String.
* <p>Differs from {@link #nullSafeToString(Object)} in that it returns
* an empty String rather than "null" for a {@code null} value.
* @param obj the object to build a display String for
* @return a display String representation of {@code obj}
* @see #nullSafeToString(Object)
*/
public static String getDisplayString(Object obj) {
if (obj == null) {
return EMPTY_STRING;
}
return nullSafeToString(obj);
}
/**
* Determine the class name for the given object.
* <p>Returns {@code "null"} if {@code obj} is {@code null}.
* @param obj the object to introspect (may be {@code null})
* @return the corresponding class name
*/
public static String nullSafeClassName(Object obj) {
return (obj != null ? obj.getClass().getName() : NULL_STRING);
}
/**
* Return a String representation of the specified Object.
* <p>Builds a String representation of the contents in case of an array.
* Returns {@code "null"} if {@code obj} is {@code null}.
* @param obj the object to build a String representation for
* @return a String representation of {@code obj}
*/
public static String nullSafeToString(Object obj) {
if (obj == null) {
return NULL_STRING;
}
if (obj instanceof String) {
return (String) obj;
}
if (obj instanceof Object[]) {
return nullSafeToString((Object[]) obj);
}
if (obj instanceof boolean[]) {
return nullSafeToString((boolean[]) obj);
}
if (obj instanceof byte[]) {
return nullSafeToString((byte[]) obj);
}
if (obj instanceof char[]) {
return nullSafeToString((char[]) obj);
}
if (obj instanceof double[]) {
return nullSafeToString((double[]) obj);
}
if (obj instanceof float[]) {
return nullSafeToString((float[]) obj);
}
if (obj instanceof int[]) {
return nullSafeToString((int[]) obj);
}
if (obj instanceof long[]) {
return nullSafeToString((long[]) obj);
}
if (obj instanceof short[]) {
return nullSafeToString((short[]) obj);
}
String str = obj.toString();
return (str != null ? str : EMPTY_STRING);
}
/**
* Return a String representation of the contents of the specified array.
* <p>The String representation consists of a list of the array's elements,
* enclosed in curly braces ({@code "{}"}). Adjacent elements are separated
* by the characters {@code ", "} (a comma followed by a space). Returns
* {@code "null"} if {@code array} is {@code null}.
* @param array the array to build a String representation for
* @return a String representation of {@code array}
*/
public static String nullSafeToString(Object[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
}
else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(String.valueOf(array[i]));
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>The String representation consists of a list of the array's elements,
* enclosed in curly braces ({@code "{}"}). Adjacent elements are separated
* by the characters {@code ", "} (a comma followed by a space). Returns
* {@code "null"} if {@code array} is {@code null}.
* @param array the array to build a String representation for
* @return a String representation of {@code array}
*/
public static String nullSafeToString(boolean[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
}
else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>The String representation consists of a list of the array's elements,
* enclosed in curly braces ({@code "{}"}). Adjacent elements are separated
* by the characters {@code ", "} (a comma followed by a space). Returns
* {@code "null"} if {@code array} is {@code null}.
* @param array the array to build a String representation for
* @return a String representation of {@code array}
*/
public static String nullSafeToString(byte[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
}
else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>The String representation consists of a list of the array's elements,
* enclosed in curly braces ({@code "{}"}). Adjacent elements are separated
* by the characters {@code ", "} (a comma followed by a space). Returns
* {@code "null"} if {@code array} is {@code null}.
* @param array the array to build a String representation for
* @return a String representation of {@code array}
*/
public static String nullSafeToString(char[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
}
else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append("'").append(array[i]).append("'");
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>The String representation consists of a list of the array's elements,
* enclosed in curly braces ({@code "{}"}). Adjacent elements are separated
* by the characters {@code ", "} (a comma followed by a space). Returns
* {@code "null"} if {@code array} is {@code null}.
* @param array the array to build a String representation for
* @return a String representation of {@code array}
*/
public static String nullSafeToString(double[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
}
else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>The String representation consists of a list of the array's elements,
* enclosed in curly braces ({@code "{}"}). Adjacent elements are separated
* by the characters {@code ", "} (a comma followed by a space). Returns
* {@code "null"} if {@code array} is {@code null}.
* @param array the array to build a String representation for
* @return a String representation of {@code array}
*/
public static String nullSafeToString(float[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
}
else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>The String representation consists of a list of the array's elements,
* enclosed in curly braces ({@code "{}"}). Adjacent elements are separated
* by the characters {@code ", "} (a comma followed by a space). Returns
* {@code "null"} if {@code array} is {@code null}.
* @param array the array to build a String representation for
* @return a String representation of {@code array}
*/
public static String nullSafeToString(int[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
}
else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>The String representation consists of a list of the array's elements,
* enclosed in curly braces ({@code "{}"}). Adjacent elements are separated
* by the characters {@code ", "} (a comma followed by a space). Returns
* {@code "null"} if {@code array} is {@code null}.
* @param array the array to build a String representation for
* @return a String representation of {@code array}
*/
public static String nullSafeToString(long[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
}
else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
/**
* Return a String representation of the contents of the specified array.
* <p>The String representation consists of a list of the array's elements,
* enclosed in curly braces ({@code "{}"}). Adjacent elements are separated
* by the characters {@code ", "} (a comma followed by a space). Returns
* {@code "null"} if {@code array} is {@code null}.
* @param array the array to build a String representation for
* @return a String representation of {@code array}
*/
public static String nullSafeToString(short[] array) {
if (array == null) {
return NULL_STRING;
}
int length = array.length;
if (length == 0) {
return EMPTY_ARRAY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
if (i == 0) {
sb.append(ARRAY_START);
}
else {
sb.append(ARRAY_ELEMENT_SEPARATOR);
}
sb.append(array[i]);
}
sb.append(ARRAY_END);
return sb.toString();
}
}

1310
src/main/java/com/alibaba/excel/util/StringUtils.java

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save