Exporting datagridview to csv file

不想你离开。 提交于 2019-12-17 07:35:44

问题


I'm working on a application which will export my DataGridView called scannerDataGridView to a csv file.

Found some example code to do this, but can't get it working. Btw my datagrid isn't databound to a source.

When i try to use the Streamwriter to only write the column headers everything goes well, but when i try to export the whole datagrid including data i get an exeption trhown.

System.NullReferenceException: Object reference not set to an instance of an object. at Scanmonitor.Form1.button1_Click(Object sender, EventArgs e)

Here is my Code, error is given on the following line:

dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();

//csvFileWriter = StreamWriter
//scannerDataGridView = DataGridView   

private void button1_Click(object sender, EventArgs e)
{
    string CsvFpath = @"C:\scanner\CSV-EXPORT.csv";
    try
    {
        System.IO.StreamWriter csvFileWriter = new StreamWriter(CsvFpath, false);

        string columnHeaderText = "";

        int countColumn = scannerDataGridView.ColumnCount - 1;

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

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


        csvFileWriter.WriteLine(columnHeaderText);

        foreach (DataGridViewRow dataRowObject in scannerDataGridView.Rows)
        {
            if (!dataRowObject.IsNewRow)
            {
                string dataFromGrid = "";

                dataFromGrid = dataRowObject.Cells[0].Value.ToString();

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

                    csvFileWriter.WriteLine(dataFromGrid);
                }
            }
        }


        csvFileWriter.Flush();
        csvFileWriter.Close();
    }
    catch (Exception exceptionObject)
    {
        MessageBox.Show(exceptionObject.ToString());
    }

回答1:


LINQ FTW!

var sb = new StringBuilder();

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

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

And indeed, c.Value.ToString() will throw on null value, while c.Value will correctly convert to an empty string.




回答2:


A little known feature of the DataGridView is the ability to programmatically select some or all of the DataGridCells, and send them to a DataObject using the method DataGridView.GetClipboardContent(). Whats the advantage of this then?

A DataObject doesn't just store an object, but rather the representation of that object in various different formats. This is how the Clipboard is able to work its magic; it has various formats stored and different controls/classes can specify which format they wish to accept. In this case, the DataGridView will store the selected cells in the DataObject as a tab-delimited text format, a CSV format, or as HTML (*).

The contents of the DataObject can be retrieved by calling the DataObject.GetData() or DataObject.GetText() methods and specifying a predefined data format enum. In this case, we want the format to be TextDataFormat.CommaSeparatedValue for CSV, then we can just write that result to a file using System.IO.File class.

(*) Actually, what it returns is not, strictly speaking, HTML. This format will also contain a data header that you were not expecting. While the header does contain the starting position of the HTML, I just discard anything above the HTML tag like myString.Substring(IndexOf("<HTML>"));.

Observe the following code:

void SaveDataGridViewToCSV(string filename)
{        
    // Choose whether to write header. Use EnableWithoutHeaderText instead to omit header.
    dataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
    // Select all the cells
    dataGridView1.SelectAll();
    // Copy selected cells to DataObject
    DataObject dataObject = dataGridView1.GetClipboardContent();
    // Get the text of the DataObject, and serialize it to a file
    File.WriteAllText(filename, dataObject.GetText(TextDataFormat.CommaSeparatedValue));
}

Now, isn't that better? Why re-invent the wheel?

Hope this helps...




回答3:


I know this is probably already dead but I made a simple code that creates a CSV based on a DataGridView object and asks where you want to save it.

Its pretty straight forward, just paste de function and use it. It already has some basic exception handling so is pretty safe to use. enjoy.

    private void SaveToCSV(DataGridView DGV)
    {
        string filename = "";
        SaveFileDialog sfd = new SaveFileDialog();
        sfd.Filter = "CSV (*.csv)|*.csv";
        sfd.FileName = "Output.csv";
        if (sfd.ShowDialog() == DialogResult.OK)
        {
            MessageBox.Show("Data will be exported and you will be notified when it is ready.");
            if (File.Exists(filename))
            {
                try
                {
                    File.Delete(filename);
                }
                catch (IOException ex)
                {
                    MessageBox.Show("It wasn't possible to write the data to the disk." + ex.Message);
                }
            }
            int columnCount = DGV.ColumnCount;
            string columnNames = "";
            string[] output = new string[DGV.RowCount + 1];
            for (int i = 0; i < columnCount; i++)
            {
                columnNames += DGV.Columns[i].Name.ToString() + ",";
            }
            output[0] += columnNames;
            for (int i = 1; (i - 1) < DGV.RowCount; i++)
            {
                for (int j = 0; j < columnCount; j++)
                {
                    output[i] += DGV.Rows[i - 1].Cells[j].Value.ToString() + ",";
                }
            }
            System.IO.File.WriteAllLines(sfd.FileName, output, System.Text.Encoding.UTF8);
            MessageBox.Show("Your file was generated and its ready for use.");
        }
    }

EDIT: changed ';' to ',' since we are talking about CSV files




回答4:


      Please check this code.its working fine  

          try
               {
            //Build the CSV file data as a Comma separated string.
            string csv = string.Empty;

            //Add the Header row for CSV file.
            foreach (DataGridViewColumn column in dataGridView1.Columns)
            {
                csv += column.HeaderText + ',';
            }
            //Add new line.
            csv += "\r\n";

            //Adding the Rows

            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                foreach (DataGridViewCell cell in row.Cells)
                {
                    if (cell.Value != null)
                    {
                        //Add the Data rows.
                        csv += cell.Value.ToString().TrimEnd(',').Replace(",", ";") + ',';
                    }
                    // break;
                }
                //Add new line.
                csv += "\r\n";
            }

            //Exporting to CSV.
            string folderPath = "C:\\CSV\\";
            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }
            File.WriteAllText(folderPath + "Invoice.csv", csv);
            MessageBox.Show("");
        }
        catch
        {
            MessageBox.Show("");
        }



回答5:


Found the problem, the coding was fine but i had an empty cell that gave the problem.




回答6:


Your code was almost there... But I made the following corrections and it works great. Thanks for the post.

Error:

string[] output = new string[dgvLista_Apl_Geral.RowCount + 1];

Correction:

string[] output = new string[DGV.RowCount + 1];

Error:

System.IO.File.WriteAllLines(filename, output, System.Text.Encoding.UTF8);

Correction:

System.IO.File.WriteAllLines(sfd.FileName, output, System.Text.Encoding.UTF8);



回答7:


The line "csvFileWriter.WriteLine(dataFromGrid);" should be moved down one line below the closing bracket, else you'll get a lot of repeating results:

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



回答8:


I think this is the correct for your SaveToCSV function : ( otherwise Null ...)

 for (int i = 0; i < columnCount; i++)

Not :

 for (int i = 1; (i - 1) < DGV.RowCount; i++)


来源:https://stackoverflow.com/questions/9943787/exporting-datagridview-to-csv-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!