无法使用 OLEDB 从 CSV 获取所有列的值

Posted

技术标签:

【中文标题】无法使用 OLEDB 从 CSV 获取所有列的值【英文标题】:Unable get value of all columns from CSV using OLEDB 【发布时间】:2018-01-12 14:17:46 【问题描述】:

我正在使用 OLEDB 将 CSV 文件解析为 DataTable。它工作正常,但是当 CSV 中的某些值包含双引号(“)时会产生问题。OLEDB 会跳过该行中下一个剩余列的值。

例如,我在 CSV 文件中有以下值。这里第二行 Col2 的值包含双引号(“)。

当我将 CSV 解析为 DataTable 时,DataTable 包含以下值。这里第二行空白处是col3col4的值。

我正在使用以下连接字符串

"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties='text;HDR=Yes;IMEX=1;ColNameHeader=True;CharacterSet=65001;FMT=Delimited(,)'"

查询是

"select * from [" + fileName + "]"

这是完整的代码

string connStr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties='text;HDR=Yes;IMEX=1;ColNameHeader=True;CharacterSet=65001;FMT=Delimited(,)'";
using (OleDbConnection conn = new OleDbConnection(connStr))

    conn.Open();
    table = new DataTable();
    var dataAdapter = new OleDbDataAdapter("select * from [" + fileName + "]", conn);
    dataAdapter.Fill(table);

如何忽略值中的双引号(“)?

注意:我是从第三方下载的文件,直接使用这个 CSV 进行解析。

【问题讨论】:

它在 visualbasic 命名空间中,但肯定可以在 c# 中使用。有一个名为 TextFieldParser 的类可以轻松处理 CSV。 msdn.microsoft.com/en-us/library/… 可以试试这个而不是 oledb? @Jeremy - 它适用于文件大小 > 300MB 吗? 它的构造函数脱离了标准的 .NET 流对象,因此您可以使用最适合您的情况的任何流策略。 【参考方案1】:

您需要创建 schema.ini 文件并将其放置在与您从中提取数据的文件相同的目录中。在其中,您必须将 TextDelimiterFormat 提供给 csv 文件。将TextDelimiter 设置为none

[YOURCSVFILENAME.csv]
ColNameHeader=True
Format=CSVDelimited
TextDelimiter=none

希望这会有所帮助。

更新: 动态创建 schema.ini 文件...

  string csvFilePath = /* CSV file directory */
  string csvFileName = /* CSV file name */
  using (FileStream sr = new FileStream(csvFilePath + "\\schema.ini", 
      FileMode.Create, FileAccess.Write)) 
   
      using (StreamWriter writer=new StreamWriter(sr)) 
       
          writer.WriteLine("[" + csvFileName + "]"); 
          writer.WriteLine("ColNameHeader=True"); 
          writer.WriteLine("Format=CSVDelimited"); 
          writer.WriteLine("TextDelimiter=none"); 
          writer.Close(); 
          writer.Dispose(); 
       
   

【讨论】:

CSV 文件名是动态的。 CSV 文件名基于当前日期。那么如何在模式文件中提供动态文件名呢? 而且我正在从一个文件夹中读取多个不同格式的 CSV 文件。 在这种情况下,您必须在打开连接和查询之前动态创建 schema.ini 文件。有关示例代码,请参阅上面的更新。

以上是关于无法使用 OLEDB 从 CSV 获取所有列的值的主要内容,如果未能解决你的问题,请参考以下文章

OleDB读取Myxls生成的Excel文本,结果只能读取到第一列的值

使用特定于列的重复过滤器在 Python 中将行附加到 CSV

无法使用 spark scala 从数据集中的行中获取第一列的值

获取DataTable中隐藏列的值

仅从csv文件c#中读取特定列[重复]

告诉我 OLEDB 数据阅读器读取 excel 文件列的最大限制是多少?