¿Alguien podría decirme por qué el siguiente código no funciona? Los datos se guardan en el archivo csv, sin embargo, no se separan. Todo existe dentro de la primera celda de cada fila.
StringBuilder sb = new StringBuilder();
foreach (DataColumn col in dt.Columns)
{
sb.Append(col.ColumnName + ',');
}
sb.Remove(sb.Length - 1, 1);
sb.Append(Environment.NewLine);
foreach (DataRow row in dt.Rows)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
sb.Append(row[i].ToString() + ",");
}
sb.Append(Environment.NewLine);
}
File.WriteAllText("test.csv", sb.ToString());
Gracias.
c#
csv
delimited-text
Darren Young
fuente
fuente
Respuestas:
La siguiente versión más corta se abre bien en Excel, tal vez su problema fue la coma final
.net = 3.5
.net> = 4.0
Y como Tim señaló, si estás en .net> = 4, puedes hacerlo aún más corto:
Como sugirió Christian, si desea manejar caracteres especiales que se escapan en los campos, reemplace el bloque de bucle por:
Y la última sugerencia, podría escribir el contenido csv línea por línea en lugar de como un documento completo, para evitar tener un documento grande en la memoria.
fuente
ItemArray
a uno nuevoString[]
, puede omitir.ToArray()
con .NET 4 y usar laString.Join
sobrecarga que toma unIEnumerable<T>
(editado). 
es típica de documentos HTML / XML. No es el código anterior el que lo produce a menos que la tabla contenga
explícitamenteEnvolví esto en una clase de extensión, que te permite llamar:
en cualquier DataTable.
fuente
Una nueva función de extensión basada en la respuesta de Paul Grimshaw. Lo limpié y agregué la capacidad de manejar datos inesperados. (Datos vacíos, citas incrustadas y comas en los encabezados ...)
También devuelve una cadena que es más flexible. Devuelve Null si el objeto de la tabla no contiene ninguna estructura.
Lo llamas de la siguiente manera:
fuente
Si su código de llamada hace referencia al
System.Windows.Forms
ensamblado, puede considerar un enfoque radicalmente diferente. Mi estrategia es usar las funciones que ya proporciona el marco para lograr esto en muy pocas líneas de código y sin tener que recorrer columnas y filas. Lo que hace el siguiente código es crear programáticamente unDataGridView
sobre la marcha y establecerloDataGridView.DataSource
enDataTable
. A continuación, selecciono programáticamente todas las celdas (incluido el encabezado) enDataGridView
y llamoDataGridView.GetClipboardContent()
, colocando los resultados en WindowsClipboard
. Luego, 'pego' el contenido del portapapeles en una llamada aFile.WriteAllText()
, asegurándome de especificar el formato del 'pegar' comoTextDataFormat.CommaSeparatedValue
.Aquí está el código:
Tenga en cuenta que también me aseguro de preservar el contenido del portapapeles antes de comenzar y restaurarlo una vez que termine, para que el usuario no reciba un montón de basura inesperada la próxima vez que intente pegar. Las principales advertencias para este enfoque son 1) Su clase tiene que hacer referencia
System.Windows.Forms
, lo que puede no ser el caso en una capa de abstracción de datos, 2) Su ensamblado tendrá que estar dirigido a .NET 4.5 framework, ya que DataGridView no existe en 4.0, y 3) El método fallará si el portapapeles está siendo utilizado por otro proceso.De todos modos, este enfoque puede no ser el adecuado para su situación, pero es interesante de todos modos y puede ser otra herramienta en su caja de herramientas.
fuente
.GetClipboardContent
también maneja algunos casos extremos de valores que contienen,
."
,\t
(convierte la pestaña en espacio)Hice esto recientemente, pero incluí comillas dobles alrededor de mis valores.
Por ejemplo, cambie estas dos líneas:
fuente
Intente cambiar
sb.Append(Environment.NewLine);
asb.AppendLine();
.fuente
Intenta poner en
;
lugar de,
Espero eso ayude
fuente
¿Leer esto y esto ?
Una mejor implementación sería
fuente
El error es el separador de listas.
En lugar de escribir
sb.Append(something... + ',')
deberías poner algo comosb.Append(something... + System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator);
Debe poner el carácter separador de lista configurado en su sistema operativo (como en el ejemplo anterior), o el separador de lista en la máquina cliente donde se va a ver el archivo. Otra opción sería configurarlo en app.config o web.config como parámetro de tu aplicación.
fuente
4 líneas de código:
Tenga en cuenta que el
ToList()
al final es importante; Necesito algo para forzar una evaluación de expresión. Si estuviera jugando al golf en código, podría usarMin()
en su lugar.También tenga en cuenta que el resultado tendrá una nueva línea al final debido a la última llamada a
AppendLine()
. Puede que no quieras esto. Simplemente puede llamarTrimEnd()
para eliminarlo.fuente
Aquí hay una mejora de la publicación de vc-74 que maneja las comas de la misma manera que lo hace Excel. Excel pone comillas alrededor de los datos si los datos tienen una coma, pero no las cita si los datos no tienen una coma.
fuente
Para escribir en un archivo, creo que el siguiente método es el más eficiente y sencillo: (puede agregar comillas si lo desea)
fuente
Para imitar CSV de Excel:
fuente
fuente
fuente
Posiblemente, la forma más fácil será utilizar:
https://github.com/ukushu/DataExporter
especialmente en el caso de sus datos de tabla de datos que contienen
/r/n
caracteres o símbolo separador dentro de sus celdas de tabla de datos. Casi todas las demás respuestas no funcionarán con estas celdas.solo necesitas escribir el siguiente código:
fuente
En caso de que alguien más se tropiece con esto, estaba usando File.ReadAllText para obtener datos CSV y luego lo modifiqué y lo escribí con File.WriteAllText . Las \ r \ n CRLF estaban bien, pero las pestañas \ t se ignoraron cuando Excel las abrió. (Todas las soluciones en este hilo hasta ahora usan un delimitador de coma, pero eso no importa). El Bloc de notas mostró el mismo formato en el archivo resultante que en la fuente. Un Diff incluso mostró que los archivos eran idénticos. Pero tuve una pista cuando abrí el archivo en Visual Studio con un editor binario. El archivo de origen era Unicode pero el destino era ASCII . Para solucionarlo, modifiqué ReadAllText y WriteAllText con el tercer argumento establecido como System.Text.Encoding.Unicode , y desde allí Excel pudo abrir el archivo actualizado.
fuente
FYR
fuente
Aquí está mi solución, basada en respuestas anteriores de Paul Grimshaw y Anthony VO . Envié el código en un proyecto C # en Github .
Mi principal contribución es eliminar la creación y manipulación explícita de un
StringBuilder
y, en cambio, trabajar solo conIEnumerable
. Esto evita la asignación de un gran búfer en la memoria.}
Este enfoque se combina muy bien con la conversión
IEnumerable
a DataTable como se solicita aquí .fuente
También necesitaba anular algunos datos, por lo que hay algunas declaraciones "si más". Necesitaba asegurarme de que si un campo estaba vacío para ingresar "N / A" en su lugar, o si un campo de fecha tenía el formato "01/01/1900: 00", se guardaría como "01/01/1900" en lugar.
fuente
fuente
Si todos los datos aún están en la primera celda, significa que la aplicación con la que abrió el archivo espera otro delimitador. MSExcel puede manejar la coma como delimitador a menos que especifique lo contrario.
fuente