Conversión de cadena JSON a CSV y CSV a JSON en c#
csvhelper (4)
Estoy trabajando con archivos JSON / CSV en mi proyecto de API web asp.net y probé con las bibliotecas CSVHelper y ServiceStack.Text , pero no pude hacerlo funcionar.
El archivo JSON que contiene una matriz es dinámico y puede tener cualquier número de campos.
Leí el archivo usando streamreader y luego necesito convertirlo en un archivo CSV para que sea descargable para los usuarios finales.
texto de archivo de ejemplo
[{"COLUMN1":"a","COLUMN2":"b","COLUMN3":"c","COLUMN4":"d","COLUMN5":"e"},
{"COLUMN1":"a","COLUMN2":"b","COLUMN3":"c","COLUMN4":"d","COLUMN5":"e"}]
JSON a CSV
public static string jsonStringToCSV(string content)
{
var jsonContent = (JArray)JsonConvert.DeserializeObject(content);
var csv = ServiceStack.Text.CsvSerializer.SerializeToCsv(jsonContent);
return csv;
}
Esto no me da datos CSV
Luego, algunos archivos son delimitadores con coma o tabulación y quiero utilizar CSVHelper para convertir la cadena CSV a IEnumerable dinámicamente
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;
}
}
No sé si es demasiado tarde para informar una solución a su pregunta. En caso de que si desea explorar la biblioteca de código abierto para hacer el trabajo, aquí hay uno
Cinchoo ETL facilita la conversión de JSON a csv con pocas líneas de código
using (var r = new ChoJSONReader("sample.json"))
{
using (var w = new ChoCSVWriter("sample.csv").WithFirstLineHeader())
{
w.Write(r);
}
}
Para obtener más información / fuente, vaya a https://github.com/Cinchoo/ChoETL
Paquete Nuget:
.NET Framework:
Install-Package ChoETL.JSON
.NET Core:
Install-Package ChoETL.JSON.NETStandard
Divulgación completa: soy el autor de esta biblioteca.
Pude resolverlo mediante DeserializeObject en una tabla de datos usando Json.net, así que quiero publicar mi propia respuesta pero no la marcaré como aceptada, si alguien tiene una mejor manera de hacerlo.
Para convertir una cadena JSON a DataTable
public static DataTable jsonStringToTable(string jsonContent)
{
DataTable dt = JsonConvert.DeserializeObject<DataTable>(jsonContent);
return dt;
}
Para hacer una cadena 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();
}
Uso final en API web
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;
Tuve el mismo problema recientemente y creo que hay una solución un poco más elegante usando System.Dynamic.ExpandoObject y CsvHelper . Es menos código y es de esperar que el rendimiento sea similar o mejor en comparación con el 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);
}
}