mirror of https://github.com/alibaba/easyexcel
Jiaju Zhuang
5 years ago
11 changed files with 2005 additions and 14 deletions
@ -0,0 +1,204 @@ |
|||||||
|
package com.alibaba.excel.constant; |
||||||
|
|
||||||
|
import com.alibaba.excel.util.StringUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* Excel's built-in format conversion.Currently only supports Chinese. |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* If it is not Chinese, it is recommended to directly modify the builtinFormats, which will better support |
||||||
|
* internationalization in the future. |
||||||
|
* |
||||||
|
* <p> |
||||||
|
* Specific correspondence please see: |
||||||
|
* https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.numberingformat?view=openxml-2.8.1
|
||||||
|
* |
||||||
|
* @author Jiaju Zhuang |
||||||
|
**/ |
||||||
|
public class BuiltinFormats { |
||||||
|
|
||||||
|
public static String[] builtinFormats = { |
||||||
|
// 0
|
||||||
|
"General", |
||||||
|
// 1
|
||||||
|
"0", |
||||||
|
// 2
|
||||||
|
"0.00", |
||||||
|
// 3
|
||||||
|
"#,##0", |
||||||
|
// 4
|
||||||
|
"#,##0.00", |
||||||
|
// 5
|
||||||
|
"\"$\"#,##0_);(\"$\"#,##0)", |
||||||
|
// 6
|
||||||
|
"\"$\"#,##0_);[Red](\"$\"#,##0)", |
||||||
|
// 7
|
||||||
|
"\"$\"#,##0.00_);(\"$\"#,##0.00)", |
||||||
|
// 8
|
||||||
|
"\"$\"#,##0.00_);[Red](\"$\"#,##0.00)", |
||||||
|
// 9
|
||||||
|
"0%", |
||||||
|
// 10
|
||||||
|
"0.00%", |
||||||
|
// 11
|
||||||
|
"0.00E+00", |
||||||
|
// 12
|
||||||
|
"# ?/?", |
||||||
|
// 13
|
||||||
|
"# ??/??", |
||||||
|
// 14
|
||||||
|
"m/d/yy", |
||||||
|
// 15
|
||||||
|
"d-mmm-yy", |
||||||
|
// 16
|
||||||
|
"d-mmm", |
||||||
|
// 17
|
||||||
|
"mmm-yy", |
||||||
|
// 18
|
||||||
|
"h:mm AM/PM", |
||||||
|
// 19
|
||||||
|
"h:mm:ss AM/PM", |
||||||
|
// 20
|
||||||
|
"h:mm", |
||||||
|
// 21
|
||||||
|
"h:mm:ss", |
||||||
|
// 22
|
||||||
|
"m/d/yy h:mm", |
||||||
|
// 23-26 No specific correspondence found in the official documentation.
|
||||||
|
// 23
|
||||||
|
null, |
||||||
|
// 24
|
||||||
|
null, |
||||||
|
// 25
|
||||||
|
null, |
||||||
|
// 26
|
||||||
|
null, |
||||||
|
// 27
|
||||||
|
"yyyy\"5E74\"m\"6708\"", |
||||||
|
// 28
|
||||||
|
"m\"6708\"d\"65E5\"", |
||||||
|
// 29
|
||||||
|
"m\"6708\"d\"65E5\"", |
||||||
|
// 30
|
||||||
|
"m-d-yy", |
||||||
|
// 31
|
||||||
|
"yyyy\"5E74\"m\"6708\"d\"65E5\"", |
||||||
|
// 32
|
||||||
|
"h\"65F6\"mm\"5206\"", |
||||||
|
// 33
|
||||||
|
"h\"65F6\"mm\"5206\"ss\"79D2\"", |
||||||
|
// 34
|
||||||
|
"4E0A5348/4E0B5348h\"65F6\"mm\"5206\"", |
||||||
|
// 35
|
||||||
|
"4E0A5348/4E0B5348h\"65F6\"mm\"5206\"ss\"79D2\"", |
||||||
|
// 36
|
||||||
|
"yyyy\"5E74\"m\"6708\"", |
||||||
|
// 37
|
||||||
|
"#,##0_);(#,##0)", |
||||||
|
// 38
|
||||||
|
"#,##0_);[Red](#,##0)", |
||||||
|
// 39
|
||||||
|
"#,##0.00_);(#,##0.00)", |
||||||
|
// 40
|
||||||
|
"#,##0.00_);[Red](#,##0.00)", |
||||||
|
// 41
|
||||||
|
"_(* #,##0_);_(* (#,##0);_(* \"-\"_);_(@_)", |
||||||
|
// 42
|
||||||
|
"_(\"$\"* #,##0_);_(\"$\"* (#,##0);_(\"$\"* \"-\"_);_(@_)", |
||||||
|
// 43
|
||||||
|
"_(* #,##0.00_);_(* (#,##0.00);_(* \"-\"??_);_(@_)", |
||||||
|
// 44
|
||||||
|
"_(\"$\"* #,##0.00_);_(\"$\"* (#,##0.00);_(\"$\"* \"-\"??_);_(@_)", |
||||||
|
// 45
|
||||||
|
"mm:ss", |
||||||
|
// 46
|
||||||
|
"[h]:mm:ss", |
||||||
|
// 47
|
||||||
|
"mm:ss.0", |
||||||
|
// 48
|
||||||
|
"##0.0E+0", |
||||||
|
// 49
|
||||||
|
"@", |
||||||
|
// 50
|
||||||
|
"yyyy\"5E74\"m\"6708\"", |
||||||
|
// 51
|
||||||
|
"m\"6708\"d\"65E5\"", |
||||||
|
// 52
|
||||||
|
"yyyy\"5E74\"m\"6708\"", |
||||||
|
// 53
|
||||||
|
"m\"6708\"d\"65E5\"", |
||||||
|
// 54
|
||||||
|
"m\"6708\"d\"65E5\"", |
||||||
|
// 55
|
||||||
|
"4E0A5348/4E0B5348h\"65F6\"mm\"5206\"", |
||||||
|
// 56
|
||||||
|
"4E0A5348/4E0B5348h\"65F6\"mm\"5206\"ss\"79D2\"", |
||||||
|
// 57
|
||||||
|
"yyyy\"5E74\"m\"6708\"", |
||||||
|
// 58
|
||||||
|
"m\"6708\"d\"65E5\"", |
||||||
|
// 59
|
||||||
|
"t0", |
||||||
|
// 60
|
||||||
|
"t0.00", |
||||||
|
// 61
|
||||||
|
"t#,##0", |
||||||
|
// 62
|
||||||
|
"t#,##0.00", |
||||||
|
// 63-66 No specific correspondence found in the official documentation.
|
||||||
|
// 63
|
||||||
|
null, |
||||||
|
// 64
|
||||||
|
null, |
||||||
|
// 65
|
||||||
|
null, |
||||||
|
// 66
|
||||||
|
null, |
||||||
|
// 67
|
||||||
|
"t0%", |
||||||
|
// 68
|
||||||
|
"t0.00%", |
||||||
|
// 69
|
||||||
|
"t# ?/?", |
||||||
|
// 70
|
||||||
|
"t# ??/??", |
||||||
|
// 71
|
||||||
|
"0E27/0E14/0E1B0E1B0E1B0E1B", |
||||||
|
// 72
|
||||||
|
"0E27-0E140E140E14-0E1B0E1B", |
||||||
|
// 73
|
||||||
|
"0E27-0E140E140E14", |
||||||
|
// 74
|
||||||
|
"0E140E140E14-0E1B0E1B", |
||||||
|
// 75
|
||||||
|
"0E0A:0E190E19", |
||||||
|
// 76
|
||||||
|
"0E0A:0E190E19:0E170E17", |
||||||
|
// 77
|
||||||
|
"0E27/0E14/0E1B0E1B0E1B0E1B 0E0A:0E190E19", |
||||||
|
// 78
|
||||||
|
"0E190E19:0E170E17", |
||||||
|
// 79
|
||||||
|
"[0E0A]:0E190E19:0E170E17", |
||||||
|
// 80
|
||||||
|
"0E190E19:0E170E17.0", |
||||||
|
// 81
|
||||||
|
"d/m/bb", |
||||||
|
// end
|
||||||
|
}; |
||||||
|
|
||||||
|
public static String getBuiltinFormat(Integer index) { |
||||||
|
if (index == null || index < 0 || index >= builtinFormats.length) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
return builtinFormats[index]; |
||||||
|
} |
||||||
|
|
||||||
|
public static String getFormat(Integer index, String format) { |
||||||
|
if (!StringUtils.isEmpty(format)) { |
||||||
|
return format; |
||||||
|
} |
||||||
|
return getBuiltinFormat(index); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,154 @@ |
|||||||
|
//package com.alibaba.excel.util;
|
||||||
|
//
|
||||||
|
//import java.text.Format;
|
||||||
|
//
|
||||||
|
//import org.apache.poi.ss.format.CellFormat;
|
||||||
|
//import org.apache.poi.ss.formula.ConditionalFormattingEvaluator;
|
||||||
|
//import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
//import org.apache.poi.ss.usermodel.DataFormatter;
|
||||||
|
//import org.apache.poi.ss.usermodel.DateUtil;
|
||||||
|
//import org.apache.poi.ss.usermodel.ExcelNumberFormat;
|
||||||
|
//import org.apache.poi.ss.usermodel.ExcelStyleDateFormatter;
|
||||||
|
//import org.apache.poi.util.POILogger;
|
||||||
|
//
|
||||||
|
///**
|
||||||
|
// * Convert number data, including date.
|
||||||
|
// *
|
||||||
|
// * @author Jiaju Zhuang
|
||||||
|
// **/
|
||||||
|
//public class NumberDataFormatterUtils {
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// *
|
||||||
|
// * @param data
|
||||||
|
// * Not null.
|
||||||
|
// * @param dataFormatString
|
||||||
|
// * Not null.
|
||||||
|
// * @return
|
||||||
|
// */
|
||||||
|
// public String format(Double data, Integer dataFormat, String dataFormatString) {
|
||||||
|
//
|
||||||
|
// if (DateUtil.isCellDateFormatted(cell, cfEvaluator)) {
|
||||||
|
// return getFormattedDateString(cell, cfEvaluator);
|
||||||
|
// }
|
||||||
|
// return getFormattedNumberString(cell, cfEvaluator);
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private String getFormattedDateString(Double data,String dataFormatString) {
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if (cell == null) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// Format dateFormat = getFormat(cell, cfEvaluator);
|
||||||
|
// synchronized (dateFormat) {
|
||||||
|
// if (dateFormat instanceof ExcelStyleDateFormatter) {
|
||||||
|
// // Hint about the raw excel value
|
||||||
|
// ((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted(cell.getNumericCellValue());
|
||||||
|
// }
|
||||||
|
// Date d = cell.getDateCellValue();
|
||||||
|
// return performDateFormatting(d, dateFormat);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Return a Format for the given cell if one exists, otherwise try to
|
||||||
|
// * create one. This method will return <code>null</code> if the any of the
|
||||||
|
// * following is true:
|
||||||
|
// * <ul>
|
||||||
|
// * <li>the cell's style is null</li>
|
||||||
|
// * <li>the style's data format string is null or empty</li>
|
||||||
|
// * <li>the format string cannot be recognized as either a number or date</li>
|
||||||
|
// * </ul>
|
||||||
|
// *
|
||||||
|
// * @param cell The cell to retrieve a Format for
|
||||||
|
// * @return A Format for the format String
|
||||||
|
// */
|
||||||
|
// private Format getFormat(Cell cell, ConditionalFormattingEvaluator cfEvaluator) {
|
||||||
|
// if (cell == null) return null;
|
||||||
|
//
|
||||||
|
// ExcelNumberFormat numFmt = ExcelNumberFormat.from(cell, cfEvaluator);
|
||||||
|
//
|
||||||
|
// if ( numFmt == null) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// int formatIndex = numFmt.getIdx();
|
||||||
|
// String formatStr = numFmt.getFormat();
|
||||||
|
// if(formatStr == null || formatStr.trim().length() == 0) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// return getFormat(cell.getNumericCellValue(), formatIndex, formatStr, isDate1904(cell));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private boolean isDate1904(Cell cell) {
|
||||||
|
// if ( cell != null && cell.getSheet().getWorkbook() instanceof Date1904Support) {
|
||||||
|
// return ((Date1904Support)cell.getSheet().getWorkbook()).isDate1904();
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private Format getFormat(double cellValue, int formatIndex, String formatStrIn, boolean use1904Windowing) {
|
||||||
|
// localeChangedObservable.checkForLocaleChange();
|
||||||
|
//
|
||||||
|
// // Might be better to separate out the n p and z formats, falling back to p when n and z are not set.
|
||||||
|
// // That however would require other code to be re factored.
|
||||||
|
// // String[] formatBits = formatStrIn.split(";");
|
||||||
|
// // int i = cellValue > 0.0 ? 0 : cellValue < 0.0 ? 1 : 2;
|
||||||
|
// // String formatStr = (i < formatBits.length) ? formatBits[i] : formatBits[0];
|
||||||
|
//
|
||||||
|
// String formatStr = formatStrIn;
|
||||||
|
//
|
||||||
|
// // Excel supports 2+ part conditional data formats, eg positive/negative/zero,
|
||||||
|
// // or (>1000),(>0),(0),(negative). As Java doesn't handle these kinds
|
||||||
|
// // of different formats for different ranges, just +ve/-ve, we need to
|
||||||
|
// // handle these ourselves in a special way.
|
||||||
|
// // For now, if we detect 2+ parts, we call out to CellFormat to handle it
|
||||||
|
// // TODO Going forward, we should really merge the logic between the two classes
|
||||||
|
// if (formatStr.contains(";") &&
|
||||||
|
// (formatStr.indexOf(';') != formatStr.lastIndexOf(';')
|
||||||
|
// || rangeConditionalPattern.matcher(formatStr).matches()
|
||||||
|
// ) ) {
|
||||||
|
// try {
|
||||||
|
// // Ask CellFormat to get a formatter for it
|
||||||
|
// CellFormat cfmt = CellFormat.getInstance(locale, formatStr);
|
||||||
|
// // CellFormat requires callers to identify date vs not, so do so
|
||||||
|
// Object cellValueO = Double.valueOf(cellValue);
|
||||||
|
// if (DateUtil.isADateFormat(formatIndex, formatStr) &&
|
||||||
|
// // don't try to handle Date value 0, let a 3 or 4-part format take care of it
|
||||||
|
// ((Double)cellValueO).doubleValue() != 0.0) {
|
||||||
|
// cellValueO = DateUtil.getJavaDate(cellValue, use1904Windowing);
|
||||||
|
// }
|
||||||
|
// // Wrap and return (non-cachable - CellFormat does that)
|
||||||
|
// return new DataFormatter.CellFormatResultWrapper( cfmt.apply(cellValueO) );
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// logger.log(POILogger.WARN, "Formatting failed for format " + formatStr + ", falling back", e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Excel's # with value 0 will output empty where Java will output 0. This hack removes the # from the format.
|
||||||
|
// if (emulateCSV && cellValue == 0.0 && formatStr.contains("#") && !formatStr.contains("0")) {
|
||||||
|
// formatStr = formatStr.replaceAll("#", "");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // See if we already have it cached
|
||||||
|
// Format format = formats.get(formatStr);
|
||||||
|
// if (format != null) {
|
||||||
|
// return format;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Is it one of the special built in types, General or @?
|
||||||
|
// if ("General".equalsIgnoreCase(formatStr) || "@".equals(formatStr)) {
|
||||||
|
// return generalNumberFormat;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Build a formatter, and cache it
|
||||||
|
// format = createFormat(cellValue, formatIndex, formatStr);
|
||||||
|
// formats.put(formatStr, format);
|
||||||
|
// return format;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
@ -0,0 +1,16 @@ |
|||||||
|
package com.alibaba.easyexcel.test.temp.dataformat; |
||||||
|
|
||||||
|
import com.alibaba.excel.metadata.CellData; |
||||||
|
|
||||||
|
import lombok.Data; |
||||||
|
|
||||||
|
/** |
||||||
|
* TODO |
||||||
|
* |
||||||
|
* @author 罗成 |
||||||
|
**/ |
||||||
|
@Data |
||||||
|
public class DataFormatData { |
||||||
|
private CellData<String> date; |
||||||
|
private CellData<String> num; |
||||||
|
} |
@ -0,0 +1,127 @@ |
|||||||
|
package com.alibaba.easyexcel.test.temp.dataformat; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
import java.text.SimpleDateFormat; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Date; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Cell; |
||||||
|
import org.apache.poi.ss.usermodel.DataFormatter; |
||||||
|
import org.apache.poi.ss.usermodel.DateUtil; |
||||||
|
import org.apache.poi.ss.usermodel.Sheet; |
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
||||||
|
import org.junit.Ignore; |
||||||
|
import org.junit.Test; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
import com.alibaba.easyexcel.test.temp.Lock2Test; |
||||||
|
import com.alibaba.excel.EasyExcel; |
||||||
|
import com.alibaba.fastjson.JSON; |
||||||
|
|
||||||
|
/** |
||||||
|
* 格式测试 |
||||||
|
* |
||||||
|
* @author Jiaju Zhuang |
||||||
|
**/ |
||||||
|
@Ignore |
||||||
|
public class DataFormatTest { |
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(Lock2Test.class); |
||||||
|
|
||||||
|
@Test |
||||||
|
public void test() throws Exception { |
||||||
|
File file = new File("D:\\test\\dataformat.xlsx"); |
||||||
|
|
||||||
|
List<DataFormatData> list = |
||||||
|
EasyExcel.read(file, DataFormatData.class, null).sheet().headRowNumber(0).doReadSync(); |
||||||
|
LOGGER.info("数据:{}", list.size()); |
||||||
|
for (DataFormatData data : list) { |
||||||
|
Integer dataFormat = data.getDate().getDataFormat(); |
||||||
|
|
||||||
|
String dataFormatString = data.getDate().getDataFormatString(); |
||||||
|
|
||||||
|
if (dataFormat == null || dataFormatString == null) { |
||||||
|
|
||||||
|
} else { |
||||||
|
LOGGER.info("格式化:{};{}:{}", dataFormat, dataFormatString, |
||||||
|
DateUtil.isADateFormat(dataFormat, dataFormatString)); |
||||||
|
} |
||||||
|
|
||||||
|
LOGGER.info("返回数据:{}", JSON.toJSONString(data)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void testxls() throws Exception { |
||||||
|
File file = new File("D:\\test\\dataformat.xls"); |
||||||
|
|
||||||
|
List<DataFormatData> list = |
||||||
|
EasyExcel.read(file, DataFormatData.class, null).sheet().headRowNumber(0).doReadSync(); |
||||||
|
LOGGER.info("数据:{}", list.size()); |
||||||
|
for (DataFormatData data : list) { |
||||||
|
Integer dataFormat = data.getDate().getDataFormat(); |
||||||
|
|
||||||
|
String dataFormatString = data.getDate().getDataFormatString(); |
||||||
|
|
||||||
|
if (dataFormat == null || dataFormatString == null) { |
||||||
|
|
||||||
|
} else { |
||||||
|
LOGGER.info("格式化:{};{}:{}", dataFormat, dataFormatString, |
||||||
|
DateUtil.isADateFormat(dataFormat, dataFormatString)); |
||||||
|
} |
||||||
|
|
||||||
|
LOGGER.info("返回数据:{}", JSON.toJSONString(data)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void test3() throws IOException { |
||||||
|
String file = "D:\\test\\dataformat1.xlsx"; |
||||||
|
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(file); |
||||||
|
Sheet xssfSheet = xssfWorkbook.getSheetAt(0); |
||||||
|
Cell cell = xssfSheet.getRow(0).getCell(0); |
||||||
|
DataFormatter d = new DataFormatter(); |
||||||
|
System.out.println(d.formatCellValue(cell)); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void test31() throws IOException { |
||||||
|
System.out.println(DateUtil.isADateFormat(181, "[DBNum1][$-404]m\"\u6708\"d\"\u65e5\";@")); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void test43() throws IOException { |
||||||
|
SimpleDateFormat s = new SimpleDateFormat("yyyy'年'm'月'd'日' h'点'mm'哈哈哈m'"); |
||||||
|
System.out.println(s.format(new Date())); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void test463() throws IOException { |
||||||
|
SimpleDateFormat s = new SimpleDateFormat("[$-804]yyyy年m月"); |
||||||
|
System.out.println(s.format(new Date())); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void test1() throws Exception { |
||||||
|
System.out.println(DateUtil.isADateFormat(181, "yyyy\"年啊\"m\"月\"d\"日\"\\ h")); |
||||||
|
System.out.println(DateUtil.isADateFormat(180, "yyyy\"年\"m\"月\"d\"日\"\\ h\"点\"")); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void test2() throws Exception { |
||||||
|
List<String> list1 = new ArrayList<String>(3000); |
||||||
|
long start = System.currentTimeMillis(); |
||||||
|
for (int i = 0; i < 10000; i++) { |
||||||
|
list1.clear(); |
||||||
|
} |
||||||
|
System.out.println("end:" + (System.currentTimeMillis() - start)); |
||||||
|
start = System.currentTimeMillis(); |
||||||
|
for (int i = 0; i < 10000; i++) { |
||||||
|
list1 = new ArrayList<String>(3000); |
||||||
|
} |
||||||
|
System.out.println("end:" + (System.currentTimeMillis() - start)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue