好吧我想在C#中创建一个.csv文件.我一直在四处寻找并注意到很多人正在使用system.IO.memorystream和system.io.streamwriter.
问题是:我有一个Web应用程序.我想让用户能够导出到excel.问题是,Excel无法安装在服务器上(不要问).我希望能够为报告编写.csv工作表导出.现在,报告标题和数据对于所有报告都是不同的(循环将解决此问题).任何人都有一个例子或更好的资源让我通过?
这是我通常采用的方法.可能不是最有效的.
////// Generates the contents of the log file. /// ///The contents of the log file. internal string GenerateLogFile() { StringBuilder csvExport = new StringBuilder(); csvExport.AppendLine(Resources.CSVHeader); foreach (DataRow row in this.logEntries.Rows) { csvExport.AppendLine( string.Format( "\"{0}\",\"{1}\",\"{2}\",\"{3}\",\"{4}\",\"{5}\",\"{6}\",\"{7}\",\"{8}\", \"{9}\"", row[ColumnNames.LogTime], row[ColumnNames.Field1], row[ColumnNames.Field2], row[ColumnNames.Field3], row[ColumnNames.Field4], row[ColumnNames.Field5], row[ColumnNames.Field6], row[ColumnNames.Field7], row[ColumnNames.Field8], row[ColumnNames.Field9])); } return csvExport.ToString(); } ////// Adds the CSV file to the response. /// /// The contents of the CSV file. internal void DisplayLogFile(string csvExportContents) { byte[] data = new ASCIIEncoding().GetBytes(csvExportContents); HttpContext.Current.Response.Clear(); HttpContext.Current.Response.ContentType = "APPLICATION/OCTET-STREAM"; HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=Export.csv"); HttpContext.Current.Response.OutputStream.Write(data, 0, data.Length); HttpContext.Current.Response.End(); }
private void WriteItem(StreamWriter sr, T item) { string itemString = item.ToString(); if(itemString.IndexOfAny(new char[] { '"', ',', '\n', '\r' }) != -1)//skip test and always escape for different speed/filesize optimisation { sr.Write('"'); sr.Write(itemString.Replace("\"", "\"\"")); sr.Write('"'); } else sr.Write(itemString); } private void WriteLine (StreamWriter sr, IEnumerable line) { bool first = true; foreach(T item in line) { if(!first) sr.Write(','); first = false; WriteItem(sr, item); } } private void WriteCSV (StreamWriter sr, IEnumerable > allLines) { bool first = true; foreach(IEnumerable line in allLines) { if(!first) sr.Write('\n'); first = false; WriteLine(sr, line); } } private void WriteCSV (HttpResponse response, IEnumerable > allLines) { response.ContentType = "text/csv"; WriteCSV(response.Output, allLines); }
还可以使用推荐的文件名发送内容处置标头.
编辑:最近,如果需要在枚举中的项之间间隔一个动作(如上面的逗号和换行符),我宁愿保留一个继续被检查的布尔值,我直接处理枚举器,然后处理与其余元素分开的第一个元素.我开始将这作为效率推动的微观选择,但已经发展到只是发现它更好地表达了第一项不同的代码路径.因此,我现在将上述内容写成:
private void WriteLine(StreamWriter sr, IEnumerable line) { using(var en = line.GetEnumerator()) if(en.MoveNext()) { WriteItem(sr, en.Current); while(en.MoveNext()) { sr.Write(','); WriteItem(sr, en.Current); } } private void WriteCSV (StreamWriter sr, IEnumerable > allLines) { using(var en = allLines.GetEnumerator()) if(en.MoveNext()) { WriteLine(sr, en.Current); while(en.MoveNext()) { sr.Write('\n'); WriteLine(sr, en.Current); } } }