c#中的JSON到CSV和CSV到JSON
本文关键字:CSV JSON 中的 | 更新日期: 2023-09-27 18:17:12
我一直在寻找一种方法将json文件转换为csv,反之亦然使用c#。我在谷歌上搜索了一下,什么也没找到。到目前为止,我所尝试的一切都不是关于堆栈溢出的答案,只是对我不起作用。有人知道任何工具或教程,我可以看看如何完成这个与。net框架?通常我会张贴我尝试过的东西,但我显然离这里很远,所以毫无意义。
妥协与问题
你可以在。net框架中完成这一点,但是由于层次结构和集合,没有一个清晰明显的方法来直接完成这一点。我的意思是,CSV数据非常扁平且非结构化,而JSON数据非常有组织且迭代。让我们来看一个简单的JSON数据块,它看起来像这样:
{
"Data": [
{
"Name":"Mickey Mouse",
"Friends":[ "Pluto", "Minnie", "Donald" ]
},
{
"Name":"Pluto",
"Friends":[ "Mickey" ]
}
]
}
最明显的CSV文件可能是:
Name,Friend
Mickey Mouse,Pluto
Mickey Mouse,Minnie
Mickey Mouse,Donald
Pluto,Mickey
这是更简单的转换但假设你只有那个CSV文件。JSON应该是什么样子并不是很明显。有人可能会说JSON应该是这样的:
{
"Data": [
{ "Name":"Mickey Mouse", "Friend":"Pluto" },
{ "Name":"Mickey Mouse", "Friend":"Minnie" },
{ "Name":"Mickey Mouse", "Friend":"Donald" },
{ "Name":"Pluto", "Friend":"Mickey" },
]
}
生成的JSON文件与输入的JSON文件非常不同。我的观点是,这不是一个简单/明显的转换,所以任何现成的或复制/粘贴的解决方案都是不完美的。无论你的解决方案是什么,你都必须做出妥协或明智的决定。
。. NET框架选项
现在我们已经解决了这个问题,. net为您提供了一些开箱即用的功能,并且还提供了一些很好的nuget选项。如果你想利用纯粹的。net功能,你可以使用以下两个SO的组合:
- 不完美,但这个答案有一些很棒的代码,可以让你开始在逻辑中生成CSV文件
- 这个问题和由此产生的答案提供了一些关于仅使用。net框架而不使用任何第三方实用程序生成JSON的好信息。
你应该能够应用这两个链接中的概念,加上我在这篇文章的第一个"妥协和问题"部分中需要做出的妥协和明智的决定来完成你需要的。
我以前做过的事
我已经做了类似的事情,我实际上使用了Microsoft.VisualBasic.FileIO
命名空间中的一些功能(在c#应用程序中工作得很好),除了Web API的序列化功能外,还使用动态对象(使用动态关键字)作为中介来完成CSV->JSON转换。代码如下所示。它不是非常强大,并且做出了一些重大的妥协,但它对我来说工作得很好。如果您想尝试这样做,您必须创建自己的反向版本,但正如我在第一节中提到的,这确实是最简单的部分。
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Web.Http;
// NOTE: This is not purely my code. This was put together
// with the help of other SO questions that I wish I had the
// links to so I could credit them. You probably will find
// some chunk(s) of this code elsewhere on SO.
namespace Application1.Controllers
{
public class Foo
{
public string Csv { get; set; }
}
public class JsonController : ApiController
{
[HttpPost]
[Route("~/Csv/ToJson")]
public dynamic[] ConvertCsv([FromBody] Foo input)
{
var data = CsvToDynamicData(input.Csv);
return data.ToArray();
}
internal static List<dynamic> CsvToDynamicData(string csv)
{
var headers = new List<string>();
var dataRows = new List<dynamic>();
using (TextReader reader = new StringReader(csv))
{
using (var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(reader))
{
parser.Delimiters = new[] {","};
parser.HasFieldsEnclosedInQuotes = true;
parser.TrimWhiteSpace = true;
var rowIdx = 0;
while (!parser.EndOfData)
{
var colIdx = 0;
dynamic rowData = new ExpandoObject();
var rowDataAsDictionary = (IDictionary<string, object>) rowData;
foreach (var field in parser.ReadFields().AsEnumerable())
{
if (rowIdx == 0)
{
// header
headers.Add(field.Replace("''", "_").Replace("/", "_").Replace(",", "_"));
}
else
{
if (field == "null" || field == "NULL")
{
rowDataAsDictionary.Add(headers[colIdx], null);
}
else
{
rowDataAsDictionary.Add(headers[colIdx], field);
}
}
colIdx++;
}
if (rowDataAsDictionary.Keys.Any())
{
dataRows.Add(rowData);
}
rowIdx++;
}
}
}
return dataRows;
}
}
}
如果你想要更健壮的东西,那么你总是可以利用这些伟大的项目:
- JSON。它可以很好地从动态对象创建JSON。考虑到您不使用Web API,这将是第一个地方,我将寻找采取
dynamic[]
返回值并将其转换为JSON。 - CsvHelper
除了使用多个库的组合来完成JSON和CSV之间的转换之外,Cinchoo ETL还提供了统一的接口来完成这两种格式之间的转换。
示例JSON文件:
[
{
"Name" : "Xytrex Co.",
"Description" : "Industrial Cleaning Supply Company",
"AccountNumber" : "ABC15797531"
},
{
"Name" : "Watson and Powell, Inc.",
"Description" : "Law firm. New York Headquarters",
"AccountNumber" : "ABC24689753"
}
]
生成CSV文件:
Name,Description,AccountNumber
Xytrex Co.,Industrial Cleaning Supply Company,ABC15797531
Watson and Powell Inc.,Law firm. New York Headquarters,ABC24689753
JSON到CSV:
using (var p = ChoJSONReader.LoadText(json))
{
using (var w = new ChoCSVWriter(Console.Out)
.WithFirstLineHeader()
)
{
w.Write(p);
}
}
样本小提琴: https://dotnetfiddle.net/T3u4W2
CSV to JSON:
using (var p = ChoCSVReader.LoadText(csv)
.WithFirstLineHeader()
)
{
using (var w = new ChoJSONWriter(Console.Out))
{
w.Write(p);
}
}
样本小提琴: https://dotnetfiddle.net/gVlJVX
就像jasxidian提到的,问题是json可以有层次结构,而csv没有。
所以,我可以给你两个建议:
-
创建一个分层csv,不应该是太多的努力:
"Id";"Name";"Age";"Type" "FriendId" 1;"Mickey Mouse";20;"mouse" 2 3 4 2;"Pluto";7;"dog" 1 3;"Minnie";20;"mouse" 4;"Donald";22;"duck"
-
创建多个文件,可能会更费力,但更美观,更动态,当你使用。从数据库导出/导入。也许这个链接可以帮助你:http://www.snellman.net/blog/archive/2016-01-12-json-to-multicsv
-
all.csv(存储所有字符)
"Id";"Name";"Age";"Type" 1;"Mickey Mouse";20;"mouse" 2;"Pluto";7;"dog" 3;"Minnie";20;"mouse" 4;"Donald";22;"duck"
-
friends.csv(存储所有关系)
"FriendKey1";"FriendKey2" 1;2 2;1 1;3 1;4
-