JSON 字符串到 CSV 和 CSV 到 JSON 在 c# 中的转换
JSON string to CSV and CSV to JSON conversion in c#
我正在我的 asp.net 网络 API 项目中使用 JSON/CSV 文件并尝试使用 CSVHelper and ServiceStack.Text 库但无法正常工作。
包含数组的JSON文件是动态的,可以有任意数量的字段
我使用 streamreader 读取文件,然后需要将其转换为 CSV 文件以供最终用户下载。
示例文件文本
[{"COLUMN1":"a","COLUMN2":"b","COLUMN3":"c","COLUMN4":"d","COLUMN5":"e"},
{"COLUMN1":"a","COLUMN2":"b","COLUMN3":"c","COLUMN4":"d","COLUMN5":"e"}]
JSON 到 CSV
public static string jsonStringToCSV(string content)
{
var jsonContent = (JArray)JsonConvert.DeserializeObject(content);
var csv = ServiceStack.Text.CsvSerializer.SerializeToCsv(jsonContent);
return csv;
}
这不会生成 CSV 数据
然后一些文件是带逗号或制表符的分隔符类型,我想利用 CSVHelper 将 CSV 字符串动态转换为 IEnumerable
public static IEnumerable StringToList(string data, string delimiter, bool HasHeader)
{
using (var csv = new CsvReader(new StringReader(data)))
{
csv.Configuration.SkipEmptyRecords = true;
csv.Configuration.HasHeaderRecord = HasHeader;
csv.Configuration.Delimiter = delimiter;
var records = csv.GetRecords();
return records;
}
}
我能够使用 Json.net 通过 DeserializeObject 将其解决到数据表,所以想 post 我自己的答案但不会将其标记为已接受,如果有人有更好的方法来做到这一点.
将JSON字符串转换为DataTable
public static DataTable jsonStringToTable(string jsonContent)
{
DataTable dt = JsonConvert.DeserializeObject<DataTable>(jsonContent);
return dt;
}
制作CSV字符串
public static string jsonToCSV(string jsonContent, string delimiter)
{
StringWriter csvString = new StringWriter();
using (var csv = new CsvWriter(csvString))
{
csv.Configuration.SkipEmptyRecords = true;
csv.Configuration.WillThrowOnMissingField = false;
csv.Configuration.Delimiter = delimiter;
using (var dt = jsonStringToTable(jsonContent))
{
foreach (DataColumn column in dt.Columns)
{
csv.WriteField(column.ColumnName);
}
csv.NextRecord();
foreach (DataRow row in dt.Rows)
{
for (var i = 0; i < dt.Columns.Count; i++)
{
csv.WriteField(row[i]);
}
csv.NextRecord();
}
}
}
return csvString.ToString();
}
Web 中的最终用法 API
string csv = jsonToCSV(content, ",");
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StringContent(csv);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "export.csv" };
return result;
public void Convert2Json()
{
try
{
if (FileUpload1.PostedFile.FileName != string.Empty)
{
string[] FileExt = FileUpload1.FileName.Split('.');
string FileEx = FileExt[FileExt.Length - 1];
if (FileEx.ToLower() == "csv")
{
string SourcePath = Server.MapPath("Resources//" + FileUpload1.FileName);
FileUpload1.SaveAs(SourcePath);
string Destpath = (Server.MapPath("Resources//" + FileExt[0] + ".json"));
StreamWriter sw = new StreamWriter(Destpath);
var csv = new List<string[]>();
var lines = System.IO.File.ReadAllLines(SourcePath);
foreach (string line in lines)
csv.Add(line.Split(','));
string json = new
System.Web.Script.Serialization.JavaScriptSerializer().Serialize(csv);
sw.Write(json);
sw.Close();
TextBox1.Text = Destpath;
MessageBox.Show("File is converted to json.");
}
else
{
MessageBox.Show("Invalid File");
}
}
else
{
MessageBox.Show("File Not Found.");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
我不知道现在报告您问题的解决方案是否为时已晚。以防万一,如果您想探索开源库来完成这项工作,这里有一个
Cinchoo ETL 只需几行代码即可轻松将 JSON 转换为 csv
using (var r = new ChoJSONReader("sample.json"))
{
using (var w = new ChoCSVWriter("sample.csv").WithFirstLineHeader())
{
w.Write(r);
}
}
有关更多信息/来源,请转至 https://github.com/Cinchoo/ChoETL
Nuget 包:
.NET 框架:
Install-Package ChoETL.JSON
.NET 核心:
Install-Package ChoETL.JSON.NETStandard
示例 fiddle:https://dotnetfiddle.net/T3u4W2
完全披露:我是这个库的作者。
最近遇到了同样的问题,我相信使用 System.Dynamic.ExpandoObject and CsvHelper 有更优雅的解决方案。它的代码更少,并且希望性能与 DataTable 相比相似或更好。
public static string JsonToCsv(string jsonContent, string delimiter)
{
var expandos = JsonConvert.DeserializeObject<ExpandoObject[]>(jsonContent);
using (var writer = new StringWriter())
{
using (var csv = new CsvWriter(writer))
{
csv.Configuration.Delimiter = delimiter;
csv.WriteRecords(expandos as IEnumerable<dynamic>);
}
return writer.ToString();
}
}
using System.Globalization;
using (var csv = new CsvWriter(csvString, CultureInfo.CurrentCulture)) {
...
}
这个代码对我来说没问题:
3 个功能(检查、解析和辅助)
private bool IsValidJson(string strInput)
{
try
{
if (string.IsNullOrWhiteSpace(strInput)) { return false; }
strInput = strInput.Trim();
if ((strInput.StartsWith("{") && strInput.EndsWith("}")) || (strInput.StartsWith("[") && strInput.EndsWith("]")))
{
try
{
_ = JToken.Parse(strInput);
return true;
}
catch
{
return false;
}
}
return false;
}
catch { throw; }
}
private string ParseJsonToCsv(string json)
{
try
{
XmlNode xml = JsonConvert.DeserializeXmlNode("{records:{record:" + json + "}}");
XmlDocument xmldoc = new XmlDocument(); xmldoc.LoadXml(xml.InnerXml);
DataSet dataSet = new DataSet(); dataSet.ReadXml(new XmlNodeReader(xmldoc));
string csv = DTableToCsv(dataSet.Tables[0], ",");
return csv;
}
catch { throw; }
}
private string DTableToCsv(DataTable table, string delimator)
{
try
{
var result = new StringBuilder();
for (int i = 0; i < table.Columns.Count; i++)
{
result.Append(table.Columns[i].ColumnName);
result.Append(i == table.Columns.Count - 1 ? "\n" : delimator);
}
foreach (DataRow row in table.Rows)
for (int i = 0; i < table.Columns.Count; i++)
{
result.Append(row[i].ToString());
result.Append(i == table.Columns.Count - 1 ? "\n" : delimator);
}
return result.ToString().TrimEnd(new char[] { '\r', '\n' });
}
catch { throw; }
}
我正在我的 asp.net 网络 API 项目中使用 JSON/CSV 文件并尝试使用 CSVHelper and ServiceStack.Text 库但无法正常工作。
包含数组的JSON文件是动态的,可以有任意数量的字段
我使用 streamreader 读取文件,然后需要将其转换为 CSV 文件以供最终用户下载。
示例文件文本
[{"COLUMN1":"a","COLUMN2":"b","COLUMN3":"c","COLUMN4":"d","COLUMN5":"e"},
{"COLUMN1":"a","COLUMN2":"b","COLUMN3":"c","COLUMN4":"d","COLUMN5":"e"}]
JSON 到 CSV
public static string jsonStringToCSV(string content)
{
var jsonContent = (JArray)JsonConvert.DeserializeObject(content);
var csv = ServiceStack.Text.CsvSerializer.SerializeToCsv(jsonContent);
return csv;
}
这不会生成 CSV 数据
然后一些文件是带逗号或制表符的分隔符类型,我想利用 CSVHelper 将 CSV 字符串动态转换为 IEnumerable
public static IEnumerable StringToList(string data, string delimiter, bool HasHeader)
{
using (var csv = new CsvReader(new StringReader(data)))
{
csv.Configuration.SkipEmptyRecords = true;
csv.Configuration.HasHeaderRecord = HasHeader;
csv.Configuration.Delimiter = delimiter;
var records = csv.GetRecords();
return records;
}
}
我能够使用 Json.net 通过 DeserializeObject 将其解决到数据表,所以想 post 我自己的答案但不会将其标记为已接受,如果有人有更好的方法来做到这一点.
将JSON字符串转换为DataTable
public static DataTable jsonStringToTable(string jsonContent)
{
DataTable dt = JsonConvert.DeserializeObject<DataTable>(jsonContent);
return dt;
}
制作CSV字符串
public static string jsonToCSV(string jsonContent, string delimiter)
{
StringWriter csvString = new StringWriter();
using (var csv = new CsvWriter(csvString))
{
csv.Configuration.SkipEmptyRecords = true;
csv.Configuration.WillThrowOnMissingField = false;
csv.Configuration.Delimiter = delimiter;
using (var dt = jsonStringToTable(jsonContent))
{
foreach (DataColumn column in dt.Columns)
{
csv.WriteField(column.ColumnName);
}
csv.NextRecord();
foreach (DataRow row in dt.Rows)
{
for (var i = 0; i < dt.Columns.Count; i++)
{
csv.WriteField(row[i]);
}
csv.NextRecord();
}
}
}
return csvString.ToString();
}
Web 中的最终用法 API
string csv = jsonToCSV(content, ",");
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StringContent(csv);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("text/csv");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = "export.csv" };
return result;
public void Convert2Json()
{
try
{
if (FileUpload1.PostedFile.FileName != string.Empty)
{
string[] FileExt = FileUpload1.FileName.Split('.');
string FileEx = FileExt[FileExt.Length - 1];
if (FileEx.ToLower() == "csv")
{
string SourcePath = Server.MapPath("Resources//" + FileUpload1.FileName);
FileUpload1.SaveAs(SourcePath);
string Destpath = (Server.MapPath("Resources//" + FileExt[0] + ".json"));
StreamWriter sw = new StreamWriter(Destpath);
var csv = new List<string[]>();
var lines = System.IO.File.ReadAllLines(SourcePath);
foreach (string line in lines)
csv.Add(line.Split(','));
string json = new
System.Web.Script.Serialization.JavaScriptSerializer().Serialize(csv);
sw.Write(json);
sw.Close();
TextBox1.Text = Destpath;
MessageBox.Show("File is converted to json.");
}
else
{
MessageBox.Show("Invalid File");
}
}
else
{
MessageBox.Show("File Not Found.");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
我不知道现在报告您问题的解决方案是否为时已晚。以防万一,如果您想探索开源库来完成这项工作,这里有一个
Cinchoo ETL 只需几行代码即可轻松将 JSON 转换为 csv
using (var r = new ChoJSONReader("sample.json"))
{
using (var w = new ChoCSVWriter("sample.csv").WithFirstLineHeader())
{
w.Write(r);
}
}
有关更多信息/来源,请转至 https://github.com/Cinchoo/ChoETL
Nuget 包:
.NET 框架:
Install-Package ChoETL.JSON
.NET 核心:
Install-Package ChoETL.JSON.NETStandard
示例 fiddle:https://dotnetfiddle.net/T3u4W2
完全披露:我是这个库的作者。
最近遇到了同样的问题,我相信使用 System.Dynamic.ExpandoObject and CsvHelper 有更优雅的解决方案。它的代码更少,并且希望性能与 DataTable 相比相似或更好。
public static string JsonToCsv(string jsonContent, string delimiter)
{
var expandos = JsonConvert.DeserializeObject<ExpandoObject[]>(jsonContent);
using (var writer = new StringWriter())
{
using (var csv = new CsvWriter(writer))
{
csv.Configuration.Delimiter = delimiter;
csv.WriteRecords(expandos as IEnumerable<dynamic>);
}
return writer.ToString();
}
}
using System.Globalization;
using (var csv = new CsvWriter(csvString, CultureInfo.CurrentCulture)) {
...
}
这个代码对我来说没问题:
3 个功能(检查、解析和辅助)
private bool IsValidJson(string strInput)
{
try
{
if (string.IsNullOrWhiteSpace(strInput)) { return false; }
strInput = strInput.Trim();
if ((strInput.StartsWith("{") && strInput.EndsWith("}")) || (strInput.StartsWith("[") && strInput.EndsWith("]")))
{
try
{
_ = JToken.Parse(strInput);
return true;
}
catch
{
return false;
}
}
return false;
}
catch { throw; }
}
private string ParseJsonToCsv(string json)
{
try
{
XmlNode xml = JsonConvert.DeserializeXmlNode("{records:{record:" + json + "}}");
XmlDocument xmldoc = new XmlDocument(); xmldoc.LoadXml(xml.InnerXml);
DataSet dataSet = new DataSet(); dataSet.ReadXml(new XmlNodeReader(xmldoc));
string csv = DTableToCsv(dataSet.Tables[0], ",");
return csv;
}
catch { throw; }
}
private string DTableToCsv(DataTable table, string delimator)
{
try
{
var result = new StringBuilder();
for (int i = 0; i < table.Columns.Count; i++)
{
result.Append(table.Columns[i].ColumnName);
result.Append(i == table.Columns.Count - 1 ? "\n" : delimator);
}
foreach (DataRow row in table.Rows)
for (int i = 0; i < table.Columns.Count; i++)
{
result.Append(row[i].ToString());
result.Append(i == table.Columns.Count - 1 ? "\n" : delimator);
}
return result.ToString().TrimEnd(new char[] { '\r', '\n' });
}
catch { throw; }
}