Ich arbeite mit JSON/CSV-Dateien in meinem asp.net-Web-API-Projekt und habe es mit CSVHelper und ServiceStack.Text -Bibliotheken versucht, es konnte jedoch nicht funktionieren.
Die JSON-Datei, die ein Array enthält, ist dynamisch und kann eine beliebige Anzahl von Feldern aufweisen
Ich lese die Datei mit Streamreader und muss sie dann in eine CSV-Datei konvertieren, damit sie für Endbenutzer heruntergeladen werden kann.
Beispieltext
[{"COLUMN1":"a","COLUMN2":"b","COLUMN3":"c","COLUMN4":"d","COLUMN5":"e"},
{"COLUMN1":"a","COLUMN2":"b","COLUMN3":"c","COLUMN4":"d","COLUMN5":"e"}]
JSON zu CSV
public static string jsonStringToCSV(string content)
{
var jsonContent = (JArray)JsonConvert.DeserializeObject(content);
var csv = ServiceStack.Text.CsvSerializer.SerializeToCsv(jsonContent);
return csv;
}
Dies führt nicht zu CSV-Daten
Dann sind einige Dateien als Trennzeichen mit Komma oder Tabulator und ich möchte CSVHelper verwenden, um den CSV-String dynamisch in IEnumerable zu konvertieren
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;
}
}
Ich konnte es von DeserializeObject mit Json.net in eine datierbare Datenbank umwandeln. Daher möchte ich meine eigene Antwort posten, aber nicht als akzeptabel markieren, wenn jemand eine bessere Möglichkeit hat, dies zu tun.
So konvertieren Sie den JSON-String in DataTable
public static DataTable jsonStringToTable(string jsonContent)
{
DataTable dt = JsonConvert.DeserializeObject<DataTable>(jsonContent);
return dt;
}
So erstellen Sie eine CSV-Zeichenfolge
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();
}
Endgültige Verwendung in 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;
Ich weiß nicht, ob dies zu spät ist, um eine Lösung für Ihre Frage zu melden. Für den Fall, dass Sie die Open Source-Bibliothek erkunden möchten, um die Arbeit zu erledigen, finden Sie hier eine
Cinchoo ETL vereinfacht die Konvertierung von JSON in CSV mit wenigen Codezeilen
using (var r = new ChoJSONReader("sample.json"))
{
using (var w = new ChoCSVWriter("sample.csv").WithFirstLineHeader())
{
w.Write(r);
}
}
Weitere Informationen/Quellen finden Sie unter https://github.com/Cinchoo/ChoETL
Nuget-Paket:
.NET Framework:
Install-Package ChoETL.JSON
.NET Core:
Install-Package ChoETL.JSON.NETStandard
Full Disclosure: Ich bin der Autor dieser Bibliothek.
Hatte das gleiche Problem in letzter Zeit und ich glaube, es gibt eine etwas elegantere Lösung mit System.Dynamic.ExpandoObject und CsvHelper . Es ist weniger Code und hoffentlich ist die Leistung ähnlich oder besser als die von 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);
}
}