IEnumerable <t>到CSV文件</t>

时间:2011-06-01 10:22:08

标签: c# .net linq csv

我从LINQ查询得到的结果为IEnumerable<T>

类型的var

我希望根据LINQ

的结果创建CSV文件

我从以下查询中获得结果

var r = from table in myDataTable.AsEnumerable()
        orderby table.Field<string>(para1)
        group table by new { Name = table[para1], Y = table[para2] }
        into ResultTable
        select new
        {
            Name = ResultTable.Key,
            Count = ResultTable.Count()
        };

6 个答案:

答案 0 :(得分:17)

检查

 public static class LinqToCSV
    {
        public static string ToCsv<T>(this IEnumerable<T> items)
            where T : class
        {
            var csvBuilder = new StringBuilder();
            var properties = typeof(T).GetProperties();
            foreach (T item in items)
            {
                string line = string.Join(",",properties.Select(p => p.GetValue(item, null).ToCsvValue()).ToArray());
                csvBuilder.AppendLine(line);
            }
            return csvBuilder.ToString();
        }

        private static string ToCsvValue<T>(this T item)
        {
            if(item == null) return "\"\"";

            if (item is string)
            {
                return string.Format("\"{0}\"", item.ToString().Replace("\"", "\\\""));
            }
            double dummy;
            if (double.TryParse(item.ToString(), out dummy))
            {
                return string.Format("{0}", item);
            }
            return string.Format("\"{0}\"", item);
        }
    }

完整代码:Scott Hanselman's ComputerZen Blog - From Linq To CSV

答案 1 :(得分:6)

IEnumerable<string> lines = r.Select(x => String.Format("{0},{1}", r.Name, r.Count));
System.IO.File.WriteAllLines(path, lines);

将产生:

name1,count1
name2,count2
...

答案 2 :(得分:2)

对于Linq2CSV来说,这是在尖叫:

http://www.codeproject.com/KB/linq/LINQtoCSV.aspx

也可以在nuget上找到:

http://nuget.org/List/Packages/LinqToCsv

优秀的图书馆,真的值得推荐。

答案 3 :(得分:2)

不清楚你真正想要的是什么,但这可以是一个解决方案public void Read(){

    var r = from table in myDataTable.AsEnumerable()
            orderby table.Field<string>(para1)
            group table by new { Name = table[para1], Y = table[para2] }
                into ResultTable
                select new NameCount()
                {
                    Name = ResultTable.Key,
                    Count = ResultTable.Count()
                }.ToString();

    //Write all r to a File
}
public class NameCount
{
    public string Name { get; set; }
    public int Count { get; set; }
    public string ToString()
    {
        return string.Format("{0},{1}\r\n", Name, Count);
    }
}

答案 4 :(得分:1)

这是我用于任何IEnumerable的基本解决方案:

using System.Reflection;
using System.Text;
//***        
    public void ToCSV<T>(IEnumerable<T> items, string filePath)
    {
        var dataTable = new DataTable(typeof(T).Name);
        PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
        foreach (var prop in props)
            dataTable.Columns.Add(prop.Name, prop.PropertyType);

        foreach (var item in items)
        {
            var values = new object[props.Length];
            for (var i = 0; i < props.Length; i++)
            {
                values[i] = props[i].GetValue(item, null);
            }
            dataTable.Rows.Add(values);
        }

        StringBuilder fileContent = new StringBuilder();
        foreach (var col in dataTable.Columns)
            fileContent.Append(col.ToString() + ",");

        fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);

        foreach (DataRow dr in dataTable.Rows)
        {
            foreach (var column in dr.ItemArray)
                fileContent.Append("\"" + column.ToString() + "\",");

            fileContent.Replace(",", System.Environment.NewLine, fileContent.Length - 1, 1);
        }

        //good place to validate File.Exist or catch exceptions
        System.IO.File.WriteAllText(filePath, fileContent.ToString());            
    }

答案 5 :(得分:0)

我从你的问题中假设你想要一个 Generic 方法来做这件事,不管T是什么?

这样的东西
public void ToCSV<T>(IEnumerable<T>, TextWriter writer) . . .

您无法克服的问题是,T是一个复杂的类型,逗号分隔T的每个元素,您需要了解T的内部,或{ {1}}需要知道如何将它自己写为CSV行,这意味着您需要一个ICSVRow接口,并且您需要将T约束到实现ICSVRow的对象。这也意味着这对匿名类型不起作用。

任何问题都只是喊出来。