如何获取包含日期的单元格的值,并使用NPOI保持原始格式

本文关键字:NPOI 格式 原始 单元格 何获取 获取 日期 包含 | 更新日期: 2023-09-27 18:16:33

我有一个Excel文件,我使用DevExpress编辑,我正在使用NPOI阅读。当我尝试以字符串形式获取日期单元格的值时,它不会保留原始值。

例如

:在DevExpress网格中,我设置了这个值:2016-08-12。我想在我的字符串中获得相同的值,但我得到了42689

获取单元格值的代码如下:

    ICell cell = row.GetCell(i);
    cell.SetCellType(CellType.String);
    string fieldString = cell.StringCellValue;
    result = result + ";" + FieldValue; 

如何获得原始的格式化日期值?

如何获取包含日期的单元格的值,并使用NPOI保持原始格式

在Excel中,日期以数字形式存储。如果希望获得格式化的日期,则需要检查单元格是否包含日期(有一个实用程序方法用于此),然后获取单元格的日期值,获取数据格式,最后使用该格式将日期转换为字符串。你不应该强迫CellType字符串,否则你将不再能够告诉单元格原来举行了一个日期。我建议使用如下的扩展方法来根据单元格的类型获取已格式化的单元格值:

using NPOI.SS.UserModel;
public static class NpoiExtensions
{
    public static string GetFormattedCellValue(this ICell cell, IFormulaEvaluator eval = null)
    {
        if (cell != null)
        {
            switch (cell.CellType)
            {
                case CellType.String:
                    return cell.StringCellValue;
                case CellType.Numeric:
                    if (DateUtil.IsCellDateFormatted(cell))
                    {
                        DateTime date = cell.DateCellValue;
                        ICellStyle style = cell.CellStyle;
                        // Excel uses lowercase m for month whereas .Net uses uppercase
                        string format = style.GetDataFormatString().Replace('m', 'M');
                        return date.ToString(format);
                    }
                    else
                    {
                        return cell.NumericCellValue.ToString();
                    }
                case CellType.Boolean:
                    return cell.BooleanCellValue ? "TRUE" : "FALSE";
                case CellType.Formula:
                    if (eval != null)
                        return GetFormattedCellValue(eval.EvaluateInCell(cell));
                    else
                        return cell.CellFormula;
                case CellType.Error:
                    return FormulaError.ForInt(cell.ErrorCellValue).String;
            }
        }
        // null or blank cell, or unknown cell type
        return string.Empty;
    }
}

然后,像这样使用:

ICell cell = row.GetCell(i);
string fieldString = cell.GetFormattedCellValue();
result = result + ";" + FieldValue;

可选:如果单元格中有任何公式,并且希望对这些公式进行计算,则根据工作簿类型创建IFormulaEvaluator,并将计算器传递给GetFormattedCellValue()方法。例如:

IFormulaEvaluator eval;
if (workbook is XSSFWorkbook)
    eval = new XSSFFormulaEvaluator(workbook);
else
    eval = new HSSFFormulaEvaluator(workbook);
...
ICell cell = row.GetCell(i);
string fieldString = cell.GetFormattedCellValue(eval);
result = result + ";" + FieldValue;

您可以使用此代码。DateTime.FromOADate(row.Cells[0].NumericCellValue)

如果文件有自定义的格式化日期,则需要测试这些日期,否则该函数将返回一个数字。这个版本的布莱恩·罗杰斯的回答将检查:

 public static string GetFormattedCellValue(this ICell cell, IFormulaEvaluator eval = null)
    {
        // https://github.com/tonyqus/npoi/blob/master/main/SS/UserModel/BuiltinFormats.cs
        //*The first user-defined format starts at 164.
        //  var dataformatNumber = cell.CellStyle.DataFormat;
        //var formatstring = cell.CellStyle.GetDataFormatString();
        //e.g. m/d/yyyy' h:mm:ss' ' AM/PM' #164
        //e.g m/d/yyyy' hh:mm  #165
        if (cell != null)
        {
            switch (cell.CellType)
            {
                case CellType.String:
                    return cell.StringCellValue;
                case CellType.Numeric:
                    if (DateUtil.IsCellDateFormatted(cell))
                    {
                        DateTime date = cell.DateCellValue;
                        ICellStyle style = cell.CellStyle;
                        // Excel uses lowercase m for month whereas .Net uses uppercase
                        string format = style.GetDataFormatString().Replace('m', 'M');
                        return date.ToString(format);
                    }
                    else if(cell.CellStyle.DataFormat>=164 && DateUtil.IsValidExcelDate(cell.NumericCellValue) && cell.DateCellValue != null)
                    {
                        return cell.DateCellValue.ToString();
                    }
                    else
                    {
                        return cell.NumericCellValue.ToString();
                    }
                case CellType.Boolean:
                    return cell.BooleanCellValue ? "TRUE" : "FALSE";
                case CellType.Formula:
                    if (eval != null)
                        return GetFormattedCellValue(eval.EvaluateInCell(cell));
                    else
                        return cell.CellFormula;
                case CellType.Error:
                    return FormulaError.ForInt(cell.ErrorCellValue).String;
            }
        }
        // null or blank cell, or unknown cell type
        return string.Empty;
    }