0

我有一个List<Customer>包含5,000Customer行的

public class Customer{

    public Int32 CustomerID {get;set;}

    public String Name {get;set;}

    public Decimal AccountPrice {get;set;}


}

我想将此列表转换为CSV并将其作为下载提供给浏览器。我有成功返回流的代码,HttpContextBase但文件的内容不起作用。

我努力了

String.Join("," customers.Select(x=> new{ Name = x.Name.ToString(), AccountPrice = AccountPrice.ToString() }).ToArray());

但这不适用于异常匿名类型ToArray()任何指导将不胜感激。

4

4 回答 4

3

既然你坚持一条线...

List<Customer> myList;

String.Join(System.Environment.NewLine,myList.Select(c=>String.Join(",", new[]{c.ID.ToString(), c.Name}));

或者你可以通过迭代来做到这一点。压缩代码应该是首选......除非它更难阅读

这是一个紧凑但仍然可读的版本:

StringBuilder csv = new StringBuilder();

myList.ForEach(c=>{
   csv.Append(c.ID).Append(",");
   csv.Append(c.Name).Append(System.Environment.NewLine); 
});
于 2013-07-12T20:14:12.450 回答
3
StringBuilder sb = new StringBuilder();

sb.Append("Name");
sb.Append(",");
sb.Append("Account Price");
sb.Append(System.Environment.NewLine);

foreach (Customer c in customers)
{
    sb.Append(c.Name);
    sb.Append(",");
    sb.Append(c.AccountPrice);
    sb.Append(System.Environment.NewLine);
}

 string csv = sb.ToString();

这对我来说更容易一目了然。在您的尝试中,您不使用新行,这是在 CSV 中创建行所必需的,您知道这一点。

于 2013-07-12T20:17:30.613 回答
2

这就是我通常的做法。我有一个扩展 FileResult 类的 CSVResult 类,如下所示:

public class CSVResult : FileResult
{
    private IQueryable _data;
    private string[] _headers;

    public CSVResult(string fileName, IQueryable data)
        : base("text/csv")
    {
        this.FileDownloadName = fileName;
        _data = data;
    }

    public CSVResult(string fileName, IQueryable data, string[] headers)
        : this(fileName, data)
    {
        _headers = headers;
    }

    // Returns a string array containing the headers (column names) 
    private string[] GetHeaders()
    {
        var headers = (from p in _data.ElementType.GetProperties()
                        select p.Name).ToArray();

        return headers;
    }

    // Writes the CSV file to the http response 
    protected override void WriteFile(HttpResponseBase response)
    {
        Stream outputStream = response.OutputStream;
        using (MemoryStream memoryStream = new MemoryStream())
        {
            WriteObject(memoryStream);
            outputStream.Write(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
        }
    }

    // Writes the CSV data into a stream
    private void WriteObject(Stream stream)
    {
        StreamWriter writer = new StreamWriter(stream, System.Text.Encoding.Default);

        if (_headers == null)
        {
            _headers = GetHeaders();
        }

        // First line for column names                        
        foreach (var h in _headers)
        {
            writer.Write(string.Format("\"{0}\",", h));
        }

        writer.WriteLine();

        foreach (var row in _data)
        {
            foreach (var p in row.GetType().GetProperties())
            {
                var value = p.GetValue(row, null);
                string strValue = value == null ? string.Empty : value.ToString();

                writer.Write(string.Format("\"{0}\",", strValue));
            }

            writer.WriteLine();
        }

        writer.Flush();
    }
}

然后,您可以像这样在 Controller 中使用它:

public ActionResult ExportToCSV() 
{
    var data = customers.AsQueryable();
    var fileName = "customers.csv";

    return new CSVResult(fileName, data);
}

当您不提供列名时,CSVResult 类使用属性名作为列名。但是,您也可以像这样提供列名:

public ActionResult ExportToCSV() 
{
    var data = customers.AsQueryable();
    var fileName = "customers.csv";
    string[] headers = new string[] { "Customer ID", "Customer Name", "Account Price" };

    return new CSVResult(fileName, data, headers);
}
于 2013-07-13T01:36:14.003 回答
-1

您可以使用 OLEDB,例如,您可以对 CSV 执行类似以下操作,对 Excel 执行类似操作

//Target Database: CSV
string strBasePath = @"C:\Database";
string strFilename = @"NewCSV.csv";
string CSVConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source='" + strBasePath + @"';Extended Properties='text; HDR=Yes;FMT=Delimited';";

接着 :

using (OleDbConnection CSVConnection = new OleDbConnection(CSVConnectionString))
{
     try
     {
         CSVConnection.Open();
         string strInsertCommand = @"INSERT INTO " + strFilename + @" (CustomerID, CustomerName, Country) VALUES (@custid, @name, @country)";
         OleDbCommand InsertCommanmd = CSVConnection.CreateCommand();
         InsertCommanmd.CommandText = strInsertCommand;

         foreach ( var item in List<T> )
         {
             InsertCommanmd.Parameters.Clear();
             InsertCommanmd.Parameters.AddWithValue("@custid", item.prop1);
             InsertCommanmd.Parameters.AddWithValue("@name", item.prop2);
             InsertCommanmd.Parameters.AddWithValue("@country", item.prop3);
             InsertCommanmd.ExecuteNonQuery();
         }
     }
     finally
     {
          if (!CSVConnection.State.Equals(ConnectionState.Closed))
              CSVConnection.Close();
     }
}

为了在 Excel 中抢占先机:

string ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Path\Book81.xlsx;Extended Properties=Excel 8.0;";
OleDbConnection ExcelConnection = new OleDbConnection(ConnectionString);
ExcelConnection.Open();
string update = "UPDATE [Sheet1$] SET Name='Smith Jones' where name='Smith'";
OleDbCommand UpdateCommand = new OleDbCommand(update, ExcelConnection);
UpdateCommand.ExecuteNonQuery();
于 2013-07-12T20:35:26.333 回答