0

As you can see from the pictures i have attached below i am having some trouble with converting this to a valid csv file. I am nearly there but cant quite figure out the last bit i need. I need to bring the column headers into the textbox and i also need to remove the ',' at the end of each line. BTW i am converting the top DGV.

enter image description here

enter image description here

here is my code -

private void btnSave_Click(object sender, EventArgs e)
    {
        int countRow = dgvCsv1.RowCount;
        int cellCount = dgvCsv1.Rows[0].Cells.Count;


        for (int rowIndex = 0; rowIndex <= countRow -1; rowIndex++)
        {
            for (int cellIndex = 0; cellIndex <= cellCount - 1; cellIndex++)
            {
                textBoxExport.Text = textBoxExport.Text + dgvCsv1.Rows[rowIndex].Cells[cellIndex].Value.ToString() + ",";
            }
            textBoxExport.Text = textBoxExport.Text + "\r\n";
        }

        System.IO.File.WriteAllText(lblFilePath.Text, textBoxExport.Text);
    }

Any help greatly appreciated.

MOKane
  • 51
  • 1
  • 8
  • If you have a collection of strings, you can use `string.Join()` to put commas between the strings (so one solution is to build each row into a `List` and then `Join` them. Another way is to create a Boolean (say `var firstItem=true;`) and then put the comma _before_ every item except the first. – Flydog57 Nov 15 '18 at 15:11
  • do your loop to cellIndex < cellcount, and after the loop add the last field – nabuchodonossor Nov 15 '18 at 15:11
  • One thing to worry about with CSV is field data that contains commas. Some parsers will ignore commas embedded in string that are surrounded by quotes. You might consider putting all strings within double-quotes, or to test if a field contains a comma and, if so, surround it in quotes. It depends on the rules set by the consumer of your file. – Flydog57 Nov 15 '18 at 15:15
  • 2
    Possible duplicate of [Exporting datagridview to csv file](https://stackoverflow.com/questions/9943787/exporting-datagridview-to-csv-file) – obl Nov 15 '18 at 15:21
  • I would recommend reading the question here for better alternatives. https://stackoverflow.com/questions/1941392/are-there-any-csv-readers-writer-libraries-in-c As FlyDog mentioned if there's commas/quotes in any of your table it could cause you issues. If your columns aren't changed by the user you could just loop through all rows and format each new line var newLine = string.Format("{0},{1},{2},{3}", dgvCsv1.Rows[0],dgvCsv1.Rows[1],dgvCsv1.Rows[2],dgvCsv1.Rows[3]); – Nathan Champion Nov 15 '18 at 15:21
  • I really feel for that 67 year old delivery person. – Joel Coehoorn Nov 15 '18 at 19:08

2 Answers2

1

This has already been solved here. The LINQ solution does exactly what you want.

var sb = new StringBuilder();

var headers = dgvCsv1.Columns.Cast<DataGridViewColumn>();
sb.AppendLine(string.Join(",", headers.Select(column => "\"" + column.HeaderText + "\"").ToArray()));

foreach (DataGridViewRow row in dgvCsv1.Rows)
{
    var cells = row.Cells.Cast<DataGridViewCell>();
    sb.AppendLine(string.Join(",", cells.Select(cell => "\"" + cell.Value + "\"").ToArray()));
}

So the final code would look like:

private void btnSave_Click(object sender, EventArgs e)
    {
        var sb = new StringBuilder();

        var headers = dgvCsv1.Columns.Cast<DataGridViewColumn>();
        sb.AppendLine(string.Join(",", headers.Select(column => "\"" + column.HeaderText + "\"").ToArray()));

        foreach (DataGridViewRow row in dgvCsv1.Rows)
        {
            var cells = row.Cells.Cast<DataGridViewCell>();
            sb.AppendLine(string.Join(",", cells.Select(cell => "\"" + cell.Value + "\"").ToArray()));
        }
        textBoxExport.Text = sb.ToString();

        System.IO.File.WriteAllText(lblFilePath.Text, textBoxExport.Text);
    }
James
  • 168
  • 8
  • This is not an answer. A link to another answer is just a map or pointer to where an answer is and should be a comment. See [Your answer is in another castle](https://meta.stackexchange.com/questions/225370/your-answer-is-in-another-castle-when-is-an-answer-not-an-answer) – Ňɏssa Pøngjǣrdenlarp Nov 15 '18 at 17:03
  • OK, I added the relevant code. The result of sb.ToString() will be the desired CSV. – James Nov 15 '18 at 18:59
1
  1. Remove last delimiter (comma)

You already have the number of columns ColumnCount, therefore, while looping through the columns, a simple check is needed to see if the currentColumn is “less than” the ColumnCount -1. If the currentColumn IS less than ColumnCount -1, then you need to add the “comma” ,. If currentColumn is NOT “less than” ColumnCount, then this can mean only one thing… this is the last column and instead of adding the comma you want to add a new line.

if (currentCol < ColumnCount - 1) {
  textBoxExport.Text += ",";
}
else {
  textBoxExport.Text += Environment.NewLine;
}
  1. Column Headers in CSV file

This will need to be separate from looping through the rows. Before looping through the rows, loop through the columns of the grid and get each columns Name property. This would be the first line in the CSV file. You can use the same strategy as above to avoid the last comma.

for (int currentCol = 0; currentCol < ColumnCount; currentCol++) {
  textBoxExport.Text += dgvCsv1.Columns[currentCol].Name;
  if (currentCol < ColumnCount - 1) {
    textBoxExport.Text += ",";
  }
  else {
    textBoxExport.Text += Environment.NewLine;
  }
}

Lastly, it is unclear why you are using a TextBox to store the CSV string. I recommend using a StringBuilder. Below is an example of what is described above.

private void btnSave_Click(object sender, EventArgs e) {
  StringBuilder sb = new StringBuilder();
  int RowCount = dgvCsv1.RowCount;
  int ColumnCount = dgvCsv1.ColumnCount;

  // get column headers
  for (int currentCol = 0; currentCol < ColumnCount; currentCol++) {
    sb.Append(dgvCsv1.Columns[currentCol].Name);
    if (currentCol < ColumnCount - 1) {
      sb.Append(",");
    }
    else {
      sb.AppendLine();
    }
  }

  // get the rows data
  for (int currentRow = 0; currentRow < RowCount; currentRow++) {
    if (!dgvCsv1.Rows[currentRow].IsNewRow) {
      for (int currentCol = 0; currentCol < ColumnCount; currentCol++) {
        if (dgvCsv1.Rows[currentRow].Cells[currentCol].Value != null) {
          sb.Append(dgvCsv1.Rows[currentRow].Cells[currentCol].Value.ToString());
        }
        if (currentCol < ColumnCount - 1) {
          sb.Append(",");
        }
        else {
          sb.AppendLine();
        }
      }
    }
  }
  textBoxExport.Text = sb.ToString();
  System.IO.File.WriteAllText(@"D:\Test\DGV_CSV_EXPORT.csv", sb.ToString());
}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
JohnG
  • 9,259
  • 2
  • 20
  • 29