25
25
import org .apache .poi .ss .usermodel .CellType ;
26
26
import org .apache .poi .ss .usermodel .DataFormatter ;
27
27
import org .apache .poi .ss .usermodel .DateUtil ;
28
+ import org .apache .poi .ss .usermodel .ExcelNumberFormat ;
28
29
import org .apache .poi .ss .usermodel .FormulaEvaluator ;
29
30
30
31
/**
31
32
* Specialized subclass for formatting the date into an ISO date/time and ignore the format as given in the Excel file.
32
33
*
33
34
* @author Marten Deinum
34
- *
35
- * @see DateTimeFormatter#ISO_OFFSET_DATE_TIME
36
35
*/
37
36
public class IsoFormattingDateDataFormatter extends DataFormatter {
38
37
@@ -46,9 +45,10 @@ public IsoFormattingDateDataFormatter(Locale locale) {
46
45
47
46
@ Override
48
47
public String formatRawCellContents (double value , int formatIndex , String formatString , boolean use1904Windowing ) {
48
+
49
49
if (DateUtil .isADateFormat (formatIndex , formatString ) && DateUtil .isValidExcelDate (value )) {
50
- return super . formatRawCellContents ( value , formatIndex , "yyyy-MM-ddTHH:mm:ss" ,
51
- use1904Windowing );
50
+ String formatToUse = determineFormat ( formatIndex );
51
+ return super . formatRawCellContents ( value , formatIndex , formatToUse , use1904Windowing );
52
52
}
53
53
return super .formatRawCellContents (value , formatIndex , formatString , use1904Windowing );
54
54
}
@@ -60,17 +60,34 @@ public String formatCellValue(Cell cell, FormulaEvaluator evaluator, Conditional
60
60
}
61
61
62
62
CellType cellType = cell .getCellType ();
63
- if (cellType == CellType .FORMULA ) {
64
- if (evaluator == null ) {
65
- return cell .getCellFormula ();
66
- }
67
- cellType = evaluator .evaluateFormulaCell (cell );
63
+ if (cellType == CellType .FORMULA && useCachedValuesForFormulaCells ()) {
64
+ cellType = cell .getCachedFormulaResultType ();
68
65
}
69
66
70
- if (cellType == CellType .NUMERIC && DateUtil .isCellDateFormatted (cell , cfEvaluator )) {
67
+ if (cellType != CellType .STRING && DateUtil .isCellDateFormatted (cell , cfEvaluator )) {
68
+ String formatToUse = determineFormat (ExcelNumberFormat .from (cell , cfEvaluator ).getIdx ());
71
69
LocalDateTime value = cell .getLocalDateTimeCellValue ();
72
- return (value != null ) ? value .format (DateTimeFormatter .ISO_LOCAL_DATE_TIME ) : "" ;
70
+ return (value != null ) ? value .format (DateTimeFormatter .ofPattern ( formatToUse ) ) : "" ;
73
71
}
74
72
return super .formatCellValue (cell , evaluator , cfEvaluator );
75
73
}
74
+
75
+ /**
76
+ * Determine the format to use for either date, time of datetime. Based on the internal formats used by Excel.
77
+ * 14, 15, 16, 17 are dates only
78
+ * 18, 19, 20, 21 are times only
79
+ * anything else is interpreted as a datetime, including custom formats that might be in use!
80
+ * @param formatIndex the format index from excel.
81
+ * @return the format to use, never {@code null}.
82
+ */
83
+
84
+ private String determineFormat (int formatIndex ) {
85
+ if (formatIndex >= 14 && formatIndex < 18 ) {
86
+ return "yyyy-MM-dd" ;
87
+ }
88
+ else if (formatIndex >= 18 && formatIndex < 22 ) {
89
+ return "HH:mm:ss" ;
90
+ }
91
+ return "yyyy-MM-dd'T'HH:mm:ss" ;
92
+ }
76
93
}
0 commit comments