#c# #json #csv #asp.net-core #asp.net-web-api
Вопрос:
Я работаю с файлами JSON / CSV в моем asp.net проект веб-API и попробовал с помощью CSVHelper и ServiceStack.Текстовые библиотеки, но не смог заставить их работать.
Файл 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;
}
}
Комментарии:
1. Не могли бы вы предоставить нам, пожалуйста, сообщение об ошибке или вывод
2. @Eminem Пожалуйста, посмотрите скриншот excel.
3. Я запрашиваю вывод, который он ДАЕТ. Не то, что вы ожидаете от этого
4. Да, то же самое, скриншот показывает, что он дает не так, как я ожидал.
5. Mybad. Я думал, что это фактические значения
Ответ №1:
Я смог решить эту проблему путем десериализации объекта в datatable с помощью 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();
}
Окончательное использование в веб-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 resu<
Комментарии:
1. Именно то, чего я пытался достичь. Отлично работает!
2. Отлично ли это работает? Мой jsonStringToTable разбился из-за форматирования в newtonsoft.
3. Когда я ищу в библиотеке NuGet Json. NET Я возвращаю Newtonsoft. Json в окне результатов. Я думаю, это то же самое. Он уже установлен в моем проекте, но CSVWriter, похоже, отсутствует. Проект использует . NET v4.6.2 Есть идеи, как заставить его работать?
4. CSVWriter доступен в другом пакете под названием CSVHelper — github.com/JoshClose/CsvHelper вы можете установить > Установить-Пакет CSVHelper
5. что вы делаете, когда у вас есть объект Json в качестве поля? Десериализация в DataTable выдаст ошибку
Ответ №2:
Я не знаю, не слишком ли поздно сообщать о решении вашего вопроса. На всякий случай, если вы хотите изучить библиотеку с открытым исходным кодом для выполнения этой работы, вот один
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
Пример скрипки: https://dotnetfiddle.net/T3u4W2
Полное раскрытие: я автор этой библиотеки.
Комментарии:
1. понятно. К вашему сведению, это библиотека с открытым исходным кодом, показывающая, как решить проблему с ее помощью. Не более того.
2. Я понимаю. Я просто говорю, как это воспринимается сообществом. Просто укажите ваше отношение к библиотеке, и все должно быть в порядке.
3. Я установил ваш
Install-Package ChoETL
, а затем пытаюсь добавить его пространство имен. Но система выдает мне ошибку отсутствия ссылки . Я также очистил решение, но все напрасно. Не могли бы вы помочь!! @RajN4. Ваш проект .net framework или .net core? Если .net core использует стандартный пакет ChoETL.JSON.net. Если .net framework, используйте ChoETL.JSON
5. Эта библиотека превосходна. Он распутывает даже вложенные уровни json в csv, захватывая все данные.
Ответ №3:
Недавно была такая же проблема, и я считаю, что есть немного более элегантное решение с использованием системы.Dynamic.ExpandoObject и CSVHelper. Это меньше кода, и, надеюсь, производительность аналогична или лучше по сравнению с таблицей данных.
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();
}
}
Комментарии:
1. Я нашел это решение лучшим из всех. 🙂
2. Не удается заставить это работать, если в некоторых записях отсутствуют некоторые значения
Ответ №4:
Этот код подходит для меня:
3 функции (проверка, анализ и aux)
private bool IsValidJson(string strInput)
{
try
{
if (string.IsNullOrWhiteSpace(strInput)) { return false; }
strInput = strInput.Trim();
if ((strInput.StartsWith("{") amp;amp; strInput.EndsWith("}")) || (strInput.StartsWith("[") amp;amp; 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; }
}
Ответ №5:
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);
}
}
Комментарии:
1. Вы используете строку. Разделение (‘,’), что не очень хорошая идея. Лучше использовать программу чтения csv.
Ответ №6:
using System.Globalization;
using (var csv = new CsvWriter(csvString, CultureInfo.CurrentCulture)) {
...
}