From 33929c717017658e3fc65741f7c4eb5d6ecb00a6 Mon Sep 17 00:00:00 2001 From: Jiaju Zhuang Date: Mon, 16 Sep 2019 18:29:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=94=A8string=E5=8E=BB?= =?UTF-8?q?=E6=8E=A5=E6=94=B6number=E6=95=B0=E6=8D=AE=E4=BC=9A=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=A7=91=E5=AD=A6=E8=AE=A1=E6=95=B0=E6=B3=95=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/alibaba/excel/EasyExcelFactory.java | 2 +- .../v03/handlers/FormulaRecordHandler.java | 4 +- .../v03/handlers/NumberRecordHandler.java | 4 +- .../v07/handlers/DefaultCellHandler.java | 5 +- .../bigdecimal/BigDecimalNumberConverter.java | 4 +- .../BooleanNumberConverter.java | 12 +-- .../byteconverter/ByteNumberConverter.java | 6 +- .../converters/date/DateNumberConverter.java | 16 ++- .../DoubleNumberConverter.java | 6 +- .../floatconverter/FloatNumberConverter.java | 6 +- .../integer/IntegerNumberConverter.java | 6 +- .../longconverter/LongNumberConverter.java | 6 +- .../shortconverter/ShortNumberConverter.java | 6 +- .../string/StringNumberConverter.java | 14 +-- .../com/alibaba/excel/metadata/CellData.java | 57 +++++++--- .../listener/ModelBuildEventListener.java | 6 +- .../alibaba/excel/util/ConverterUtils.java | 40 ++++++- .../alibaba/excel/write/ExcelBuilderImpl.java | 39 +++++-- .../LongestMatchColumnWidthStyleStrategy.java | 2 +- .../easyexcel/test/temp/poi/PoiWriteTest.java | 101 ++++++++++++++++++ .../easyexcel/test/temp/poi/TestCell.java | 18 ++++ .../easyexcel/test/temp/simple/HgTest.java | 2 +- 22 files changed, 297 insertions(+), 65 deletions(-) create mode 100644 src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java create mode 100644 src/test/java/com/alibaba/easyexcel/test/temp/poi/TestCell.java diff --git a/src/main/java/com/alibaba/excel/EasyExcelFactory.java b/src/main/java/com/alibaba/excel/EasyExcelFactory.java index 39fe0311..a4924973 100644 --- a/src/main/java/com/alibaba/excel/EasyExcelFactory.java +++ b/src/main/java/com/alibaba/excel/EasyExcelFactory.java @@ -73,7 +73,7 @@ public class EasyExcelFactory { * read sheet. * @param listener * Callback method after each row is parsed. - * @deprecated please use 'EasyExcel.read(in,head,listener).sheet(sheetNo).doRead().finish();' + * @deprecated please use 'EasyExcel.read(in,head,listener).sheet(sheetNo).doRead();' */ @Deprecated public static void readBySax(InputStream in, Sheet sheet, AnalysisEventListener listener) { diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java index f8899c03..0ff8f995 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/FormulaRecordHandler.java @@ -1,5 +1,7 @@ package com.alibaba.excel.analysis.v03.handlers; +import java.math.BigDecimal; + import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; import org.apache.poi.hssf.model.HSSFFormulaParser; import org.apache.poi.hssf.record.FormulaRecord; @@ -66,7 +68,7 @@ public class FormulaRecordHandler extends AbstractXlsRecordHandler { tempCellData.setFormulaValue(formulaValue); break; case NUMERIC: - this.cellData = new CellData(frec.getValue()); + this.cellData = new CellData(BigDecimal.valueOf(frec.getValue())); this.cellData.setFormula(Boolean.TRUE); this.cellData.setFormulaValue(formulaValue); break; diff --git a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java index 23aff5a3..75c3128a 100644 --- a/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v03/handlers/NumberRecordHandler.java @@ -1,5 +1,7 @@ package com.alibaba.excel.analysis.v03.handlers; +import java.math.BigDecimal; + import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener; import org.apache.poi.hssf.record.NumberRecord; import org.apache.poi.hssf.record.Record; @@ -29,7 +31,7 @@ public class NumberRecordHandler extends AbstractXlsRecordHandler { NumberRecord numrec = (NumberRecord)record; this.row = numrec.getRow(); this.column = numrec.getColumn(); - this.cellData = new CellData(numrec.getValue()); + this.cellData = new CellData(BigDecimal.valueOf(numrec.getValue())); this.cellData.setDataFormat(formatListener.getFormatIndex(numrec)); this.cellData.setDataFormatString(formatListener.getFormatString(numrec)); } diff --git a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java index 37d12ad7..5a52c996 100644 --- a/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java +++ b/src/main/java/com/alibaba/excel/analysis/v07/handlers/DefaultCellHandler.java @@ -7,6 +7,7 @@ import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_TAG; import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TAG; import static com.alibaba.excel.constant.ExcelXmlConstants.CELL_VALUE_TYPE_TAG; +import java.math.BigDecimal; import java.util.Map; import java.util.TreeMap; @@ -162,8 +163,8 @@ public class DefaultCellHandler implements XlsxCellHandler, XlsxRowResultHolder case NUMBER: case EMPTY: currentCellData.setType(CellDataTypeEnum.NUMBER); - if (currentCellData.getDoubleValue() == null) { - currentCellData.setDoubleValue(Double.valueOf(currentCellValue)); + if (currentCellData.getNumberValue() == null) { + currentCellData.setNumberValue(new BigDecimal(currentCellValue)); } break; default: diff --git a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java index f7f14057..bf9b735f 100644 --- a/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/bigdecimal/BigDecimalNumberConverter.java @@ -28,12 +28,12 @@ public class BigDecimalNumberConverter implements Converter { @Override public BigDecimal convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return BigDecimal.valueOf(cellData.getDoubleValue()); + return cellData.getNumberValue(); } @Override public CellData convertToExcelData(BigDecimal value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(value.doubleValue()); + return new CellData(value); } } diff --git a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java index 44cbdb9d..06ac0c73 100644 --- a/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/booleanconverter/BooleanNumberConverter.java @@ -1,5 +1,7 @@ package com.alibaba.excel.converters.booleanconverter; +import java.math.BigDecimal; + import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; @@ -12,10 +14,6 @@ import com.alibaba.excel.metadata.property.ExcelContentProperty; * @author Jiaju Zhuang */ public class BooleanNumberConverter implements Converter { - - private static final Double ONE = 1.0; - private static final Double ZERO = 0.0; - @Override public Class supportJavaTypeKey() { return Boolean.class; @@ -29,7 +27,7 @@ public class BooleanNumberConverter implements Converter { @Override public Boolean convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - if (ONE.equals(cellData.getDoubleValue())) { + if (BigDecimal.ONE.equals(cellData.getNumberValue())) { return Boolean.TRUE; } return Boolean.FALSE; @@ -39,9 +37,9 @@ public class BooleanNumberConverter implements Converter { public CellData convertToExcelData(Boolean value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (value) { - return new CellData(ONE); + return new CellData(BigDecimal.ONE); } - return new CellData(ZERO); + return new CellData(BigDecimal.ZERO); } } diff --git a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java index c3ecf47d..8c16a779 100644 --- a/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/byteconverter/ByteNumberConverter.java @@ -1,5 +1,7 @@ package com.alibaba.excel.converters.byteconverter; +import java.math.BigDecimal; + import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; @@ -26,13 +28,13 @@ public class ByteNumberConverter implements Converter { @Override public Byte convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return cellData.getDoubleValue().byteValue(); + return cellData.getNumberValue().byteValue(); } @Override public CellData convertToExcelData(Byte value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(value.doubleValue()); + return new CellData(BigDecimal.valueOf(value)); } } diff --git a/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java b/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java index 810188a3..fcc76bb3 100644 --- a/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/date/DateNumberConverter.java @@ -1,8 +1,9 @@ package com.alibaba.excel.converters.date; +import java.math.BigDecimal; import java.util.Date; -import org.apache.poi.hssf.usermodel.HSSFDateUtil; +import org.apache.poi.ss.usermodel.DateUtil; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; @@ -31,9 +32,10 @@ public class DateNumberConverter implements Converter { public Date convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { - return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), globalConfiguration.getUse1904windowing(), null); + return DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(), + globalConfiguration.getUse1904windowing(), null); } else { - return HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), + return DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(), contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null); } } @@ -41,6 +43,12 @@ public class DateNumberConverter implements Converter { @Override public CellData convertToExcelData(Date value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData((double)(value.getTime())); + if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) { + return new CellData( + BigDecimal.valueOf(DateUtil.getExcelDate(value, globalConfiguration.getUse1904windowing()))); + } else { + return new CellData(BigDecimal.valueOf( + DateUtil.getExcelDate(value, contentProperty.getDateTimeFormatProperty().getUse1904windowing()))); + } } } diff --git a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java index f272c824..15fbdae3 100644 --- a/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/doubleconverter/DoubleNumberConverter.java @@ -1,5 +1,7 @@ package com.alibaba.excel.converters.doubleconverter; +import java.math.BigDecimal; + import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; @@ -26,13 +28,13 @@ public class DoubleNumberConverter implements Converter { @Override public Double convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return cellData.getDoubleValue(); + return cellData.getNumberValue().doubleValue(); } @Override public CellData convertToExcelData(Double value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(value); + return new CellData(BigDecimal.valueOf(value)); } } diff --git a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java index 8913a571..a1b64719 100644 --- a/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/floatconverter/FloatNumberConverter.java @@ -1,5 +1,7 @@ package com.alibaba.excel.converters.floatconverter; +import java.math.BigDecimal; + import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; @@ -26,13 +28,13 @@ public class FloatNumberConverter implements Converter { @Override public Float convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return cellData.getDoubleValue().floatValue(); + return cellData.getNumberValue().floatValue(); } @Override public CellData convertToExcelData(Float value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(value.doubleValue()); + return new CellData(BigDecimal.valueOf(value)); } } diff --git a/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java b/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java index 4dff32d9..3b0deac6 100644 --- a/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/integer/IntegerNumberConverter.java @@ -1,5 +1,7 @@ package com.alibaba.excel.converters.integer; +import java.math.BigDecimal; + import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; @@ -26,13 +28,13 @@ public class IntegerNumberConverter implements Converter { @Override public Integer convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return cellData.getDoubleValue().intValue(); + return cellData.getNumberValue().intValue(); } @Override public CellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(value.doubleValue()); + return new CellData(BigDecimal.valueOf(value)); } } diff --git a/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java b/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java index bceedd55..8058d624 100644 --- a/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/longconverter/LongNumberConverter.java @@ -1,5 +1,7 @@ package com.alibaba.excel.converters.longconverter; +import java.math.BigDecimal; + import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; @@ -26,13 +28,13 @@ public class LongNumberConverter implements Converter { @Override public Long convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return cellData.getDoubleValue().longValue(); + return cellData.getNumberValue().longValue(); } @Override public CellData convertToExcelData(Long value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(value.doubleValue()); + return new CellData(BigDecimal.valueOf(value)); } } diff --git a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java index 91f6579c..7d1d7da2 100644 --- a/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/shortconverter/ShortNumberConverter.java @@ -1,5 +1,7 @@ package com.alibaba.excel.converters.shortconverter; +import java.math.BigDecimal; + import com.alibaba.excel.converters.Converter; import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.metadata.CellData; @@ -26,13 +28,13 @@ public class ShortNumberConverter implements Converter { @Override public Short convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return cellData.getDoubleValue().shortValue(); + return cellData.getNumberValue().shortValue(); } @Override public CellData convertToExcelData(Short value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(value.doubleValue()); + return new CellData(BigDecimal.valueOf(value)); } } diff --git a/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java b/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java index 62b25238..89cbe1d2 100644 --- a/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java +++ b/src/main/java/com/alibaba/excel/converters/string/StringNumberConverter.java @@ -1,5 +1,7 @@ package com.alibaba.excel.converters.string; +import java.math.BigDecimal; + import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.ss.usermodel.DateUtil; @@ -34,30 +36,30 @@ public class StringNumberConverter implements Converter { // If there are "DateTimeFormat", read as date if (contentProperty != null && contentProperty.getDateTimeFormatProperty() != null) { return DateUtils.format( - HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), + DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(), contentProperty.getDateTimeFormatProperty().getUse1904windowing(), null), contentProperty.getDateTimeFormatProperty().getFormat()); } // If there are "NumberFormat", read as number if (contentProperty != null && contentProperty.getNumberFormatProperty() != null) { - return NumberUtils.format(cellData.getDoubleValue(), contentProperty); + return NumberUtils.format(cellData.getNumberValue(), contentProperty); } // Excel defines formatting if (cellData.getDataFormat() != null) { if (DateUtil.isADateFormat(cellData.getDataFormat(), cellData.getDataFormatString())) { - return DateUtils.format(HSSFDateUtil.getJavaDate(cellData.getDoubleValue(), + return DateUtils.format(DateUtil.getJavaDate(cellData.getNumberValue().doubleValue(), globalConfiguration.getUse1904windowing(), null)); } else { - return NumberUtils.format(cellData.getDoubleValue(), contentProperty); + return NumberUtils.format(cellData.getNumberValue(), contentProperty); } } // Default conversion number - return NumberUtils.format(cellData.getDoubleValue(), contentProperty); + return NumberUtils.format(cellData.getNumberValue(), contentProperty); } @Override public CellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new CellData(Double.valueOf(value)); + return new CellData(new BigDecimal(value)); } } diff --git a/src/main/java/com/alibaba/excel/metadata/CellData.java b/src/main/java/com/alibaba/excel/metadata/CellData.java index 0a1ffeb0..a3a40c61 100644 --- a/src/main/java/com/alibaba/excel/metadata/CellData.java +++ b/src/main/java/com/alibaba/excel/metadata/CellData.java @@ -1,19 +1,23 @@ package com.alibaba.excel.metadata; +import java.math.BigDecimal; + import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.util.StringUtils; /** - * Excel internal cell data + * Excel internal cell data. + * + *

* * @author Jiaju Zhuang */ -public class CellData { +public class CellData { private CellDataTypeEnum type; /** * {@link CellDataTypeEnum#NUMBER} */ - private Double doubleValue; + private BigDecimal numberValue; /** * {@link CellDataTypeEnum#STRING} and{@link CellDataTypeEnum#ERROR} */ @@ -33,10 +37,14 @@ public class CellData { * The string of number formatting.Currently only supported when reading */ private String dataFormatString; + /** + * The resulting converted data. + */ + private T data; - public CellData(CellData other) { + public CellData(CellData other) { this.type = other.type; - this.doubleValue = other.doubleValue; + this.numberValue = other.numberValue; this.stringValue = other.stringValue; this.booleanValue = other.booleanValue; this.formula = other.formula; @@ -44,6 +52,19 @@ public class CellData { this.imageValue = other.imageValue; this.dataFormat = other.dataFormat; this.dataFormatString = other.dataFormatString; + this.data = other.data; + } + + public CellData() {} + + public CellData(T data) { + this.data = data; + } + + public CellData(T data, String formulaValue) { + this.data = data; + this.formula = Boolean.TRUE; + this.formulaValue = formulaValue; } public CellData(String stringValue) { @@ -62,12 +83,12 @@ public class CellData { this.formula = Boolean.FALSE; } - public CellData(Double doubleValue) { - if (doubleValue == null) { + public CellData(BigDecimal numberValue) { + if (numberValue == null) { throw new IllegalArgumentException("DoubleValue can not be null"); } this.type = CellDataTypeEnum.NUMBER; - this.doubleValue = doubleValue; + this.numberValue = numberValue; this.formula = Boolean.FALSE; } @@ -105,12 +126,12 @@ public class CellData { this.type = type; } - public Double getDoubleValue() { - return doubleValue; + public BigDecimal getNumberValue() { + return numberValue; } - public void setDoubleValue(Double doubleValue) { - this.doubleValue = doubleValue; + public void setNumberValue(BigDecimal numberValue) { + this.numberValue = numberValue; } public String getStringValue() { @@ -169,6 +190,14 @@ public class CellData { this.dataFormatString = dataFormatString; } + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + /** * Ensure that the object does not appear null */ @@ -181,7 +210,7 @@ public class CellData { } return; case NUMBER: - if (doubleValue == null) { + if (numberValue == null) { type = CellDataTypeEnum.EMPTY; } return; @@ -198,7 +227,7 @@ public class CellData { public String toString() { switch (type) { case NUMBER: - return doubleValue.toString(); + return numberValue.toString(); case BOOLEAN: return booleanValue.toString(); case STRING: diff --git a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java index 7896334f..6bea5931 100644 --- a/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java +++ b/src/main/java/com/alibaba/excel/read/listener/ModelBuildEventListener.java @@ -49,7 +49,7 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener map.put(entry.getKey(), null); continue; } - map.put(entry.getKey(), (String)ConverterUtils.convertToJavaObject(cellData, String.class, null, + map.put(entry.getKey(), (String)ConverterUtils.convertToJavaObject(cellData, null, null, currentReadHolder.converterMap(), currentReadHolder.globalConfiguration())); } return map; @@ -62,7 +62,7 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener list.add(null); continue; } - list.add((String)ConverterUtils.convertToJavaObject(cellData, String.class, null, + list.add((String)ConverterUtils.convertToJavaObject(cellData, null, null, currentReadHolder.converterMap(), currentReadHolder.globalConfiguration())); } return list; @@ -91,7 +91,7 @@ public class ModelBuildEventListener extends AbstractIgnoreExceptionReadListener continue; } ExcelContentProperty excelContentProperty = contentPropertyMap.get(index); - Object value = ConverterUtils.convertToJavaObject(cellData, excelContentProperty.getField().getType(), + Object value = ConverterUtils.convertToJavaObject(cellData, excelContentProperty.getField(), excelContentProperty, currentReadHolder.converterMap(), currentReadHolder.globalConfiguration()); if (value != null) { map.put(excelContentProperty.getField().getName(), value); diff --git a/src/main/java/com/alibaba/excel/util/ConverterUtils.java b/src/main/java/com/alibaba/excel/util/ConverterUtils.java index 7445b4ce..a06ab382 100644 --- a/src/main/java/com/alibaba/excel/util/ConverterUtils.java +++ b/src/main/java/com/alibaba/excel/util/ConverterUtils.java @@ -1,5 +1,8 @@ package com.alibaba.excel.util; +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; @@ -56,17 +59,48 @@ public class ConverterUtils { * Convert it into a Java object * * @param cellData - * @param clazz + * @param field * @param contentProperty * @param converterMap * @param globalConfiguration * @return */ - public static Object convertToJavaObject(CellData cellData, Class clazz, ExcelContentProperty contentProperty, + public static Object convertToJavaObject(CellData cellData, Field field, ExcelContentProperty contentProperty, Map converterMap, GlobalConfiguration globalConfiguration) { + Class clazz; + if (field == null) { + clazz = String.class; + } else { + clazz = field.getType(); + } if (clazz == CellData.class) { - return new CellData(cellData); + Type type = field.getGenericType(); + Class classGeneric; + if (type instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType)type; + classGeneric = (Class)((ParameterizedType)parameterizedType.getActualTypeArguments()[0]).getRawType(); + } else { + classGeneric = String.class; + } + CellData cellDataReturn = new CellData(cellData); + cellDataReturn.setData( + doConvertToJavaObject(cellData, classGeneric, contentProperty, converterMap, globalConfiguration)); + return cellDataReturn; } + return doConvertToJavaObject(cellData, clazz, contentProperty, converterMap, globalConfiguration); + } + + /** + * + * @param cellData + * @param clazz + * @param contentProperty + * @param converterMap + * @param globalConfiguration + * @return + */ + private static Object doConvertToJavaObject(CellData cellData, Class clazz, ExcelContentProperty contentProperty, + Map converterMap, GlobalConfiguration globalConfiguration) { Converter converter = null; if (contentProperty != null) { converter = contentProperty.getConverter(); diff --git a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java index 3c257262..e0e8503b 100644 --- a/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java +++ b/src/main/java/com/alibaba/excel/write/ExcelBuilderImpl.java @@ -21,6 +21,7 @@ import com.alibaba.excel.context.WriteContext; import com.alibaba.excel.context.WriteContextImpl; import com.alibaba.excel.converters.Converter; import com.alibaba.excel.converters.ConverterKeyBuild; +import com.alibaba.excel.enums.CellDataTypeEnum; import com.alibaba.excel.enums.HeadKindEnum; import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.excel.exception.ExcelGenerateException; @@ -291,16 +292,12 @@ public class ExcelBuilderImpl implements ExcelBuilder { private CellData converterAndSet(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value, ExcelContentProperty excelContentProperty) { if (value == null) { - return null; + return new CellData(); } if (value instanceof String && currentWriteHolder.globalConfiguration().getAutoTrim()) { value = ((String)value).trim(); } CellData cellData = convert(currentWriteHolder, clazz, cell, value, excelContentProperty); - if (cellData == null || cellData.getType() == null) { - throw new ExcelDataConvertException( - "Convert data:" + value + " return null,at row:" + cell.getRow().getRowNum()); - } if (cellData.getFormula() != null && cellData.getFormula()) { cell.setCellFormula(cellData.getFormulaValue()); } @@ -312,11 +309,13 @@ public class ExcelBuilderImpl implements ExcelBuilder { cell.setCellValue(cellData.getBooleanValue()); return cellData; case NUMBER: - cell.setCellValue(cellData.getDoubleValue()); + cell.setCellValue(cellData.getNumberValue().doubleValue()); return cellData; case IMAGE: setImageValue(cellData, cell); return cellData; + case EMPTY: + return cellData; default: throw new ExcelDataConvertException("Not supported data:" + value + " return type:" + cell.getCellType() + "at row:" + cell.getRow().getRowNum()); @@ -346,9 +345,31 @@ public class ExcelBuilderImpl implements ExcelBuilder { private CellData convert(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value, ExcelContentProperty excelContentProperty) { + // This means that the user has defined the data. if (value instanceof CellData) { - return (CellData)value; + CellData cellDataValue = (CellData)value; + if (cellDataValue.getType() != null) { + return cellDataValue; + } else { + if (cellDataValue.getData() == null) { + cellDataValue.setType(CellDataTypeEnum.EMPTY); + return cellDataValue; + } + } + CellData cellDataReturn = doConvert(currentWriteHolder, cellDataValue.getData().getClass(), cell, + cellDataValue.getData(), excelContentProperty); + // The formula information is subject to user input + if (cellDataValue.getFormula() != null) { + cellDataReturn.setFormula(cellDataValue.getFormula()); + cellDataReturn.setFormulaValue(cellDataValue.getFormulaValue()); + } + return cellDataReturn; } + return doConvert(currentWriteHolder, clazz, cell, value, excelContentProperty); + } + + private CellData doConvert(WriteHolder currentWriteHolder, Class clazz, Cell cell, Object value, + ExcelContentProperty excelContentProperty) { Converter converter = null; if (excelContentProperty != null) { converter = excelContentProperty.getConverter(); @@ -368,6 +389,10 @@ public class ExcelBuilderImpl implements ExcelBuilder { throw new ExcelDataConvertException("Convert data:" + value + " error,at row:" + cell.getRow().getRowNum(), e); } + if (cellData == null || cellData.getType() == null) { + throw new ExcelDataConvertException( + "Convert data:" + value + " return null,at row:" + cell.getRow().getRowNum()); + } return cellData; } } diff --git a/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java b/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java index 5c6ec8c9..320573bd 100644 --- a/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java +++ b/src/main/java/com/alibaba/excel/write/style/column/LongestMatchColumnWidthStyleStrategy.java @@ -58,7 +58,7 @@ public class LongestMatchColumnWidthStyleStrategy extends AbstractColumnWidthSty case BOOLEAN: return cellData.getBooleanValue().toString().getBytes().length; case NUMBER: - return cellData.getDoubleValue().toString().getBytes().length; + return cellData.getNumberValue().toString().getBytes().length; default: return -1; } diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java new file mode 100644 index 00000000..02e38c09 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/poi/PoiWriteTest.java @@ -0,0 +1,101 @@ +package com.alibaba.easyexcel.test.temp.poi; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import org.apache.poi.ss.formula.functions.T; +import org.apache.poi.xssf.streaming.SXSSFCell; +import org.apache.poi.xssf.streaming.SXSSFRow; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.streaming.SXSSFWorkbook; +import org.junit.Ignore; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.excel.metadata.CellData; + +import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; + +/** + * 测试poi + * + * @author Jiaju Zhuang + **/ +@Ignore +public class PoiWriteTest { + private static final Logger LOGGER = LoggerFactory.getLogger(PoiWriteTest.class); + + @Test + public void write() throws IOException { + FileOutputStream fileOutputStream = new FileOutputStream("D://test//tt12.xlsx"); + SXSSFWorkbook sxxsFWorkbook = new SXSSFWorkbook(); + SXSSFSheet sheet = sxxsFWorkbook.createSheet("t1"); + SXSSFRow row = sheet.createRow(0); + SXSSFCell cell1 = row.createCell(0); + cell1.setCellValue(1); + SXSSFCell cell2 = row.createCell(1); + cell2.setCellValue(1); + SXSSFCell cell3 = row.createCell(2); + cell3.setCellFormula("=A1+B1"); + sxxsFWorkbook.write(fileOutputStream); + } + + @Test + public void test() throws Exception { + Class clazz = TestCell.class; + + Field field = clazz.getDeclaredField("c2"); + // 通过getDeclaredField可以获得成员变量,但是对于Map来说,仅仅可以知道它是个Map,无法知道键值对各自的数据类型 + + Type gType = field.getGenericType(); + // 获得field的泛型类型 + + // 如果gType是ParameterizedType对象(参数化) + if (gType instanceof ParameterizedType) { + + ParameterizedType pType = (ParameterizedType)gType; + // 就把它转换成ParameterizedType对象 + + Type[] tArgs = pType.getActualTypeArguments(); + // 获得泛型类型的泛型参数(实际类型参数) + ParameterizedTypeImpl c = (ParameterizedTypeImpl)pType.getActualTypeArguments()[0]; + Class ttt = c.getRawType(); + System.out.println(ttt); + } else { + System.out.println("出错!!!"); + } + + } + + @Test + public void test2() throws Exception { + Class clazz = TestCell.class; + + Field field = clazz.getDeclaredField("c2"); + // 通过getDeclaredField可以获得成员变量,但是对于Map来说,仅仅可以知道它是个Map,无法知道键值对各自的数据类型 + + Type gType = field.getGenericType(); + // 获得field的泛型类型 + + // 如果gType是ParameterizedType对象(参数化) + if (gType instanceof ParameterizedType) { + + ParameterizedType pType = (ParameterizedType)gType; + // 就把它转换成ParameterizedType对象 + + Type[] tArgs = pType.getActualTypeArguments(); + // 获得泛型类型的泛型参数(实际类型参数) + ParameterizedTypeImpl c = (ParameterizedTypeImpl)pType.getActualTypeArguments()[0]; + Class ttt = c.getRawType(); + System.out.println(ttt); + } else { + System.out.println("出错!!!"); + } + + } + +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/poi/TestCell.java b/src/test/java/com/alibaba/easyexcel/test/temp/poi/TestCell.java new file mode 100644 index 00000000..3c4e0ab6 --- /dev/null +++ b/src/test/java/com/alibaba/easyexcel/test/temp/poi/TestCell.java @@ -0,0 +1,18 @@ +package com.alibaba.easyexcel.test.temp.poi; + +import java.util.List; + +import com.alibaba.excel.metadata.CellData; + +import lombok.Data; + +/** + * TODO + * + * @author 罗成 + **/ +@Data +public class TestCell { + private CellData c1; + private CellData> c2; +} diff --git a/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java b/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java index 4ece35e1..e0032fd0 100644 --- a/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java +++ b/src/test/java/com/alibaba/easyexcel/test/temp/simple/HgTest.java @@ -24,7 +24,7 @@ public class HgTest { @Test public void hh() throws IOException { List list = - EasyExcel.read(new FileInputStream("D:\\test\\商户不匹配工单信息收集表格.xlsx")).headRowNumber(0).sheet().doReadSync(); + EasyExcel.read(new FileInputStream("D:\\test\\test.xlsx")).headRowNumber(0).sheet().doReadSync(); for (Object data : list) { LOGGER.info("返回数据:{}", JSON.toJSONString(data)); }