【问题标题】:LinqToExcel Not Parsing DateLinqToExcel 不解析日期
【发布时间】:2017-07-28 00:17:11
【问题描述】:

我正在与客户合作,将一个相当大的 Excel 文件(超过 37K 行)导入自定义系统,并利用出色的 LinqToExcel 库来执行此操作。在读取所有数据时,我注意到它打破了大约 80% 的记录,并进一步挖掘。它失败的原因是大多数记录(相关日期范围为 2011 - 2015)是正常的,例如1/3/2015,但是从 2016 年开始,结构变为如下所示:'1/4/2016(注意日期开头的“勾号”)并且 LinqToExcel 开始为该列返回 DBNull。

关于它为什么会这样做以及解决方法的任何想法?请注意,这不是强制转换问题 - 我可以使用即时窗口查看 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.ExcelQueryExecutorclass 失败:

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();
    }

由于他们的班级使用OleDbDataReader 来检索结果,我认为这就是找不到相关单元格值的原因。我什至不知道从那里去哪里。

【问题讨论】:

  • 是否可以清理 Excel 电子表格以使日期有效?
  • 我现在正试图从客户那里得到一个合适的,否则手动编辑将是唯一的选择,而且要修复的记录不到 5K。我更惊讶于这个值一般不能被读取。
  • 这不是我的代码 - 它是 LinqToExcel 库本身的一部分。这就是没有正确读取值的原因。
  • 你在调用 LinqToExcel 库吗?你能告诉我们那个代码吗?没有看到你的代码就很难给出建议。尽可能向我们展示(调用 LinqToExcel 的代码、您的映射、数据映射到的类等)。
  • 完成!我添加了示例代码,虽然这是那个库,但我不确定这是否有帮助。

标签: c# linq-to-excel


【解决方案1】:

找到了!一旦我追查到失败的是 OleDbDataReader 而不是 LinqToExcel 库本身,它就让我走上了一条不同的路。显然,当OleDbDataReader 读取 Excel 文件时(就像几乎所有实用程序在幕后所做的那样),会扫描前几条记录以确定与列关联的内容类型。在我的场景中,超过 2 万条记录具有“正常”日期,因此它假设一切都是日期。一旦它到达“坏”记录,日期前面的' 意味着它无法解析为日期,因此值为空。

为了避免这种情况,我加载文件并告诉它忽略列标题。由于此列的标题是一个字符串,并且大多数值是日期,因此由于类型不匹配并且我需要的值被正确加载,它使所有内容都成为字符串。从那里,我可以相应地解析并让它工作。

来源:What is IMEX in the OLEDB connection string?

【讨论】:

  • 我认为 LinqToExcel 默认忽略了第一行(标题行)。我错了吗?
  • 这是一个可选设置,是的。这方面的数据太糟糕了,我认为这不是 LinqToExcel 的错——这就是我提供的数据有多糟糕。
猜你喜欢
  • 2017-02-15
  • 1970-01-01
  • 1970-01-01
  • 2016-01-10
  • 2013-08-13
  • 2016-04-30
  • 2013-07-10
  • 1970-01-01
  • 2023-03-28
相关资源
最近更新 更多