LinqToExcel 不解析日期
LinqToExcel Not Parsing Date
我正在与客户合作,将一个相当大的 Excel 文件(超过 37K 行)导入自定义系统,并利用出色的 LinqToExcel 库来完成此操作。在读取所有数据时,我注意到它打破了大约 80% 的记录并进一步挖掘。它失败的原因是大多数记录(相关日期范围为 2011 - 2015)都是正常的,例如1/3/2015
,但是从 2016 年开始,结构变为如下所示:'1/4/2016
(注意日期开头的 "tick")并且 LinqToExcel 开始返回 DBNull对于那个专栏。
关于它为什么会这样做以及解决方法的任何想法?请注意,这不是转换问题 - 我可以使用 Immediate Window 查看 LinqToExcel.Row
值的所有值以及该列索引所在的位置,它是空的。
编辑
这是我用来读取文件的代码:
var excel = new LinqToExcel.ExcelQueryFactory(Path.Combine(this.FilePath, this.CurrentFilename));
foreach (var row in excel.Worksheet(file.WorksheetName))
{
data.Add(this.FillEntity(row));
}
我指的问题在 row
变量内部,它是一个 LinqToExcel.Row
实例,包含来自 Excel 的原始数据。 row
中的值全部排成一行,日期列除外,该列为空。
** 编辑 2 **
我从 GitHub 下载了 LinqToExcel 代码并将其连接到我的项目,看起来问题比这个库更深。它使用 IDataReader
读取所有值,并且未被读取的相关单元格从该级别开始为空。这是来自
LinqToExcel.ExcelQueryExecutor
class 失败:
private IEnumerable<object> GetRowResults(IDataReader data, IEnumerable<string> columns)
{
var results = new List<object>();
var columnIndexMapping = new Dictionary<string, int>();
for (var i = 0; i < columns.Count(); i++)
columnIndexMapping[columns.ElementAt(i)] = i;
while (data.Read())
{
IList<Cell> cells = new List<Cell>();
for (var i = 0; i < columns.Count(); i++)
{
var value = data[i];
//I added this in, since the worksheet has over 37K rows and
//I needed to snag right before it hit the values I was looking for
//to see what the IDataReader was exposing. The row inside the
//IDataReader relevant to the column I'm referencing is null,
//even though the data definitely exists in the Excel file
if (value.GetType() == typeof(DateTime) && value.Cast<DateTime>() == new DateTime(2015, 12, 31))
{
}
value = TrimStringValue(value);
cells.Add(new Cell(value));
}
results.CallMethod("Add", new Row(cells, columnIndexMapping));
}
return results.AsEnumerable();
}
由于他们的 class 使用 OleDbDataReader
检索结果,我认为这就是无法找到相关单元格值的原因。我什至不知道从那里去哪里。
找到了!一旦我发现失败的是 OleDbDataReader
而不是 LinqToExcel 库本身,它就让我走上了一条不同的道路去环顾四周。显然,当 Excel 文件被 OleDbDataReader
读取时(实际上所有实用程序都在幕后进行),将扫描前几条记录以确定与该列关联的内容类型。在我的场景中,超过 20K 条记录有 "normal" 日期,因此它假定所有内容都是日期。到了"bad"条记录后,日期前的'
表示无法解析为日期,所以值为null。
为了避免这种情况,我加载了文件并告诉它忽略第 header 列。由于此列的 header 是一个字符串并且大部分值是日期,因此由于类型不匹配并且我需要的值已正确加载,所以它使所有内容都成为字符串。从那里,我可以相应地解析并让它工作。
我正在与客户合作,将一个相当大的 Excel 文件(超过 37K 行)导入自定义系统,并利用出色的 LinqToExcel 库来完成此操作。在读取所有数据时,我注意到它打破了大约 80% 的记录并进一步挖掘。它失败的原因是大多数记录(相关日期范围为 2011 - 2015)都是正常的,例如1/3/2015
,但是从 2016 年开始,结构变为如下所示:'1/4/2016
(注意日期开头的 "tick")并且 LinqToExcel 开始返回 DBNull对于那个专栏。
关于它为什么会这样做以及解决方法的任何想法?请注意,这不是转换问题 - 我可以使用 Immediate Window 查看 LinqToExcel.Row
值的所有值以及该列索引所在的位置,它是空的。
编辑
这是我用来读取文件的代码:
var excel = new LinqToExcel.ExcelQueryFactory(Path.Combine(this.FilePath, this.CurrentFilename));
foreach (var row in excel.Worksheet(file.WorksheetName))
{
data.Add(this.FillEntity(row));
}
我指的问题在 row
变量内部,它是一个 LinqToExcel.Row
实例,包含来自 Excel 的原始数据。 row
中的值全部排成一行,日期列除外,该列为空。
** 编辑 2 **
我从 GitHub 下载了 LinqToExcel 代码并将其连接到我的项目,看起来问题比这个库更深。它使用 IDataReader
读取所有值,并且未被读取的相关单元格从该级别开始为空。这是来自
LinqToExcel.ExcelQueryExecutor
class 失败:
private IEnumerable<object> GetRowResults(IDataReader data, IEnumerable<string> columns)
{
var results = new List<object>();
var columnIndexMapping = new Dictionary<string, int>();
for (var i = 0; i < columns.Count(); i++)
columnIndexMapping[columns.ElementAt(i)] = i;
while (data.Read())
{
IList<Cell> cells = new List<Cell>();
for (var i = 0; i < columns.Count(); i++)
{
var value = data[i];
//I added this in, since the worksheet has over 37K rows and
//I needed to snag right before it hit the values I was looking for
//to see what the IDataReader was exposing. The row inside the
//IDataReader relevant to the column I'm referencing is null,
//even though the data definitely exists in the Excel file
if (value.GetType() == typeof(DateTime) && value.Cast<DateTime>() == new DateTime(2015, 12, 31))
{
}
value = TrimStringValue(value);
cells.Add(new Cell(value));
}
results.CallMethod("Add", new Row(cells, columnIndexMapping));
}
return results.AsEnumerable();
}
由于他们的 class 使用 OleDbDataReader
检索结果,我认为这就是无法找到相关单元格值的原因。我什至不知道从那里去哪里。
找到了!一旦我发现失败的是 OleDbDataReader
而不是 LinqToExcel 库本身,它就让我走上了一条不同的道路去环顾四周。显然,当 Excel 文件被 OleDbDataReader
读取时(实际上所有实用程序都在幕后进行),将扫描前几条记录以确定与该列关联的内容类型。在我的场景中,超过 20K 条记录有 "normal" 日期,因此它假定所有内容都是日期。到了"bad"条记录后,日期前的'
表示无法解析为日期,所以值为null。
为了避免这种情况,我加载了文件并告诉它忽略第 header 列。由于此列的 header 是一个字符串并且大部分值是日期,因此由于类型不匹配并且我需要的值已正确加载,所以它使所有内容都成为字符串。从那里,我可以相应地解析并让它工作。