Asp.net Web APIプロジェクトでJSON/CSVファイルを使用しており、 CSVHelper および 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データをもたらさない
次に、いくつかのファイルはカンマまたはタブを使用した区切り文字タイプであり、CSV文字列をIEnumerableに動的に変換するために CSVHelper を利用したい
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;
}
}
DeserializeObjectでJson.netを使用してデータテーブルに解決できたので、自分で答えを投稿したいが、これを行うより良い方法があれば、承認済みとしてマークしません。
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;
あなたの質問に対する解決策を報告するには遅すぎるかどうかはわかりません。あなたが仕事をするためにオープンソースライブラリを探索したい場合に備えて、ここに1つがあります
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 Framework:
Install-Package ChoETL.JSON
。NET Core:
Install-Package ChoETL.JSON.NETStandard
完全な開示:私はこのライブラリの著者です。
最近同じ問題があり、 System.Dynamic.ExpandoObject および 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();
}
}
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);
}
}