Экспорт таблицы данных в CSV-файл - PullRequest
16 голосов
/ 30 марта 2012

Я работаю над приложением, которое будет экспортировать мой DataGridView, который называется scannerDataGridView, в файл csv.

Найден пример кода для этого, но он не может заставить его работать.Кстати, моя сетка данных не привязана к источнику.

Когда я пытаюсь использовать Streamwriter, чтобы записывать только заголовки столбцов, все идет хорошо, но когда я пытаюсь экспортировать всю сетку данных, включая данные, я получаю trhown исключения.

System.NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта.at Scanmonitor.Form1.button1_Click (Отправитель объекта, 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());
    }

Ответы [ 8 ]

31 голосов
/ 30 апреля 2013

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

И действительно, c.Value.ToString() сгенерирует нулевое значение, тогда как c.Value правильно преобразует в пустую строку.

16 голосов
/ 08 октября 2014

Немного известной особенностью DataGridView является возможность программно выбирать некоторые или все DataGridCells и отправлять их на DataObject, используя метод DataGridView.GetClipboardContent().В чем преимущество этого тогда?

A DataObject не просто хранит объект, а скорее представляет его в различных форматах.Вот как буфер обмена способен творить свою магию;в нем хранятся различные форматы, и различные элементы управления / классы могут указывать, какой формат они хотят принять.В этом случае DataGridView сохранит выбранные ячейки в объекте DataObject в виде текстового формата с разделителями табуляции, формата CSV или HTML (*).

Содержимое объекта DataObject можно получить, вызвавDataObject.GetData() или DataObject.GetText() методы и указание предопределенного формата данных enum.В этом случае мы хотим, чтобы форматом был TextDataFormat.CommaSeparatedValue для CSV, тогда мы можем просто записать этот результат в файл, используя класс 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));
}

Теперь,разве это не лучше?Зачем заново изобретать колесо?

Надеюсь, это поможет ...

7 голосов
/ 21 августа 2015

Я знаю, что это, вероятно, уже мертв, но я сделал простой код, который создает CSV на основе объекта DataGridView и спрашивает, где вы хотите его сохранить.

Это довольно просто, просто вставьте де функцию ииспользуй это.Он уже имеет некоторую базовую обработку исключений, поэтому довольно безопасен в использовании.наслаждайтесь.

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

РЕДАКТИРОВАТЬ: изменено ';'на ',' так как мы говорим о файлах CSV

3 голосов
/ 06 сентября 2017
      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("");
        }
2 голосов
/ 27 сентября 2015

Ваш код был почти там ... Но я внес следующие исправления, и он прекрасно работает.Спасибо за сообщение.

Ошибка:

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

Исправление:

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

Ошибка:

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

Исправление:

System.IO.File.WriteAllLines(sfd.FileName, output, System.Text.Encoding.UTF8);
2 голосов
/ 02 апреля 2012

Обнаружил проблему, кодирование в порядке, но у меня была пустая ячейка, которая вызвала проблему.

1 голос
/ 15 марта 2013

Строка "csvFileWriter.WriteLine (dataFromGrid);"следует переместить на одну строку ниже закрывающей скобки, иначе вы получите много повторяющихся результатов:

for (int i = 1; i <= countColumn; i++)
{
dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
}
csvFileWriter.WriteLine(dataFromGrid);
0 голосов
/ 06 августа 2017

Я думаю, что это правильно для вашей функции SaveToCSV: (иначе Null ...)

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

Не:

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