diff --git a/src/main/java/com/alibaba/excel/enums/NumericCellTypeEnum.java b/src/main/java/com/alibaba/excel/enums/NumericCellTypeEnum.java
new file mode 100644
index 00000000..22001f13
--- /dev/null
+++ b/src/main/java/com/alibaba/excel/enums/NumericCellTypeEnum.java
@@ -0,0 +1,22 @@
+package com.alibaba.excel.enums;
+
+import org.apache.poi.ss.usermodel.CellType;
+
+/**
+ * Used to supplement {@link CellType}.
+ *
+ * Cannot distinguish between date and number in write case.
+ *
+ * @author Jiaju Zhuang
+ */
+public enum NumericCellTypeEnum {
+ /**
+ * number
+ */
+ NUMBER,
+ /**
+ * date. Support only when writing.
+ */
+ DATE,
+ ;
+}
diff --git a/src/main/java/com/alibaba/excel/metadata/csv/CsvCell.java b/src/main/java/com/alibaba/excel/metadata/csv/CsvCell.java
index a434758e..f0e925e6 100644
--- a/src/main/java/com/alibaba/excel/metadata/csv/CsvCell.java
+++ b/src/main/java/com/alibaba/excel/metadata/csv/CsvCell.java
@@ -18,7 +18,6 @@ import org.apache.poi.ss.usermodel.CellBase;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Comment;
-import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Row;
@@ -47,6 +46,11 @@ public class CsvCell extends CellBase {
@Setter(value = AccessLevel.NONE)
private CellType cellType;
+ /**
+ * numeric cell type
+ */
+ private NumericCellTypeEnum numericCellType;
+
/**
* workbook
*/
@@ -65,7 +69,7 @@ public class CsvCell extends CellBase {
/**
* {@link CellType#NUMERIC}
*/
- private Double numberValue;
+ private BigDecimal numberValue;
/**
* {@link CellType#STRING} and {@link CellType#ERROR} {@link CellType#FORMULA}
*/
@@ -75,6 +79,11 @@ public class CsvCell extends CellBase {
*/
private Boolean booleanValue;
+ /**
+ * {@link CellType#NUMERIC}
+ */
+ private LocalDateTime dateValue;
+
/**
* formula
*/
@@ -121,25 +130,33 @@ public class CsvCell extends CellBase {
@Override
protected void setCellValueImpl(double value) {
- this.numberValue = value;
+ numberValue = BigDecimal.valueOf(value);
this.cellType = CellType.NUMERIC;
}
@Override
protected void setCellValueImpl(Date value) {
- this.numberValue = DateUtil.getExcelDate(value, csvWorkbook.getUse1904windowing());
+ if (value == null) {
+ return;
+ }
+ this.dateValue = LocalDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault());
this.cellType = CellType.NUMERIC;
+ this.numericCellType = NumericCellTypeEnum.DATE;
}
@Override
protected void setCellValueImpl(LocalDateTime value) {
- this.numberValue = DateUtil.getExcelDate(value, csvWorkbook.getUse1904windowing());
+ this.dateValue = value;
this.cellType = CellType.NUMERIC;
+ this.numericCellType = NumericCellTypeEnum.DATE;
}
@Override
protected void setCellValueImpl(Calendar value) {
- this.numberValue = DateUtil.getExcelDate(value, csvWorkbook.getUse1904windowing());
+ if (value == null) {
+ return;
+ }
+ this.dateValue = LocalDateTime.ofInstant(value.toInstant(), ZoneId.systemDefault());
this.cellType = CellType.NUMERIC;
}
@@ -231,18 +248,15 @@ public class CsvCell extends CellBase {
@Override
public Date getDateCellValue() {
- if (numberValue == null) {
+ if (dateValue == null) {
return null;
}
- return DateUtil.getJavaDate(numberValue, csvWorkbook.getUse1904windowing());
+ return Date.from(dateValue.atZone(ZoneId.systemDefault()).toInstant());
}
@Override
public LocalDateTime getLocalDateTimeCellValue() {
- if (numberValue == null) {
- return null;
- }
- return DateUtil.getLocalDateTime(numberValue, csvWorkbook.getUse1904windowing());
+ return dateValue;
}
@Override
@@ -263,7 +277,7 @@ public class CsvCell extends CellBase {
@Override
public void setCellErrorValue(byte value) {
- this.numberValue = value;
+ this.numberValue = BigDecimal.valueOf(value);
this.cellType = CellType.ERROR;
}
diff --git a/src/main/java/com/alibaba/excel/metadata/csv/CsvCellStyle.java b/src/main/java/com/alibaba/excel/metadata/csv/CsvCellStyle.java
index ca153e45..08b46e3a 100644
--- a/src/main/java/com/alibaba/excel/metadata/csv/CsvCellStyle.java
+++ b/src/main/java/com/alibaba/excel/metadata/csv/CsvCellStyle.java
@@ -52,13 +52,17 @@ public class CsvCellStyle implements CellStyle {
@Override
public short getDataFormat() {
- initDataFormatData();
+ if (dataFormatData == null) {
+ return 0;
+ }
return dataFormatData.getIndex();
}
@Override
public String getDataFormatString() {
- initDataFormatData();
+ if (dataFormatData == null) {
+ return null;
+ }
return dataFormatData.getFormat();
}
diff --git a/src/main/java/com/alibaba/excel/metadata/csv/CsvSheet.java b/src/main/java/com/alibaba/excel/metadata/csv/CsvSheet.java
index 0b203804..14c6a207 100644
--- a/src/main/java/com/alibaba/excel/metadata/csv/CsvSheet.java
+++ b/src/main/java/com/alibaba/excel/metadata/csv/CsvSheet.java
@@ -7,9 +7,9 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import com.alibaba.excel.constant.BuiltinFormats;
import com.alibaba.excel.enums.NumericCellTypeEnum;
import com.alibaba.excel.exception.ExcelGenerateException;
-import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.DateUtils;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.util.NumberDataFormatterUtils;
@@ -25,6 +25,7 @@ import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationHelper;
+import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Footer;
import org.apache.poi.ss.usermodel.Header;
@@ -45,7 +46,6 @@ import org.apache.poi.ss.util.PaneInformation;
*/
@Data
public class CsvSheet implements Sheet, Closeable {
-
/**
* workbook
*/
@@ -747,21 +747,40 @@ public class CsvSheet implements Sheet, Closeable {
case FORMULA:
return csvCell.getStringCellValue();
case NUMERIC:
-
- NumberDataFormatterUtils.format()
-
+ Short dataFormat = null;
+ String dataFormatString = null;
+ if (csvCell.getCellStyle() != null) {
+ dataFormat = csvCell.getCellStyle().getDataFormat();
+ dataFormatString = csvCell.getCellStyle().getDataFormatString();
+ }
if (csvCell.getNumericCellType() == NumericCellTypeEnum.DATE) {
+ if (csvCell.getDateValue() == null) {
+ return null;
+ }
// date
- if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) {
- return new WriteCellData<>(DateUtils.format(value, null));
- } else {
- return new WriteCellData<>(
- DateUtils.format(value, contentProperty.getDateTimeFormatProperty().getFormat()));
+ if (dataFormat == null) {
+ dataFormatString = DateUtils.defaultDateFormat;
+ dataFormat = csvWorkbook.createDataFormat().getFormat(dataFormatString);
}
-
+ if (dataFormatString == null) {
+ dataFormatString = csvWorkbook.createDataFormat().getFormat(dataFormat);
+ }
+ return NumberDataFormatterUtils.format(
+ DateUtil.getExcelDate(csvCell.getDateValue(), csvWorkbook.getUse1904windowing()),
+ dataFormat, dataFormatString, csvWorkbook.getUse1904windowing(), csvWorkbook.getLocale(),
+ csvWorkbook.getUseScientificFormat());
} else {
+ if (csvCell.getNumberValue() == null) {
+ return null;
+ }
//number
-
+ if (dataFormat == null) {
+ dataFormat = BuiltinFormats.GENERAL;
+ dataFormatString = csvWorkbook.createDataFormat().getFormat(dataFormat);
+ }
+ return NumberDataFormatterUtils.format(csvCell.getNumericCellValue(), dataFormat, dataFormatString,
+ csvWorkbook.getUse1904windowing(), csvWorkbook.getLocale(),
+ csvWorkbook.getUseScientificFormat());
}
case BOOLEAN:
return csvCell.getBooleanValue().toString();
@@ -772,6 +791,4 @@ public class CsvSheet implements Sheet, Closeable {
}
}
- private String
-
}
diff --git a/src/main/java/com/alibaba/excel/metadata/csv/CsvWorkbook.java b/src/main/java/com/alibaba/excel/metadata/csv/CsvWorkbook.java
index ba55e01f..e26a2b65 100644
--- a/src/main/java/com/alibaba/excel/metadata/csv/CsvWorkbook.java
+++ b/src/main/java/com/alibaba/excel/metadata/csv/CsvWorkbook.java
@@ -32,10 +32,7 @@ public class CsvWorkbook implements Workbook {
* output
*/
private Appendable out;
- /**
- * locale
- */
- private Locale locale;
+
/**
* true if date uses 1904 windowing, or false if using 1900 date windowing.
*
@@ -45,6 +42,18 @@ public class CsvWorkbook implements Workbook {
*/
private Boolean use1904windowing;
+ /**
+ * locale
+ */
+ private Locale locale;
+
+ /**
+ * Whether to use scientific Format.
+ *
+ * default is false
+ */
+ private Boolean useScientificFormat;
+
/**
* data format
*/
@@ -58,10 +67,11 @@ public class CsvWorkbook implements Workbook {
*/
private ListNumber
value.
*
Number
value.
*
*
- * @param excelFormatStr
- * The data format string
- * @param format
- * A Format instance
+ * @param excelFormatStr The data format string
+ * @param format A Format instance
*/
public void addFormat(String excelFormatStr, Format format) {
formats.put(excelFormatStr, format);
@@ -715,10 +724,8 @@ public class DataFormatter {
/**
* Enables custom rounding mode on the given Decimal Format.
*
- * @param format
- * DecimalFormat
- * @param roundingMode
- * RoundingMode
+ * @param format DecimalFormat
+ * @param roundingMode RoundingMode
*/
public static void setExcelStyleRoundingMode(DecimalFormat format, RoundingMode roundingMode) {
format.setRoundingMode(roundingMode);
@@ -737,7 +744,9 @@ public class DataFormatter {
// enforce singleton
}
- /** Format a number as an SSN */
+ /**
+ * Format a number as an SSN
+ */
public static String format(Number num) {
String result = df.format(num);
return result.substring(0, 3) + '-' + result.substring(3, 5) + '-' + result.substring(5, 9);
@@ -767,7 +776,9 @@ public class DataFormatter {
// enforce singleton
}
- /** Format a number as Zip + 4 */
+ /**
+ * Format a number as Zip + 4
+ */
public static String format(Number num) {
String result = df.format(num);
return result.substring(0, 5) + '-' + result.substring(5, 9);
@@ -797,7 +808,9 @@ public class DataFormatter {
// enforce singleton
}
- /** Format a number as a phone number */
+ /**
+ * Format a number as a phone number
+ */
public static String format(Number num) {
String result = df.format(num);
StringBuilder sb = new StringBuilder();
@@ -833,7 +846,8 @@ public class DataFormatter {
}
/**
- * Workaround until we merge {@link org.apache.poi.ss.usermodel.DataFormatter} with {@link CellFormat}. Constant, non-cachable wrapper around a
+ * Workaround until we merge {@link org.apache.poi.ss.usermodel.DataFormatter} with {@link CellFormat}. Constant,
+ * non-cachable wrapper around a
* {@link CellFormatResult}
*/
private final class CellFormatResultWrapper extends Format {
diff --git a/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java b/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java
index de01ad54..f9a8ee23 100644
--- a/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java
+++ b/src/main/java/com/alibaba/excel/util/NumberDataFormatterUtils.java
@@ -1,5 +1,7 @@
package com.alibaba.excel.util;
+import java.util.Locale;
+
import com.alibaba.excel.metadata.format.DataFormatter;
import com.alibaba.excel.metadata.GlobalConfiguration;
@@ -26,13 +28,32 @@ public class NumberDataFormatterUtils {
*/
public static String format(Double data, Short dataFormat, String dataFormatString,
GlobalConfiguration globalConfiguration) {
+ if (globalConfiguration == null) {
+ return format(data, dataFormat, dataFormatString, null, null, null);
+ }
+ return format(data, dataFormat, dataFormatString, globalConfiguration.getUse1904windowing(),
+ globalConfiguration.getLocale(), globalConfiguration.getUseScientificFormat());
+ }
+
+ /**
+ * Format number data.
+ *
+ * @param data
+ * @param dataFormat Not null.
+ * @param dataFormatString
+ * @param use1904windowing
+ * @param locale
+ * @param useScientificFormat
+ * @return
+ */
+ public static String format(Double data, Short dataFormat, String dataFormatString, Boolean use1904windowing,
+ Locale locale, Boolean useScientificFormat) {
DataFormatter dataFormatter = DATA_FORMATTER_THREAD_LOCAL.get();
if (dataFormatter == null) {
- dataFormatter = new DataFormatter(globalConfiguration);
+ dataFormatter = new DataFormatter(use1904windowing, locale, useScientificFormat);
DATA_FORMATTER_THREAD_LOCAL.set(dataFormatter);
}
return dataFormatter.format(data, dataFormat, dataFormatString);
-
}
public static void removeThreadLocalCache() {
diff --git a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java
index a7a3d74a..3e9732a9 100644
--- a/src/main/java/com/alibaba/excel/util/WorkBookUtil.java
+++ b/src/main/java/com/alibaba/excel/util/WorkBookUtil.java
@@ -69,7 +69,9 @@ public class WorkBookUtil {
case CSV:
CsvWorkbook csvWorkbook = new CsvWorkbook(
new OutputStreamWriter(writeWorkbookHolder.getOutputStream(), writeWorkbookHolder.getCharset()),
- writeWorkbookHolder.getGlobalConfiguration().getLocale(), writeWorkbookHolder.getGlobalConfiguration().getUse1904windowing());
+ writeWorkbookHolder.getGlobalConfiguration().getLocale(),
+ writeWorkbookHolder.getGlobalConfiguration().getUse1904windowing(),
+ writeWorkbookHolder.getGlobalConfiguration().getUseScientificFormat());
writeWorkbookHolder.setCachedWorkbook(csvWorkbook);
writeWorkbookHolder.setWorkbook(csvWorkbook);
return;