web-dev-qa-db-fra.com

Exportation de données dans un fichier csv

Je travaille sur une application qui exportera mon DataGridView appelé scannerDataGridView dans un fichier csv.

J'ai trouvé un exemple de code pour le faire, mais je ne peux pas le faire fonctionner. Btw ma grille de données n'est pas liée à une source.

Lorsque j'essaie d'utiliser Streamwriter pour écrire uniquement les en-têtes de colonne, tout se passe bien, mais lorsque j'essaie d'exporter l'intégralité de la grille de données, y compris les données, j'obtiens une exception.

System.NullReferenceException: la référence d'objet n'est pas définie sur une instance d'un objet. at Scanmonitor.Form1.button1_Click (Expéditeur d'objet, EventArgs e)

Voici mon code, une erreur est donnée sur la ligne suivante:

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

Trouvé le problème, le codage était bon mais j'avais une cellule vide qui a donné le problème.

2
PandaNL

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

Et en effet, c.Value.ToString() jettera une valeur nulle, alors que c.Value sera correctement converti en chaîne vide.

31
Jonathan

Une fonctionnalité peu connue de DataGridView est la possibilité de sélectionner par programme tout ou partie des DataGridCells et de les envoyer à un DataObject à l'aide de la méthode DataGridView.GetClipboardContent(). Quel est l'avantage de cela alors? 

Une DataObject ne stocke pas simplement un objet, mais plutôt la représentation de cet objet dans différents formats. Voici comment le Presse-papiers est capable de fonctionner de manière magique. différents formats sont stockés et différents contrôles/classes peuvent spécifier le format qu’ils souhaitent accepter. Dans ce cas, le DataGridView stockera les cellules sélectionnées dans le DataObject au format texte délimité par des tabulations, au format CSV ou au format HTML (*).

Le contenu de DataObject peut être récupéré en appelant les méthodes DataObject.GetData() ou DataObject.GetText() et en spécifiant un enum de format de données prédéfini. Dans ce cas, nous voulons que le format soit TextDataFormat.CommaSeparatedValue pour CSV, nous pouvons simplement écrire ce résultat dans un fichier à l'aide de System.IO.File class. 

(*) En réalité, ce qu'il retourne n'est pas, à proprement parler, HTML. Ce format contiendra également un en-tête de données auquel vous ne vous attendiez pas. Bien que l'en-tête contienne la position de départ du code HTML, je supprime simplement tout ce qui se trouve au-dessus de la balise HTML, comme myString.Substring(IndexOf("<HTML>"));.

Observez le code suivant:

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

Maintenant, n'est-ce pas mieux? Pourquoi réinventer la roue?

J'espère que cela t'aides...

16
Adam White

Je sais que c'est probablement déjà mort, mais j'ai créé un code simple qui crée un fichier CSV basé sur un objet DataGridView et vous demande où vous souhaitez l'enregistrer.

C'est assez simple, il suffit de coller de la fonction et de l'utiliser. Il a déjà quelques bases sur la gestion des exceptions, il est donc assez sûr à utiliser. prendre plaisir.

    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: changé ';' to ',' puisque nous parlons de fichiers CSV

7
José Algarra

Votre code était presque là ... Mais j'ai apporté les corrections suivantes et cela fonctionne très bien. Merci pour le post.

Erreur:

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

Correction:

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

Erreur:

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

Correction:

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

La ligne "csvFileWriter.WriteLine (dataFromGrid);" devrait être déplacé vers le bas une ligne en dessous de la parenthèse fermante, sinon vous aurez beaucoup de résultats répétitifs

for (int i = 1; i <= countColumn; i++)
{
dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
}
csvFileWriter.WriteLine(dataFromGrid);
1
l0calh0st
      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("");
        }
1
Manish sharma

Je pense que ceci est correct pour votre fonction SaveToCSV: (sinon Null ...)

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

Ne pas :

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