Trouble with parsing CSV files in C#

时间:2017-04-06 17:09:17

标签: c# csv parsing

I'm trying to import a CSV file to my C# site and save it in the database. While doing research I learned about CSV parsing, I've tried to implement this but I've ran into some trouble. Here is a portion of my code so far:

string fileext = Path.GetExtension(fupcsv.PostedFile.FileName);

if (fileext == ".csv")
{
    string csvPath = Server.MapPath("~/CSVFiles/") + Path.GetFileName(fupcsv.PostedFile.FileName);

    fupcsv.SaveAs(csvPath);

    // Add Columns to Datatable to bind data  

    DataTable dtCSV = new DataTable();

    dtCSV.Columns.AddRange(new DataColumn[2] { new DataColumn("ModuleId", typeof(int)), new DataColumn("CourseId", typeof(int))});

    // Read all the lines of the text file and close it.  

    string[] csvData = File.ReadAllLines(csvPath);

    // iterate over each row and Split it to New line.  

    foreach (string row in csvData)
    {

        // Check for is null or empty row record  

        if (!string.IsNullOrEmpty(row))
        {

            using (TextFieldParser parser = new TextFieldParser(csvPath))
            {
                parser.TextFieldType = FieldType.Delimited;
                parser.SetDelimiters(",");
                while (!parser.EndOfData)
                {
                    //Process row
                    string[] fields = parser.ReadFields();
                    int i = 1;
                    foreach (char cell in row)
                    {
                        dtCSV.NewRow()[i] = cell;
                        i++;
                    }
                }
            }
        }
    }
}

I keep getting the error "There is no row at position -1" at " dtCSV.Rows[dtCSV.Rows.Count - 1][i] = cell;" Any help would be greatly appreciated, thanks

1 个答案:

答案 0 :(得分:3)

您正在尝试索引尚未创建的行。而不是

dtCSV.Rows[dtCSV.Rows.Count - 1][i] = cell;

使用

dtCSV.NewRow()[i] = cell;

我还建议您从i而不是0开始编制1索引。

好吧所以事实证明你的代码有很多错误,所以我做了一些修改。

string fileext = Path.GetExtension(fupcsv.PostedFile.FileName);

if (fileext == ".csv")
{
    string csvPath = Server.MapPath("~/CSVFiles/") + Path.GetFileName(fupcsv.PostedFile.FileName);

    fupcsv.SaveAs(csvPath);
    DataTable dtCSV = new DataTable();    
    dtCSV.Columns.AddRange(new DataColumn[2] { new DataColumn("ModuleId", typeof(int)), new DataColumn("CourseId", typeof(int))});

    var csvData = File.ReadAllLines(csvPath);
    bool headersSkipped = false;
    foreach (string line in csvData)
    {
        if (!headersSkipped)
        {
            headersSkipped = true;
            continue;
        }
        // Check for is null or empty row record  
        if (!string.IsNullOrEmpty(line))
        {
            //Process row
            int i = 0;
            var row = dtCSV.NewRow();
            foreach (var cell in line.Split(','))
            {
                row[i] = Int32.Parse(cell);
                i++;
            }
            dtCSV.Rows.Add(row);
            dtCSV.AcceptChanges();
        }
    }
}

我完全放弃了TextFieldParser解决方案,因为我不熟悉它,但如果你想坚持下去,那么重新融入它应该不难。

以下是您遇到的一些问题:

  • 未调用NewRow()创建新行或使用AddRow(row)
  • 将其添加到表格中
  • 迭代row中的字符,而不是您解析的fields
  • 未解析cell的值 - 它的值类型为string,您尝试添加到int

其他一些值得注意的事情(仅为了提高代码的性能和可读性:))

  • 在声明新变量时考虑使用var,不必担心你正在创建什么类型的变量,这需要很多压力
  • 正如评论中的其他人所说,使用ReadAllLines()它会将您的文本文件整齐地解析为行,从而更容易迭代。
  • 大多数情况下,使用数组或列表时,需要从0开始,而不是从1
  • 开始
  • 您必须使用AcceptChanges()提交您所做的所有更改