【问题标题】:Writing a CSV file in .net在 .net 中编写 CSV 文件
【发布时间】:2010-12-13 16:03:30
【问题描述】:

我需要将数据集导出为 CSV 文件。

我花了一段时间寻找一组可以遵循的规则,并意识到在编写 CSV 文件时有很多规则和例外。

http://knab.ws/blog/index.php?/archives/3-CSV-file-parser-and-writer-in-C-Part-1.html http://bytes.com/topic/c-sharp/answers/236875-problems-streamwriter-output-csv http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/0073fcbb-adab-40f0-b768-4bba803d3ccd

所以现在用逗号分隔字符串不是一个简单的过程,我已经搜索了一个现有的 CSV 编写器,要么是第 3 方,要么是(希望如此!)包含在 .net 框架中。

编辑:新链接: http://www.thinqlinq.com/Post.aspx/Title/LINQ-to-CSV-using-DynamicObject-and-TextFieldParser

TextFieldParser 是一个 VB 对象(可以从 C# 中引用),它将自动解析 CSV 文件。 :)

我想知道是否有人知道任何方便的 .Net(2.0 -> 3.5 和 4.0)库,可用于生成格式正确的 CSV 文件。

另外,如果有任何生成 CSV 文件的规则集。

有很多关于 CSV 阅读器和解析 CSV 文件的细节,但关于写作的细节却不多(好吧,我知道正好相反:P)。

http://www.codeproject.com/KB/database/CsvReader.aspx

任何帮助将不胜感激:)

我找到了另一篇文章,其中包含一些更详细的 CSV 规则: http://www.creativyst.com/Doc/Articles/CSV/CSV01.htm

一个整洁的第 3 方库是 Linq-to-CSV(不是框架库): http://www.codeproject.com/KB/linq/LINQtoCSV.aspx

感谢大家的帮助。 我决定最好的解决方案是创建一个简单的静态类来进行特殊字符替换(Chris 提到过)。

如果我需要 Linq 查询我的 CSV 文件,我会查看 Linq-to-CSV 的 CodeProjects 实现。

再次感谢:)

【问题讨论】:

  • 我认为,既然你是一个导出者,那么你在写作时可以相当放松,如果你只遵循一般规则,大多数程序(如 Excel)都会弄清楚如何阅读它们。
  • 确实如此。我不幸地编写了一个没有指定潜在用途的“导出”函数。我假设 99% 的时间这将是 excel 或其他应用程序可能(不太可能)的 SSIS 包。不过我只能假设。
  • 你可以试试我的轻量级分隔文件编写器:gist.github.com/eranbetzalel/…

标签: c# .net csv


【解决方案1】:

CsvHelper(我维护的一个库)也可以通过 NuGet 获得。

CsvHelper 可以自动将您的类对象写入文件。

var myObj = new MyCustomClass
{
    Prop1 = "one",
    Prop2 = 2
};
var streamWriter = // Create a writer to somewhere...
var csvWriter = new CsvWriter( streamWriter );

// You can write a single record.
csvWriter.WriteRecord( myObj );

// You can also write a collection of records.
var myRecords = new List<MyCustomClass>{ myObj };
csvWriter.WriteRecords( myRecords );

【讨论】:

  • 顺便说一句,CsvHelper 中添加了一些映射功能,允许您在不使用属性的情况下映射您的类。您可以改用流畅的映射类,它允许您映射到您无法控制的类。
  • 正是我想要的并且喜欢它!谢谢。
【解决方案2】:

如果您的单元格中有逗号,请用双引号将整个单元格括起来,例如:

cell 1,cell 2,"This is one cell, even with a comma",cell4,etc

如果你想要一个文字双引号,做两个,例如:

cell 1,cell 2,"This is my cell and it has ""quotes"" in it",cell 4,etc

至于日期,坚持 ISO 格式,应该没问题(例如 yyyy-mm-dd hh:mm:ss)

【讨论】:

  • 它们本身是唯一的“规则”吗?例如换行符呢。您知道这些规则/要求的任何参考资料吗?我假设(从搜索中)这些文件类型没有标准,只有专有要求(例如,哪些适用于 excel :P )。感谢您的意见。
  • 基本上,我会选择适用于 excel 的任何东西。至于换行符,C#的各种AppendLine和WriteLine函数似乎都是追加\r\n,这似乎与excel一致。
  • 记得用双引号将值括起来。
  • 根据en.wikipedia.org/wiki/Comma-separated_values,如果您需要严格,这个答案对于 CSV 格式要求的现实来说是很简单的。
  • 顺便说一句关于日期:您引用的不是 ISO 格式(ISO 8601 使用 T,而不是日期和时间之间的分隔空间)
【解决方案3】:

我只想添加一个RFC,它指定了我认为是规范来源的 CSV 格式。

【讨论】:

  • 谢谢理查德,这是一个非常详细的信息:)
【解决方案4】:

我已经广泛使用filehelpers,它非常适合生成 CSV。

【讨论】:

  • 谢谢,FileHelpers 看起来是一个非常方便(+ 开源)的库。不幸的是,在这种情况下,我无法将属性添加到我想转换为 CSV 的对象中。使用 .net 反射器,我看不到通过传入值/列表来执行此操作的方法。你知道这是否可能吗?
  • 您可以创建一些新的“仅生成器”类并使用 AutoMapper 将您的真实类映射到生成器类,然后使用 FileHelpers 将这些类写出来。我以前做过,很简单。
  • 文件助手真的做 CSV 吗?当然他们有分隔,但这与带有引用规则的 CSV 不同。
【解决方案5】:

这个函数可以用来从字符串列表生成一行CSV文件(也可以使用IEnumerable(Of String)或者字符串数组):

Function CreateCSVRow(strArray As List(Of String)) As String
    Dim csvCols As New List(Of String)
    Dim csvValue As String
    Dim needQuotes As Boolean
    For i As Integer = 0 To strArray.Count() - 1
        csvValue = strArray(i)
        needQuotes = (csvValue.IndexOf(",", StringComparison.InvariantCulture) >= 0 _
                      OrElse csvValue.IndexOf("""", StringComparison.InvariantCulture) >= 0 _
                      OrElse csvValue.IndexOf(vbCrLf, StringComparison.InvariantCulture) >= 0)
        csvValue = csvValue.Replace("""", """""")
        csvCols.Add(If(needQuotes, """" & csvValue & """", csvValue))
    Next
    Return String.Join(",", csvCols.ToArray())
End Function

我认为,从 VB.NET 转换为 C# 并不难)

【讨论】:

  • 感谢 Evgeny 提供的信息,我相信它对遇到这个问题的人会很有用。 :)
【解决方案6】:
【解决方案7】:

我知道你说你找到了答案,但我只是想为你提到的 LINQtoCSV 库投票。我在几个项目中使用过它,它非常适合保持您的业务代码干净并且不关心文件格式的细节/特性。

也许在您的特定情况下,编写导出器并不太难,但这个库的好处是它是双向的。如果您发现自己不得不在路上使用 CSV,那么这并不需要太多额外的代码,并且/或者它为您提供了一个一致的库,可以在未来的项目中使用。

【讨论】:

  • 谢谢,它看起来确实很方便。项目有不同的要求和优先级,因此不同的解决方案可能更适合不同的项目。谢谢,如果你喜欢,别忘了投票。 :)
【解决方案8】:

您可以使用 ODBC 读取和写入 CSV 文件(通过 OdbcConnection 和合适的连接字符串)。这对于生成 CSV 文件应该是相当不错的,并且会为您处理诸如引用之类的事情;但是我在使用它读取其他程序生成的 CSV 文件时遇到了一些问题。

【讨论】:

  • 谢谢,这个方法有入门参考吗?
  • 如果你用谷歌搜索“odbc csv 文件”,它会抛出很多链接。最上面的是c-sharpcorner.com/UploadFile/mahesh/…——请注意,您需要向下滚动才能找到 C# 代码!
【解决方案9】:

要添加到其他规则的另一条规则:使用逗号作为字段分隔符而不是字段终止符。这样做的原因是行尾的尾随逗号可能不明确:它没有意义还是表示它后面的 NULL 值?

【讨论】:

  • 非常好。最好有一个“行尾”分隔符而不是假设一个换行符。例如不同的操作系统使用不同的字符!
  • CSV 格式指定 CRLF ("\r\n") 作为每一行的终止符。
【解决方案10】:

我发现这个重要的链接非常简洁。还没试过,会告诉你结果如何!

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

仔细观察,这个实现本质上也只使用了基本规则:

特殊字符 = \n \" 和分隔符。

如果发现特殊字符,则用引号括起来。 用双引号替换引号。

基本上就是克里斯提到的规则。 我认为最简单的方法是根据简单的规则创建我的辅助方法并根据用户需求进行修改。

【讨论】:

    【解决方案11】:

    你可以使用一个字符串数组,然后使用连接:

    string out = "";
    string[] elements = { "1", "2" };
    foreach(string s in elements) { out += s + "," };
    out = out.substring(0, out.Length-1);
    

    【讨论】:

    • 可以将上面的代码替换成String.Join(",", "1", "2", "etc...");
    猜你喜欢
    • 2011-06-27
    • 2019-04-07
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 2012-06-23
    • 1970-01-01
    相关资源
    最近更新 更多