【问题标题】:CSV parser to parse double quotes via OLEDBCSV 解析器通过 OLEDB 解析双引号
【发布时间】:2011-12-12 20:43:33
【问题描述】:

如何使用 OLEDB 解析和导入每个单元格都用双引号括起来的 CSV 文件,因为有些行中包含逗号?我无法更改格式,因为它来自供应商。

我正在尝试以下操作,但由于 IO 错误而失败:

public DataTable ConvertToDataTable(string fileToImport, string fileDestination)
{
    string fullImportPath = fileDestination + @"\" + fileToImport;
    OleDbDataAdapter dAdapter = null;
    DataTable dTable = null;

    try
    {
        if (!File.Exists(fullImportPath))
            return null;

        string full = Path.GetFullPath(fullImportPath);
        string file = Path.GetFileName(full);
        string dir = Path.GetDirectoryName(full);


        //create the "database" connection string
        string connString = "Provider=Microsoft.Jet.OLEDB.4.0;"
          + "Data Source=\"" + dir + "\\\";"
          + "Extended Properties=\"text;HDR=No;FMT=Delimited\"";

        //create the database query
        string query = "SELECT * FROM " + file;

        //create a DataTable to hold the query results
        dTable = new DataTable();

        //create an OleDbDataAdapter to execute the query
        dAdapter = new OleDbDataAdapter(query, connString);


        //fill the DataTable
        dAdapter.Fill(dTable);
    }
    catch (Exception ex)
    {
        throw new Exception(CLASS_NAME + ".ConvertToDataTable: Caught Exception: " + ex);
    }
    finally
    {
        if (dAdapter != null)
            dAdapter.Dispose();
    }

    return dTable;
}

当我使用普通的 CSV 时,它可以正常工作。我需要更改 connString 中的某些内容吗??

【问题讨论】:

  • 关于错误的更多信息?
  • @Christopher rathermel 这是一个 IErrorInfo.GetDescription 失败异常

标签: c# parsing csv datatable


【解决方案1】:

看看FileHelpers.

【讨论】:

    【解决方案2】:

    在这里尝试我的答案中的代码:

    Reading CSV files in C#

    它可以很好地处理引用的 csv。

    【讨论】:

    • 我知道你知道关闭作为重复功能!
    • @Ben 对于什么是精确重复,我的看法非常狭隘。他可能对他有其他限制,要求他使用 OleDb 解析器,然后将问题缩小到引用包含文本的问题。我不记得以前看过那个具体的问题。
    • @user 看看 Microsoft.VisualBasic.TextFieldParser。它内置于 .Net。
    • 所以我一直试图让 TextFieldParser 工作,但我被困在它仍在读它的地方。我有它 HasFieldsEncosedinQuotes = true ,分隔符是“,”。有什么想法吗?
    【解决方案3】:

    使用专用的 CSV 解析器。

    那里有很多。一个流行的是FileHelpers,尽管Microsoft.VisualBasic.FileIO 命名空间中隐藏了一个 - TextFieldParser

    【讨论】:

    • 谢谢。那么可以不使用OLDB吗?如果可能的话,我宁愿不使用第三方并留在框架内。
    【解决方案4】:

    万一有人有类似的问题,我想发布我使用的代码。我最终确实使用 Textparser 来获取文件并解析列,但我使用 recrusion 来完成其余的工作和子字符串。

     /// <summary>
            /// Parses each string passed as a "row".
            /// This routine accounts for both double quotes
            /// as well as commas currently, but can be added to
            /// </summary>
            /// <param name="row"> string or row to be parsed</param>
            /// <returns></returns>
            private List<String> ParseRowToList(String row)
            {
                List<String> returnValue = new List<String>();
    
                if (row[0] == '\"')
                {// Quoted String
                    if (row.IndexOf("\",") > -1)
                    {// There are more columns
                        returnValue = ParseRowToList(row.Substring(row.IndexOf("\",") + 2));
                        returnValue.Insert(0, row.Substring(1, row.IndexOf("\",") - 1));
                    }
                    else
                    {// This is the last column
                        returnValue.Add(row.Substring(1, row.Length - 2));
                    }
                }
                else
                {// Unquoted String
                    if (row.IndexOf(",") > -1)
                    {// There are more columns
                        returnValue = ParseRowToList(row.Substring(row.IndexOf(",") + 1));
                        returnValue.Insert(0, row.Substring(0, row.IndexOf(",")));
                    }
                    else
                    {// This is the last column
                        returnValue.Add(row.Substring(0, row.Length));
                    }
                }
    
                return returnValue;
    
            }
    

    那么Textparser的代码是:

     // string pathFile = @"C:\TestFTP\TestCatalog.txt";
                string pathFile = @"C:\TestFTP\SomeFile.csv";
    
                List<String> stringList = new List<String>();
                TextFieldParser fieldParser = null;
                DataTable dtable = new DataTable();
    
                /* Set up TextFieldParser
                    *  use the correct delimiter provided
                    *  and path */
                fieldParser = new TextFieldParser(pathFile);
                /* Set that there are quotes in the file for fields and or column names */
                fieldParser.HasFieldsEnclosedInQuotes = true;
    
                /* delimiter by default to be used first */
                fieldParser.SetDelimiters(new string[] { "," });
    
                // Build Full table to be imported
                dtable = BuildDataTable(fieldParser, dtable);
    

    【讨论】:

    • 如果人们能解释为什么他们投反对票的答案会很好..它回答了我自己的问题,不知道如何才能投反对票
    【解决方案5】:

    这是我在一个项目中使用的,解析单行数据。

        private string[] csvParser(string csv, char separator = ',')
        {
            List <string> parsed = new List<string>();
            string[] temp = csv.Split(separator);
            int counter = 0;
            string data = string.Empty;
            while (counter < temp.Length)
            {
                data = temp[counter].Trim();
                if (data.Trim().StartsWith("\""))
                {
                    bool isLast = false;
                    while (!isLast && counter < temp.Length)
                    {
                        data += separator.ToString() + temp[counter + 1];
                        counter++;
                        isLast = (temp[counter].Trim().EndsWith("\""));
                    }
                }
                parsed.Add(data);
                counter++;
            }
    
            return parsed.ToArray();
    
        }
    

    http://zamirsblog.blogspot.com/2013/09/c-csv-parser-csvparser.html

    【讨论】:

    • 甚至没有关闭,不要浪费你的时间!作者应该测试一下。
    【解决方案6】:

    您可以使用此代码:MS office required

      private void ConvertCSVtoExcel(string filePath = @"E:\nucc_taxonomy_140.csv", string tableName = "TempTaxonomyCodes")
        {
            string tempPath = System.IO.Path.GetDirectoryName(filePath);
            string strConn = @"Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" + tempPath + @"\;Extensions=asc,csv,tab,txt";
            OdbcConnection conn = new OdbcConnection(strConn);
            OdbcDataAdapter da = new OdbcDataAdapter("Select * from " + System.IO.Path.GetFileName(filePath), conn);
            DataTable dt = new DataTable();
            da.Fill(dt);
    
            using (SqlBulkCopy bulkCopy = new SqlBulkCopy(ConfigurationSettings.AppSettings["dbConnectionString"]))
            {
                bulkCopy.DestinationTableName = tableName;
                bulkCopy.BatchSize = 50;
                bulkCopy.WriteToServer(dt);
            }
    
        }
    

    【讨论】:

    • 需要更多类似 mssql。
    【解决方案7】:

    在处理 CSV 文件时需要考虑很多因素。无论您从文件中提取它们,您都应该知道如何处理解析。有一些课程可以让你分道扬镳,但大多数课程并没有处理 Excel 对嵌入逗号、引号和换行符所做的细微差别。但是,如果您只想解析像 CSV 这样的 txt 文件,加载 Excel 或 MS 类的开销似乎很大。

    您可以考虑的一件事是在您自己的正则表达式中进行解析,这也将使您的代码更加独立于平台,以防您在某些时候需要将其移植到另一个服务器或应用程序。使用正则表达式的好处是几乎可以在所有语言中访问。也就是说,有一些很好的正则表达式模式可以处理 CSV 难题。这是我的镜头,它确实涵盖了嵌入的逗号、引号和换行符。正则表达式代码/模式和解释:

    http://www.kimgentes.com/worshiptech-web-tools-page/2008/10/14/regex-pattern-for-parsing-csv-files-with-embedded-commas-dou.html

    希望对你有所帮助..

    【讨论】:

      【解决方案8】:
       private static void Mubashir_CSVParser(string s)
              {
                  // extract the fields
                  Regex RegexCSVParser = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*(?![^\"]*\"))");
                  String[] Fields = RegexCSVParser.Split(s);
      
                  // clean up the fields (remove " and leading spaces)
                  for (int i = 0; i < Fields.Length; i++)
                  {
                      Fields[i] = Fields[i].TrimStart(' ', '"');
                      Fields[i] = Fields[i].TrimEnd('"');// this line remove the quotes
                      //Fields[i] = Fields[i].Trim();
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-23
        • 2018-05-13
        • 2018-09-05
        • 2021-11-11
        • 2014-02-26
        • 1970-01-01
        相关资源
        最近更新 更多