簡體   English   中英

寫入CSV文件並導出?

[英]Write to CSV file and export it?

在C#ASP.net中,有人可以告訴我如何將數組/列表中的條目寫入服務器上的CSV文件,然后打開文件嗎? 我認為第二部分將是 - Response.Redirect(“ http://myserver.com/file.csv ”),但不確定如何在服務器上寫入文件。

此外,如果許多用戶訪問此頁面,是否每次生成新的CSV文件或覆蓋同一文件更好? 如果兩個用戶都嘗試訪問相同的CSV文件等,是否會出現讀/寫/鎖定問題?


更新:

這可能是一個愚蠢的問題,我在Google上搜索過,但我無法找到明確的答案 - 你如何將CSV文件寫入網絡服務器並將其導出到C#ASP.net? 我知道如何生成它,但我想將其保存到www.mysite.com/my.csv然后導出它。

羅姆,你做錯了。 您不希望將文件寫入磁盤,以便IIS可以為它們提供服務。 這增加了安全隱患並增加了復雜性。 您真正需要做的就是將CSV直接保存到響應流中。

這是場景:用戶希望下載csv。 用戶提交一個表單,其中包含有關他們想要的csv的詳細信息。 您准備csv,然后向用戶提供一個aspx頁面的URL,該頁面可用於構造csv文件並將其寫入響應流。 用戶單擊該鏈接。 aspx頁面是空白的; 在頁面代碼隱藏中,您只需將csv寫入響應流並結束它。

您可以添加以下內容(我相信這是正確的) 加載事件:

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());

寫入響應流代碼從這里開始

這是一個非常簡單的C#免費開源CsvExport類。 底部有一個ASP.NET MVC示例。

https://github.com/jitbit/CsvExport

它關注換行符,逗號,轉義引號,MS Excel兼容性...只需將一個簡短的.cs文件添加到您的項目中,您就可以開始了。

(免責聲明:我是貢獻者之一)

關於Will的答案的評論,你可能想要替換HttpContext.Current.Response.End(); 使用HttpContext.Current.ApplicationInstance.CompleteRequest(); 原因是Response.End()拋出System.Threading.ThreadAbortException 它中止一個線程。 如果你有一個異常記錄器,那么它將充滿ThreadAbortExceptions,在這種情況下是預期的行為。

直觀地說,將CSV文件發送到瀏覽器不應引發異常。

在這里查看更多是否Response.End()被認為是有害的?

這是我寫的一個CSV動作結果,它采用DataTable並將其轉換為CSV。 您可以從視圖中返回此內容,它將提示用戶下載該文件。 您應該能夠輕松地將其轉換為List兼容表單,甚至只需將列表放入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
    {
        /// <summary>
        /// Converts the columns and rows from a data table into an Microsoft Excel compatible CSV file.
        /// </summary>
        /// <param name="dataTable"></param>
        /// <param name="fileName">The full file name including the extension.</param>
        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;
        }
    }
}

如何寫入文件(在Google中輕松搜索)... 第一個搜索結果

至於每次用戶訪問頁面時創建文件......每次訪問都將代表自己的行為。 您的業​​務案例將決定行為。

案例1 - 相同的文件但不會改變(這種類型的案例可以有多種方式被定義)

  • 您將擁有在需要時創建文件的邏輯,並且只有在不需要生成時才訪問該文件。

案例2 - 每個用戶都需要生成自己的文件

  • 您將決定如何識別每個用戶,為每個用戶創建文件以及訪問他們應該看到的文件...這可以輕松地與案例1合並。然后在提供內容后刪除文件,如果需要持久性。

案例3 - 每個訪問都需要生成相同的文件

  • 使用案例2,這將導致每次生成一次,但一旦訪問就清理。

暫無
暫無

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

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