【问题标题】:LinqToExcel returning blank rows for .csv filesLinqToExcel 返回 .csv 文件的空白行
【发布时间】:2020-12-10 16:30:20
【问题描述】:

一段时间以来,我一直在使用 LinqToExcel 从 .xlsx 文件中成功导入数据。然而,最近,我收到了一个无法读取数据的 .csv 文件。

假设文件包含以下数据:

Col1 Col2 Col3
 A    B    C
 D    E    F

我已经创建了一个用于映射列的类:

public class Test
{
    [ExcelColumn("Col1")]
    public string Col1 { get; set; }

    [ExcelColumn("Col2")]
    public string Col2 { get; set; }

    [ExcelColumn("Col3")] 
    public string Col3 { get; set; }
}

然后我尝试像这样读取数据:

var test = from c in excel.Worksheet<Test>()
           select c;

查询成功返回两个Test-objects,但所有属性值为null。

我什至尝试在没有类和标题的情况下读取数据:

var test = from c in excel.WorksheetNoHeader()
select c;

在这种情况下,查询还返回两行,均包含三个单元格/值。但同样所有这些值都是空的。这可能是什么问题?

我还应该注意,该文件在 Excel 中打开并且看起来非常好。此外,使用 StreamReader,我可以读取它的所有行和值。

【问题讨论】:

    标签: c# csv linq-to-excel


    【解决方案1】:

    每一列中的数据类型是什么? (字符串,数字,...)

    根据Initializing the Microsoft Excel driver

    TypeGuessRows

    要检查数据类型的行数。数据类型是 给定找到的最大数据种类数。如果有 是平局,数据类型按以下顺序确定:数字, 货币、日期、文本、布尔值。如果遇到不 匹配为该列猜测的数据类型,它作为 Null 返回 价值。导入时,如果列具有混合数据类型,则整个列 将根据 ImportMixedTypes 设置进行转换。默认 要检查的行数为 8。值的类型为 REG_DWORD。

    见帖子Can I specify the data type for a column rather than letting linq-to-excel decide?

    Setting TypeGuessRows for excel ACE Driver 帖子说明了如何更改 TypeGuessRows 的值。

    当驱动程序确定 Excel 列包含文本数据时, 驱动程序根据最长选择数据类型(字符串或备忘录) 它采样的值。如果驱动程序没有发现任何值 在它采样的行中超过 255 个字符,它会将 列作为 255 个字符的字符串列,而不是备注列。 因此,超过 255 个字符的值可能会被截断。到 从没有截断的备忘录列中导入数据,您必须确保 至少其中一个采样行中的备忘录列包含 值超过 255 个字符,否则您必须增加 由驱动程序采样的行以包含这样的行。你可以增加 通过增加 TypeGuessRows 的值来采样的行数 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel 注册表项。

    我们需要记住的另一件事是注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Excel\TypeGuessRows 仅适用于 Excel 97-2003。对于 Excel 2007 及更高版本, Excel Open XML(.XLSX 扩展名)实际上使用 ACE OLE DB 提供程序 而是 JET 提供商。如果要将文件扩展名保留为 .XLSX, 您需要根据您的 Excel 修改以下注册表项 版本:

    Excel 2007:HKEY_LOCAL_MACHINE\Software\Microsoft\Office\12.0\Access 连接引擎\Engines\Excel\TypeGuessRows Excel 2010: HKEY_LOCAL_MACHINE\Software\Microsoft\Office\14.0\Access 连接 引擎\引擎\Excel\TypeGuessRows Excel 2013: HKEY_LOCAL_MACHINE\Software\Microsoft\Office\15.0\Access 连接 Engine\Engines\Excel\TypeGuessRows

    【讨论】:

    • 这似乎是我的确切问题。所有单元格都具有“常规”格式,但大多数列包含文本而不是数字。我尝试打开文件并将格式设置为“文本”,然后 LinqToExcel 能够读取数据!但是,通常情况下,我无法打开文件并手动更改它。我也不能更改注册表。那么我该如何解决这个问题呢?
    • 你考虑过使用Nuget包DocumentFormat.OpenXml吗?
    • 我最终改用 Nuget 包 CsvReader 来处理我的 .csv 文件。
    【解决方案2】:

    您是否尝试通过最后调用ToListToArray 来实现您的查询?

    我尝试重新创建您的案例,并且使用以下代码 sn-p 从 Excel 文件中读取数据没有问题:

    var excel = new ExcelQueryFactory(FilePath);
    List<Test> tests = (
        from c in excel.Worksheet<Test>()
        select c
    )
    .ToList();
    

    它返回两个对象,所有属性都正确填充。

    一件小事,当我最初添加ToList 时,出现以下异常:

    The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.'
    

    根据他们在the official docs 中的说法,这似乎是合理的,因为我的机器上缺少Microsoft Access Database Engine 2010 Distributable

    【讨论】:

    • 是的,ToList() 也是同样的问题。我的机器上有 Microsoft Access Database Engine 2010 Distributable(没有错误)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    相关资源
    最近更新 更多