C#使用EPPlus读取Excel日期显示为浮点数,如何正确转换?
解决EPPlus读取Excel日期显示为浮点数并在DataGridView中正确展示的问题
问题说明
Excel文件第一列日期格式为dd.MM.yyyy hh:mm:ss,使用EPPlus读取并绑定到DataGridView时,日期显示为浮点数(如44912,0912268519)。尝试通过worksheet.Cells[2, 1, endCell.Row, 1].Style.Numberformat.Format = "dd.MM.yyyy hh:mm:ss";修改格式无效,因为该操作仅修改Excel单元格的显示格式,不会改变读取到的底层值类型。
核心原因
Excel中的日期本质是存储为OLE自动化日期:整数部分代表1900年1月1日以来的天数,小数部分代表当天的时分秒占比。EPPlus读取这类单元格时,默认返回double类型的浮点数,而非DateTime对象;直接使用ExcelTable.ToDataTable()也会保留这个数值类型,导致DataGridView显示原始浮点数。
解决方案
方法1:手动构建DataTable,转换日期列值
放弃ExcelTable.ToDataTable()的自动转换,手动遍历单元格,将日期列的浮点数转换为DateTime类型:
public static DataTable readTableFromExcel(FileInfo file) { DataTable table = new DataTable(); using (ExcelPackage package = new ExcelPackage(file)) { ExcelPackage.LicenseContext = LicenseContext.NonCommercial; ExcelWorksheet worksheet = package.Workbook.Worksheets[0]; ExcelCellAddress startCell = worksheet.Dimension.Start; ExcelCellAddress endCell = worksheet.Dimension.End; // 添加表头 for (int col = startCell.Column; col <= endCell.Column; col++) { table.Columns.Add(worksheet.Cells[startCell.Row, col].Text); } // 遍历数据行 for (int row = startCell.Row + 1; row <= endCell.Row; row++) { DataRow dataRow = table.NewRow(); for (int col = startCell.Column; col <= endCell.Column; col++) { var cellValue = worksheet.Cells[row, col].Value; // 判断是否为第一列(日期列),转换为DateTime if (col == 1 && cellValue is double dateValue) { dataRow[col - 1] = DateTime.FromOADate(dateValue); } else { dataRow[col - 1] = cellValue ?? DBNull.Value; } } table.Rows.Add(dataRow); } } return table; }
方法2:设置DataGridView列的显示格式
即使DataTable中存储的是DateTime类型,还需给DataGridView的日期列指定显示格式,确保展示为dd.MM.yyyy hh:mm:ss:
// 绑定数据源后设置列格式 tableView.DataSource = table; // 假设第一列是日期列 tableView.Columns[0].DefaultCellStyle.Format = "dd.MM.yyyy HH:mm:ss"; tableView.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
补充说明
如果不确定哪一列是日期列,可以通过判断单元格的Style.Numberformat.Format是否为日期格式来动态处理:
if (worksheet.Cells[row, col].Style.Numberformat.Format.Contains("dd") || worksheet.Cells[row, col].Style.Numberformat.Format.Contains("MM") || worksheet.Cells[row, col].Style.Numberformat.Format.Contains("yyyy")) { if (cellValue is double dateValue) { dataRow[col - 1] = DateTime.FromOADate(dateValue); } }
内容的提问来源于stack exchange,提问作者Anna Shevchenko
相关产品推荐
相关产品推荐

