Escribir en un archivo CSV y exportarlo?

En C # ASP.net, ¿podría alguien mostrarme cómo puedo escribir entradas de una Matriz / Lista en un archivo CSV en el servidor y luego abrir el archivo? Creo que la segunda parte sería algo así como: Response.Redirect (” http://myserver.com/file.csv “), pero no estoy seguro de cómo escribir el archivo en el servidor.

Además, si muchos usuarios acceden a esta página, ¿es mejor generar un nuevo archivo CSV cada vez o sobrescribir el mismo? ¿Habrá problemas de lectura / escritura / locking si ambos usuarios intentan acceder al mismo archivo CSV, etc.?


Actualizar:

Esta es probablemente una pregunta tonta y he buscado en Google, pero no puedo encontrar una respuesta definitiva: ¿cómo se escribe un archivo CSV en el servidor web y se exporta en C # ASP.net? Sé cómo generarlo, pero me gustaría guardarlo en www.mysite.com/my.csv y luego exportarlo.

Rom, lo estás haciendo mal. No desea escribir archivos en el disco para que IIS pueda servirlos. Eso agrega implicaciones de seguridad y aumenta la complejidad. Todo lo que necesitas hacer es guardar el archivo CSV directamente en la secuencia de respuesta.

Este es el escenario: el usuario desea descargar csv. El usuario envía un formulario con detalles sobre el csv que desea. Usted prepara el csv, luego proporciona al usuario una URL a una página aspx que puede usarse para construir el archivo csv y escribirlo en la secuencia de respuesta. El usuario hace clic en el enlace. La página aspx está en blanco; en el código de la página detrás de usted simplemente escriba la csv en la secuencia de respuesta y finalícela.

Puede agregar lo siguiente al evento Load (creo que es correcto):

string attachment = "attachment; filename=MyCsvLol.csv"; HttpContext.Current.Response.Clear(); HttpContext.Current.Response.ClearHeaders(); HttpContext.Current.Response.ClearContent(); HttpContext.Current.Response.AddHeader("content-disposition", attachment); HttpContext.Current.Response.ContentType = "text/csv"; HttpContext.Current.Response.AddHeader("Pragma", "public"); var sb = new StringBuilder(); foreach(var line in DataToExportToCSV) sb.AppendLine(TransformDataLineIntoCsv(line)); HttpContext.Current.Response.Write(sb.ToString()); 

escribiendo en el código de flujo de respuesta enlazado desde aquí .

Aquí hay una clase de código abierto CsvExport muy simple para C #. Hay un ejemplo de ASP.NET MVC en la parte inferior.

https://github.com/jitbit/CsvExport

Se ocupa de los saltos de línea, las comas, las comillas de escape, la compatibilidad de MS Excel … Simplemente agregue un archivo .cs corto a su proyecto y listo.

(descargo de responsabilidad: soy uno de los contribuyentes)

Un comentario sobre la respuesta de Will, es posible que desee reemplazar HttpContext.Current.Response.End(); con HttpContext.Current.ApplicationInstance.CompleteRequest(); La razón es que Response.End() arroja una System.Threading.ThreadAbortException . Anula un hilo. Si tiene un registrador de excepciones, estará lleno de ThreadAbortExceptions, que en este caso es el comportamiento esperado.

Intuitivamente, enviar un archivo CSV al navegador no debe generar una excepción.

Vea aquí para más ¿Es Response.End () considerado dañino?

Aquí hay un resultado de acción CSV que escribí que toma una DataTable y la convierte en CSV. Puede devolver esto desde su vista y le pedirá al usuario que descargue el archivo. Debería poder convertir esto fácilmente en un formulario compatible con la Lista o incluso simplemente poner su lista en una DataTable.

 using System; using System.Text; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Data; namespace Detectent.Analyze.ActionResults { public class CSVResult : ActionResult { ///  /// Converts the columns and rows from a data table into an Microsoft Excel compatible CSV file. ///  ///  /// The full file name including the extension. public CSVResult(DataTable dataTable, string fileName) { Table = dataTable; FileName = fileName; } public string FileName { get; protected set; } public DataTable Table { get; protected set; } public override void ExecuteResult(ControllerContext context) { StringBuilder csv = new StringBuilder(10 * Table.Rows.Count * Table.Columns.Count); for (int c = 0; c < Table.Columns.Count; c++) { if (c > 0) csv.Append(","); DataColumn dc = Table.Columns[c]; string columnTitleCleaned = CleanCSVString(dc.ColumnName); csv.Append(columnTitleCleaned); } csv.Append(Environment.NewLine); foreach (DataRow dr in Table.Rows) { StringBuilder csvRow = new StringBuilder(); for(int c = 0; c < Table.Columns.Count; c++) { if(c != 0) csvRow.Append(","); object columnValue = dr[c]; if (columnValue == null) csvRow.Append(""); else { string columnStringValue = columnValue.ToString(); string cleanedColumnValue = CleanCSVString(columnStringValue); if (columnValue.GetType() == typeof(string) && !columnStringValue.Contains(",")) { cleanedColumnValue = "=" + cleanedColumnValue; // Prevents a number stored in a string from being shown as 8888E+24 in Excel. Example use is the AccountNum field in CI that looks like a number but is really a string. } csvRow.Append(cleanedColumnValue); } } csv.AppendLine(csvRow.ToString()); } HttpResponseBase response = context.HttpContext.Response; response.ContentType = "text/csv"; response.AppendHeader("Content-Disposition", "attachment;filename=" + this.FileName); response.Write(csv.ToString()); } protected string CleanCSVString(string input) { string output = "\"" + input.Replace("\"", "\"\"").Replace("\r\n", " ").Replace("\r", " ").Replace("\n", "") + "\""; return output; } } } 

Cómo escribir en un archivo (búsqueda fácil en Google) … Primer resultado de búsqueda

En cuanto a la creación del archivo cada vez que un usuario accede a la página … cada acceso actuará en su propio nombre. Su caso comercial dictará el comportamiento.

Caso 1: el mismo archivo, pero no cambia (este tipo de caso puede tener múltiples formas de ser definido)

  • Tendría la lógica que creaba el archivo cuando era necesario y solo accedía al archivo si la generación no era necesaria.

Caso 2: cada usuario necesita generar su propio archivo

  • Usted decidiría cómo identifica a cada usuario, crea un archivo para cada usuario y accede al archivo que se supone que debe ver … esto puede fusionarse fácilmente con el Caso 1. Luego, borra el archivo después de publicar el contenido o no si requiere persistencia .

Caso 3: el mismo archivo pero la generación requerida para cada acceso

  • Use el Caso 2, esto generará una generación cada vez pero se limpiará una vez que se acceda a ella.

echa un vistazo a la biblioteca csvreader / writer en http://www.codeproject.com/KB/cs/CsvReaderAndWriter.aspx