简体   繁体   English

将datagridview导出到csv文件

[英]Exporting datagridview to csv file

I'm working on a application which will export my DataGridView called scannerDataGridView to a csv file.我正在开发一个将名为scannerDataGridView 的DataGridView 导出到csv 文件的应用程序。

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.当我尝试使用 Streamwriter 仅写入列标题时,一切顺利,但是当我尝试导出包括数据在内的整个数据网格时,我得到了一个例外。

System.NullReferenceException: Object reference not set to an instance of an object. System.NullReferenceException:对象引用未设置为对象的实例。 at Scanmonitor.Form1.button1_Click(Object sender, EventArgs e)在 Scanmonitor.Form1.button1_Click(对象发送者,EventArgs e)

Here is my Code, error is given on the following line:这是我的代码,以下行给出了错误:

dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString(); 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());
    }

LINQ FTW! 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.实际上, c.Value.ToString()将抛出空值,而c.Value将正确转换为空字符串。

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() . DataGridView的一个鲜为人知的功能是能够以编程方式选择部分或全部 DataGridCell,并使用DataGridView.GetClipboardContent()方法将它们发送到DataObject 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. DataObject不只是存储一个对象,而是以各种不同格式表示该对象。 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 (*).在这种情况下,DataGridView 会将 DataObject 中的选定单元格存储为制表符分隔的文本格式、CSV 格式或 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.可以通过调用DataObject.GetData()DataObject.GetText()方法并指定预定义的数据格式枚举来检索 DataObject 的内容。 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.在这种情况下,我们希望 CSV 的格式为 TextDataFormat.CommaSeparatedValue,然后我们可以使用System.IO.File类将该结果写入文件。

(*) Actually, what it returns is not, strictly speaking, HTML. (*) 实际上,严格来说,它返回的不是 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>"));虽然标题确实包含 HTML 的起始位置,但我只是丢弃了 HTML 标记上方的任何内容,例如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...希望这可以帮助...

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

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 到','因为我们在讨论CSV文件

      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("");
        }

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);

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

The line "csvFileWriter.WriteLine(dataFromGrid);"行“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);

I think this is the correct for your SaveToCSV function : ( otherwise Null ...)我认为这对您的 SaveToCSV 函数是正确的:(否则为 Null ...)

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

Not :不是 :

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

This is what I been using in my projects:这是我在项目中使用的:

void export_csv(string file, DataGridView grid)
{
    using (StreamWriter csv = new StreamWriter(file, false))
    {
        int totalcolms = grid.ColumnCount;
        foreach (DataGridViewColumn colm in grid.Columns) csv.Write(colm.HeaderText + ',');
        csv.Write('\n');
        string data = "";
        foreach (DataGridViewRow row in grid.Rows)
        {
            if (row.IsNewRow) continue;
            data = "";
            for (int i = 0; i < totalcolms; i++)
            {
                data += (row.Cells[i].Value ?? "").ToString() + ',';
            }
            if (data != string.Empty) csv.WriteLine(data);
        }
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM