如何编写字符串格式化行数据以保存为CSV文件?

时间:2017-10-27 05:55:10

标签: c# string csv datagridview

我目前有一个程序,它使用StreamReader访问CSV文件并将值存储在数据网格中,但是在保存此数据时,它会为数据行的每个列值打印一个新行。

程序当前将csv文件打印为:

  

headerText,headerText,headerText,headerText
  第1栏第2栏第1栏第2栏第3栏第1栏第2栏第3栏第4栏

我需要打印的是:

  

headerText,headerText,headerText,headerText
  第1栏,第2栏,第3栏,第4栏

string CsvFpath = "C:/StockFile/stockfiletest.csv";

try
{
    StreamWriter csvFileWriter = new StreamWriter(CsvFpath, false);
    string columnHeaderText = "";
    int countColumn = stockGridView.ColumnCount - 1;

    if (countColumn >= 0)
    {
        columnHeaderText = stockGridView.Columns[0].HeaderText;
    }

    for (int i = 1; i <= countColumn; i++)
    {
        columnHeaderText = columnHeaderText + ',' + stockGridView.Columns[i].HeaderText;
    }

    csvFileWriter.WriteLine(columnHeaderText);

    foreach (DataGridViewRow dataRowObject in stockGridView.Rows)
    {
        if (!dataRowObject.IsNewRow)
        {
            string dataFromGrid = "{0} += {1} += {2} += {3}";
            dataFromGrid = dataRowObject.Cells[0].Value.ToString();

            for (int i = 1; i <= countColumn; i++)
            {
                dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
                csvFileWriter.Write(dataFromGrid);
            }
            csvFileWriter.WriteLine();
        }
    }

    csvFileWriter.Dispose();

    MessageBox.Show("Saved stockfile.csv");
}
catch (Exception exceptionObject)
{
    MessageBox.Show(exceptionObject.ToString());
}

有谁能告诉我我的字符串形成错误以及如何实现所需的文件输出?

2 个答案:

答案 0 :(得分:0)

你的问题在这里:

for (int i = 1; i <= countColumn; i++)
{
  dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
      csvFileWriter.Write(dataFromGrid);
}

您每次都会添加字符串..而不是在任何时候清除它。所以在第1行第一列你得到“,col1”col2是“,col1,col2”..但是你每次都写出来......

有一个CSV编写器类,但是,你可以做你正在做的事情,但是,只需将写操作移到循环外,然后重置它。然而..

for (int i = 1; i <= countColumn; i++)
{
      if (i>1) csvFileWriter.Write(",");
      csvFileWriter.Write(dataRowObject.Cells[i].Value.ToString());
}

会阻止你在开始时获得额外的“,”并随时写入

答案 1 :(得分:0)

正如另一个答案中所提到的,问题是当你处理每一列时,你正在写里面循环,而不是在循环之后收集了该行的所有列信息。

另一种方法是使用string.JoinSystem.Linq来更简洁地连接每一行的列值。

另请注意,我们可以将csvFileWriter包装在using块中,以便在块执行完成时自动关闭并处理:

using (var csvFileWriter = new StreamWriter(CsvFpath, false))
{
    // Write all the column headers, joined with a ','
    csvFileWriter.WriteLine(string.Join(",",
        stockGridView.Columns.Cast<DataGridViewColumn>().Select(col => col.HeaderText)));

    // Grab all the rows that aren't new and, for each one, join the cells with a ','
    foreach (var row in stockGridView.Rows.Cast<DataGridViewRow>()
        .Where(row => !row.IsNewRow))
    {
        csvFileWriter.WriteLine(string.Join(",",
            row.Cells.Cast<DataGridViewCell>().Select(cell => cell.Value.ToString())));
    }
}

另一件事:您可以使用现有的工具来编写自己的csv解析器,而不是编写自己的csv解析器,例如CsvHelper,它将处理可能导致问题的其他种类边缘情况,例如:其中包含逗号的值。