使用EPPlus导入Excel至SQL Server:日期值格式统一需求
解决方案
可以统一将日期/时间列的值转换为双精度类型(OLE自动化日期)——这是Excel存储日期的原始格式:整数部分代表从1900年1月0日开始的天数,小数部分代表一天内的时间占比(比如0.5对应中午12点)。以下是修改后的代码和关键逻辑说明:
核心处理逻辑
- 若EPPlus返回整数/双精度值:直接保留,这本身就是Excel日期的原始数值。
- 若返回日期字符串:先解析为
DateTime对象,再通过DateTime.ToOADate()转为对应的双精度数值。
修改后的代码
for (int row = 2; row <= sheet.Dimension.Rows; row++) { var obj = Activator.CreateInstance(typeof(T)); foreach(var prop in typeof(T).GetProperties()) { if (!string.IsNullOrWhiteSpace(prop.Name)) { var column = columnInfo.SingleOrDefault(c => !string.IsNullOrWhiteSpace(c.ColumnName) && c.ColumnName.Trim() == prop.Name.Trim()); if (column != null) { int col = column.Index; var cell = sheet.Cells[row, col]; double? oleDateValue = null; var propType = prop.PropertyType; if (cell.Value != null) { // 处理整数/双精度类型的日期值 if (cell.Value is int intVal) { oleDateValue = (double)intVal; } else if (cell.Value is double doubleVal) { oleDateValue = doubleVal; } // 处理字符串格式的日期,尝试解析为DateTime后转OLE数值 else if (cell.Value is string strVal && DateTime.TryParse(strVal, out DateTime dateTimeVal)) { oleDateValue = dateTimeVal.ToOADate(); } } // 根据目标属性类型赋值 if (oleDateValue.HasValue) { if (propType == typeof(int)) { // 仅保留日期部分的整数(舍去时间小数) prop.SetValue(obj, (int)Math.Floor(oleDateValue.Value)); } else if (propType == typeof(double)) { // 保留完整的日期+时间数值 prop.SetValue(obj, oleDateValue.Value); } else if (propType == typeof(DateTime)) { // 若目标属性是DateTime,可直接转回日期对象 prop.SetValue(obj, DateTime.FromOADate(oleDateValue.Value)); } else { // 其他类型的通用转换 prop.SetValue(obj, Convert.ChangeType(oleDateValue.Value, propType)); } } else { // 处理空值:值类型赋默认值,引用类型赋null prop.SetValue(obj, propType.IsValueType ? Activator.CreateInstance(propType) : null); } } } } if (obj != null) { list.Add((T)obj); } }
关键说明
- 避免格式依赖:跳过直接调用
Value.ToString()的步骤,直接处理原始值类型,避免因单元格格式不同导致的返回值差异。 - 容错处理:用
DateTime.TryParse解析字符串,避免无效日期格式抛出异常。 - 灵活适配:根据实体类属性类型选择最终赋值类型,既可以统一为整数/双精度,也可以直接转回
DateTime。
内容的提问来源于stack exchange,提问作者user2260526
相关产品推荐
相关产品推荐

