最近要幫客戶寫個小工具,來對多個Excel文件進行數據匯總,其中主要涉及到對數據的讀取和分類,在讀取數據時就遇到了好幾個坑,這里主要說下日期類型數據的讀取
NPOI內置的單元格值類型有Unknown、Numeric、String、Formula、Blank、Boolean、Error,但是其中沒有日期類型,最開始我的取單元格值的方法如下:
switch (cell.CellType)
{
case CellType.String:
return cell.StringCellValue;
case CellType.Numeric:
return cell.NumericCellValue;
case CellType.Boolean:
return cell.BooleanCellValue;
case CellType.Error:
return cell.ErrorCellValue;
case CellType.Formula:
BaseFormulaEvaluator evaluator;
if (sheet is XSSFSheet)
{
evaluator = new XSSFFormulaEvaluator(sheet.Workbook);
}
else
{
evaluator = new HSSFFormulaEvaluator(sheet.Workbook);
}
var formulaValue = evaluator.Evaluate(cell);
if (formulaValue.CellType == CellType.Numeric)
{
return formulaValue.NumberValue;
}
else if (formulaValue.CellType == CellType.String)
{
return formulaValue.StringValue;
}
return cell.ToString();
default:
return cell.ToString();
}
測試時發現,日期類型的單元格在代碼中獲取到的CellType為Numeric,最后獲取到的是一個數字,不是日期,翻了源碼,找到了一個類DateUtil,里面提供了一個方法IsCellDateFormatted可以判斷單元格的值是不是日期類型,還提供了一個方法GetJavaDate可以把獲取到的數字轉化成日期格式,所以我對代碼進行了修改
switch (cell.CellType)
{
case CellType.String:
return cell.StringCellValue;
case CellType.Numeric:
if (DateUtil.IsCellDateFormatted(cell))
{
return cell.DateCellValue;
}
return cell.NumericCellValue;
case CellType.Boolean:
return cell.BooleanCellValue;
case CellType.Error:
return cell.ErrorCellValue;
case CellType.Formula:
BaseFormulaEvaluator evaluator;
if (sheet is XSSFSheet)
{
evaluator = new XSSFFormulaEvaluator(sheet.Workbook);
}
else
{
evaluator = new HSSFFormulaEvaluator(sheet.Workbook);
}
var formulaValue = evaluator.Evaluate(cell);
if (formulaValue.CellType == CellType.Numeric)
{
return formulaValue.NumberValue;
}
else if (formulaValue.CellType == CellType.String)
{
return formulaValue.StringValue;
}
return cell.ToString();
default:
return cell.ToString();
}
