Cómo leer un fichero CSV (comma-separated values o valores separados por coma) mediante el lenguaje de programación C# de Visual Studio .Net C Sharp y mostrar su contenido en un DataGridView. También explicamos cómo hacer el proceso inverso, cómo guardar el contenido de un DataGridView en un fichero CSV. Incluimos la descarga gratuita del código fuente completo de la aplicación de ejemplo.
- Requisitos para realizar aplicación en C# que lea y escriba ficheros CSV.
- Crear aplicación .Net C# para leer y escribir ficheros CSV.
- La aplicación ProyectoA Leer Ficheros CSV en funcionamiento.
- Descarga del código fuente completo de la aplicación ProyectoA Leer Ficheros CSV en funcionamiento.
Requisitos para realizar aplicación en C# que lea y escriba ficheros CSV
El único requisito es disponer del IDE de desarrollo Visual Studio .Net, de Microsoft. En nuestro caso usaremos la versión gratuita de este entorno de desarrollo. En el siguiente enlace explicamos cómo descargarla e instalarla:
La aplicación permitirá tanto leer (importar) un fichero CSV existente en el equipo y mostrar su contenido en una rejilla de datos, como guardar (exportar) el contenido de dicha rejilla en un fichero CSV. Por lo tanto necesitaremos permisos de lectura y escritura en la carpeta donde queramos leer o escribir los ficheros CSV.
Si únicamente queremos leer ficheros CSV, estos existirán en alguna ubicación del equipo y serán accesibles desde el usuario con el que hemos ejecutado la aplicación.
Los ficheros CSV que la aplicación puede leer son muy heterogéneos, dado que admite indicar el carácter separador de campos, así como el carácter separador de valores. Por ejemplo, el contenido de un fichero CSV puede ser:
1 2 3 4 5 6 |
"Número de factura";"Cliente";"Importe";"Fecha de alta" "ASP00098";"ProyectoA","1253,89";"01-07-2020" "ASP00231";"Cliente 2","578,00";"24-03-2021" "ASP00001";"ProyectoA","2705,55";"20-01-2021" "ASP00003";"Cliente 2","155,20";"17-01-2021" "ASP00009";"Cliente 2","1000,60";"07-01-2021" |
Como podemos observar en el ejemplo, el carácter separador de campos es el punto y coma «;» y el carácter separador de valores es la comilla doble «.
Crear aplicación .Net C# para leer y escribir ficheros CSV
Crearemos un nuevo proyecto, de tipo «Aplicación de Windows Forms (.NET Framework)»:
Introduciremos el nombre para la aplicación, en nuestro caso «ProyectoALeerCSV», así como la ubicación de los ficheros del proyecto. Elegiremos la versión de .NET Framework por defecto, en nuestro caso 4.7.2 y pulsaremos en «Crear»:
Agregaremos los componentes visuales al formulario:
- TextBox: para introducir la ruta y el nombre del fichero CSV a leer y a guardar en la exportación a CSV.
- Button: para mostrar ventana de selección de fichero CSV, para leer CSV y para exportar a CSV.
- DataGridView: donde mostraremos los datos del fichero CSV. Este DataGridView será editable, el usuario podrá modificar los datos cargados del CSV y añadir nuevas líneas.
- Varios TextBox más para establecer el carácter separador de campos y el carácter separador de valores, tanto para la importación de CSV como para la exportación.
- Un CheckBox para indicar si la primera línea de datos del fichero CSV contiene el nombre del título de las columnas.
Agregaremos estos componentes desde el Cuadro de herramientas:
El formulario quedará con este aspecto visual:
Programaremos cada botón con su código fuente correspondiente. Para el caso del botón de selección del fichero CSV, que mostrará una ventana de diálogo solicitando la ubicación del fichero CSV, añadiremos el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
private void bSelFicheroCSV_Click(object sender, EventArgs e) { OpenFileDialog dlFicheroCSV = new OpenFileDialog(); dlFicheroCSV.Title = "Abrir fichero CSV..."; //dlFicheroCSV.InitialDirectory = @"C:\"; dlFicheroCSV.Filter = "Ficheros de texto y CSV (*.txt, *.csv)|*.txt;*.csv|" + "Ficheros de texto (*.txt)|*.txt|" + "Ficheros CSV (*.csv)|*.csv|" + "Todos los ficheros (*.*)|*.*"; dlFicheroCSV.FilterIndex = 1; dlFicheroCSV.RestoreDirectory = true; if (dlFicheroCSV.ShowDialog() == DialogResult.OK) { txtFicheroCSV.Text = dlFicheroCSV.FileName; } } |
Para el caso del botón de lectura del fichero CSV seleccionado, que se leerá su contenido y lo mostrará en el DataGridView, añadiremos el siguiente código en su evento Click btLeerCSV_Click:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
private void btLeerCSV_Click(object sender, EventArgs e) { if (File.Exists(txtFicheroCSV.Text)) { try { CargarDatosCSV(txtFicheroCSV.Text, Convert.ToChar(txtSeparador.Text), opTitulos.Checked, txtSeparadorCampos.Text); } catch (Exception ex) { MessageBox.Show(ex.Message.ToString(), "Error al leer CSV...", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else { MessageBox.Show("No existe el fichero CSV seleccionado.", "Fichero no encontrado...", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } |
Dicho botón hace referencia al procedimiento CargarDatosCSV, que tendrá el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
//Carga un fichero CSV en un DataGridView private void CargarDatosCSV(string ficheroCSV, char separador, bool primeraLineaTitulo, string separadorCampos) { dbTabla.DataSource = null; dbTabla.Rows.Clear(); DataTable tablaDatos = new DataTable(); string[] lineas = File.ReadAllLines(ficheroCSV, Encoding.Default); if (lineas.Length > 0) { //Si la primea línea contiene el título string[] etiquetaTitulosFinal; if (primeraLineaTitulo) { string primelaLinea = lineas[0]; string[] etiquetaTitulos = primelaLinea.Split(separador); List<string> lista = new List<string>(); foreach (string campoActual in etiquetaTitulos) { string valor = campoActual; // Quitamos el posible carácter de inicio y fin de valor if (separadorCampos != "") { valor = valor.TrimEnd(Convert.ToChar(separadorCampos)); valor = valor.TrimStart(Convert.ToChar(separadorCampos)); } tablaDatos.Columns.Add(new DataColumn(valor)); lista.Add(valor); } etiquetaTitulosFinal = lista.ToArray(); } else { string primelaLinea = lineas[0]; string[] etiquetaTitulos = primelaLinea.Split(separador); int numero = 0; List<string> lista = new List<string>(); foreach (string campoActual in etiquetaTitulos) { string valor = "C" + Convert.ToString(numero); // Quitamos el posible carácter de inicio y fin de valor if (separadorCampos != "") { valor = valor.TrimEnd(Convert.ToChar(separadorCampos)); valor = valor.TrimStart(Convert.ToChar(separadorCampos)); } tablaDatos.Columns.Add(new DataColumn(valor)); lista.Add(valor); numero++; } etiquetaTitulosFinal = lista.ToArray(); } //Resto de filas de datos int inicioFila = 0; if (primeraLineaTitulo) inicioFila = 1; for (int i = inicioFila; i < lineas.Length; i++) { string[] filasDatos = lineas[i].Split(separador); DataRow dataGridS = tablaDatos.NewRow(); int columnIndex = 0; foreach (string campoActual in etiquetaTitulosFinal) { string valor = filasDatos[columnIndex++]; // Quitamos el posible carácter de inicio y fin de valor if (separadorCampos != "") { valor = valor.TrimEnd(Convert.ToChar(separadorCampos)); valor = valor.TrimStart(Convert.ToChar(separadorCampos)); } dataGridS[campoActual] = valor; } tablaDatos.Rows.Add(dataGridS); } } if (tablaDatos.Rows.Count > 0) { dbTabla.DataSource = tablaDatos; } } |
El botón de selección de fichero para guardar el resultado del DataGridView, btSelFicheroExportarCSV, en su evento Click:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
private void btSelFicheroExportarCSV_Click(object sender, EventArgs e) { SaveFileDialog dlFicheroCSV = new SaveFileDialog(); dlFicheroCSV.Title = "Exportar fichero CSV..."; //dlFicheroCSV.InitialDirectory = @"C:\"; dlFicheroCSV.Filter = "Ficheros de texto y CSV (*.txt, *.csv)|*.txt;*.csv|" + "Ficheros de texto (*.txt)|*.txt|" + "Ficheros CSV (*.csv)|*.csv|" + "Todos los ficheros (*.*)|*.*"; dlFicheroCSV.FilterIndex = 1; dlFicheroCSV.OverwritePrompt = true; if (dlFicheroCSV.ShowDialog() == DialogResult.OK) { txtFicheroExportarCSV.Text = dlFicheroCSV.FileName; } } |
El botón para exportar el contenido del DataGridView, btExportarCSV, en su evento Click, tendrá el siguiente código:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
private void btExportarCSV_Click(object sender, EventArgs e) { string caracterSeparadorCampos = txtSeparadorExportar.Text; if (txtFicheroExportarCSV.Text == "" || caracterSeparadorCampos == "") { MessageBox.Show("Debe indicar el fichero CSV en el que se exportará " + "la información, así como el separador a usar.", "Exportar a CSV...", MessageBoxButtons.OK, MessageBoxIcon.Information); txtFicheroExportarCSV.Focus(); } else { string caracterSeparadorValores = txtSeparadorValoresExportar.Text; if (Directory.Exists(Path.GetDirectoryName(txtFicheroExportarCSV.Text))) { StringBuilder csvMemoria = new StringBuilder(); //para los títulos de las columnas, encabezado for (int i = 0; i < dbTabla.Columns.Count; i++) { if (i == dbTabla.Columns.Count - 1) { csvMemoria.Append(String.Format(caracterSeparadorValores + "{0}" + caracterSeparadorValores, dbTabla.Columns[i].HeaderText)); } else { csvMemoria.Append(String.Format(caracterSeparadorValores + "{0}" + caracterSeparadorValores + caracterSeparadorCampos, dbTabla.Columns[i].HeaderText)); } } csvMemoria.AppendLine(); for (int m = 0; m < dbTabla.Rows.Count; m++) { for (int n = 0; n < dbTabla.Columns.Count; n++) { //si es la última columna no poner el separador if (n == dbTabla.Columns.Count - 1) { csvMemoria.Append(String.Format(caracterSeparadorValores + "{0}" + caracterSeparadorValores, dbTabla.Rows[m].Cells[n].Value)); } else { csvMemoria.Append(String.Format(caracterSeparadorValores + "{0}" + caracterSeparadorValores + caracterSeparadorCampos, dbTabla.Rows[m].Cells[n].Value)); } } csvMemoria.AppendLine(); } try { System.IO.StreamWriter sw = new System.IO.StreamWriter(txtFicheroExportarCSV.Text, false, System.Text.Encoding.Default); sw.Write(csvMemoria.ToString(), Encoding.Default); sw.Close(); MessageBox.Show("Se ha exportado el contenido del grid al fichero CSV correctamente.", "Exportado a fichero CSV...", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { MessageBox.Show(ex.Message.ToString(), "Error al exportar CSV...", MessageBoxButtons.OK, MessageBoxIcon.Error); txtFicheroExportarCSV.Focus(); } } else { MessageBox.Show("La carpeta indicada para el fichero de exportación CSV no existe.", "Exportar a fichero CSV...", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } } } |
La aplicación ProyectoA Leer Ficheros CSV en funcionamiento
La aplicación permite leer ficheros CSV con cualquier carácter separador de campos y cualquier carácter separador de valores, dado que se pueden especificar estos dos valores antes de realizar la lectura del fichero CSV. Por ejemplo, si la estructura del fichero CSV es como esta:
1 |
"Número de factura";"Cliente";"Importe";"Fecha de alta"<br>"ASP00098";"ProyectoA","1253,89";"01-07-2020" |
Indicaremos en la aplicación, en el campo «Carácter separador de campos», introduciremos punto y coma «;» y en el campo «Carácter separador de valores», introduciremos comillas dobles «. Si la primera línea contiene el nombre de los títulos de las columnas marcaremos «La primera línea contiene los títulos de las columnas». Seleccionaremos el fichero CSV que queramos leer y pulsaremos en «Leer»:
Una vez leído el fichero CSV y mostrado en el grid, podremos modificar las líneas, añadir nuevas líneas o eliminar alguna de las existentes (seleccionándola y pulsando en Control + Suprimir) :
Una vez realizadas las modificaciones, si queremos guardar el contenido del grid en un fichero CSV, elegiremos el fichero en «Exportar grid a fichero CSV» y pulsaremos en «Exportar». El contenido del grid se guardará en un fichero CSV con los caracteres separador de campos y separador de valores indicados:
Descarga del código fuente completo de la aplicación ProyectoA Leer Ficheros CSV en funcionamiento
A continuación dejamos enlace para la descarga del código fuente completo en C# (C Sharp), con Microsoft Visual Studio Community 2019 Community:
Hola… Se puede hacer un log sobre el proceso de carga del archivo?
indicando los errores encontrados