将datagridview导出到csv文件

Pan*_*aNL 16 c# datagridview streamwriter

我正在开发一个应用程序,它将我的DataGridView名为scannerDataGridView导出到csv文件.

找到一些示例代码来执行此操作,但无法使其正常工作.顺便说一下,我的数据网格没有数据绑定到源.

当我尝试使用Streamwriter只编写列标题时一切顺利,但当我尝试导出整个数据网格包括数据时,我得到一个exeption trhown.

System.NullReferenceException:未将对象引用设置为对象的实例.在Scanmonitor.Form1.button1_Click(Object sender,EventArgs e)

这是我的代码,错误在以下行中给出:

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());
    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*han 32

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()));
}
Run Code Online (Sandbox Code Playgroud)

实际上,c.Value.ToString()将抛出null值,同时c.Value将正确转换为空字符串.


Ada*_*ite 18

一个鲜为人知的特性DataGridView是能够以编程方式选择部分或全部DataGridCell,并DataObject使用该方法将它们发送给a DataGridView.GetClipboardContent().这有什么好处呢?

A DataObject不仅存储对象,而且存储各种不同格式的对象.这就是剪贴板能够发挥其魔力的方式; 它存储了各种格式,不同的控件/类可以指定它们希望接受的格式.在这种情况下,DataGridView会将选定的单元格作为制表符分隔的文本格式,CSV格式或HTML(*)存储在DataObject中.

可以通过调用DataObject.GetData()DataObject.GetText()方法并指定预定义的数据格式枚举来检索DataObject的内容.在这种情况下,我们希望CSV的格式为TextDataFormat.CommaSeparatedValue,然后我们可以使用System.IO.File类将该结果写入文件.

(*)实际上,它返回的内容严格来说不是HTML.此格式还包含您不期望的数据标头.虽然标题确实包含HTML的起始位置,但我只是丢弃HTML标记之上的任何内容myString.Substring(IndexOf("<HTML>"));.

请注意以下代码:

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));
}
Run Code Online (Sandbox Code Playgroud)

现在,不是更好吗?为什么重新发明轮子?

希望这可以帮助...

  • 我在网上看到过这个丑陋的解决方案。请不要使用它!首先,当`SelectionMode = Single`时它不起作用。其次,使用剪贴板作为临时存储空间显然是疯狂的。其他一些应用程序可能会干扰并替换“SetDataObject”和“GetText”调用之间的内容。 (2认同)

Jos*_*rra 7

我知道这可能已经死了但是我做了一个简单的代码,它根据DataGridView对象创建一个CSV并询问你想要保存它的位置.

它很直接,只需粘贴功能并使用它.它已经有一些基本的异常处理,所以使用起来非常安全.请享用.

    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.");
        }
    }
Run Code Online (Sandbox Code Playgroud)

编辑:改变了';' 到','因为我们在讨论CSV文件


Pan*_*aNL 2

发现问题,编码很好,但我有一个空单元格,导致了问题。

  • !防御性编码!= 很好 (7认同)