簡體   English   中英

在C#中創建一個.csv文件

[英]Create a .csv file in C#

好了,我想在C#中創建一個.csv文件。 我一直在環顧四周,發現很多人都在使用system.IO.memorystream和system.io.streamwriter。

問題是這樣的:我有一個Web應用程序。 我想給用戶導出到Excel的能力。 問題是,Excel無法安裝在服務器上(不要詢問)。 我希望能夠為報告編寫.csv工作表導出。 現在,所有報告的報告標題和數據都將有所不同(通過循環可以解決此問題)。 有人有例子或更好的資源供我參考嗎?

我通常采用這種方法。 可能不是最有效的。

        /// <summary>
    /// Generates the contents of the log file.
    /// </summary>
    /// <returns>The contents of the log file.</returns>
    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();
    }

    /// <summary>
    /// Adds the CSV file to the response.
    /// </summary>
    /// <param name="csvExportContents">The contents of the CSV file.</param>
    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<T>(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<T>(StreamWriter sr, IEnumerable<T> line)
{
    bool first = true;
    foreach(T item in line)
    {
        if(!first)
            sr.Write(',');
        first = false;
        WriteItem(sr, item);
    }
}
private void WriteCSV<T>(StreamWriter sr, IEnumerable<IEnumerable<T>> allLines)
{
    bool first = true;
    foreach(IEnumerable<T> line in allLines)
    {
        if(!first)
            sr.Write('\n');
        first = false;
        WriteLine(sr, line);
    }
}
private void WriteCSV<T>(HttpResponse response, IEnumerable<IEnumerable<T>> allLines)
{
    response.ContentType = "text/csv";
    WriteCSV(response.Output, allLines);
}

還可以發送帶有建議文件名的content-disposition標頭。

編輯:最近,在某些情況下需要在枚舉中的項之間進行操作間隔(例如上面的逗號和換行符)時,我寧願保留一個保持被檢查的布爾值,而是直接處理枚舉器,然后將第一個元素與其余元素分開處理。 我以效率提升中的微型選擇開始進行此操作,但是逐漸發現它可以更好地表達與第一項不同的代碼路徑。 因此,我現在將以上內容寫為:

private void WriteLine<T>(StreamWriter sr, IEnumerable<T> 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<T>(StreamWriter sr, IEnumerable<IEnumerable<T>> allLines)
{
    using(var en = allLines.GetEnumerator())
    if(en.MoveNext())
    {
      WriteLine(sr, en.Current);
      while(en.MoveNext())
      {
        sr.Write('\n');
        WriteLine(sr, en.Current);
      }
    }
}

您應該能夠使用使用System.IO.MemoryStreamSystem.IO.StreamWriter的示例就可以了。

而不是將MemoryStream寫出到文件中,而是將其作為ASP.NET中的ResponseStream返回(確保設置了適當的標頭值,以便瀏覽器知道它正在下載文件)。

僅當使用Office Interop時才需要Excel。 使用StringWriter,您只需創建一個文件並添加一些響應信息。 僅在打開文件時才需要Excel。

創建CSV文件真的沒有魔術。 CSV文件的唯一問題是沒有真正的標准,大多數進口商只會在導入過程中實現一種特定的行為。 如果幸運的話,您會得到一些可以相對猜測的東西。

生成CSV文件只是打印行。 至於實際細節,請熟悉以下內容:

http://en.wikipedia.org/wiki/Comma-separated_values

話雖如此,如果要導出到Excel,則可以使用Microsoft的OOXML SDK:

http://msdn.microsoft.com/en-us/library/bb448854.aspx

OOXML SDK是一個C#庫,可用於在服務器上生成Excel文件。 Brian Jones博客是有關如何使用此庫的重要資源:

http://blogs.msdn.com/b/brian_jones/

如果您不介意使用第三方庫並且您的項目中存在LGPL許可證,那么FileHelpers就是一個很好的工具。

這是用於創建csv文件的功能:

 private async Task<string> WriteCSV<ViewModel>(IEnumerable<ViewModel> viewModels, string path)
            {
                Type itemType = typeof(ViewModel);
                var props = itemType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                    .OrderBy(p => p.Name);

                var blobName = string.Empty;

                using (var ms = new MemoryStream())
                {

                    using (var writer = new System.IO.StreamWriter(ms))
                    {
                        writer.WriteLine(string.Join(", ", props.Select(p => p.Name)));

                        foreach (var item in viewModels)
                        {

                            writer.WriteLine(string.Join(", ", props.Select(p => p.GetValue(item, null))));
                        }
    }

 }
    }

否則,您可以參考以下鏈接:

https://travelcodingnlotsmore.wordpress.com/2013/06/06/creating-csv-file-from-data-in-list-object-in-c/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM