Строка JSON в CSV и преобразование CSV в JSON в c #

Я работаю с файлами JSON / CSV в своем проекте веб-API asp.net и пробовал использовать CSVHelper и < библиотеки href = "https://github.com/ServiceStack/ServiceStack.Text" rel = "noreferrer"> 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;
     }
}

person Priyanka Rathee    schedule 29.03.2016    source источник
comment
Не могли бы вы предоставить нам указанную ошибку или результат?   -  person Eminem    schedule 29.03.2016
comment
@Eminem См. Скриншот Excel.   -  person Priyanka Rathee    schedule 29.03.2016
comment
Я прошу дать результат. Не то, что вы ожидаете от него   -  person Eminem    schedule 29.03.2016
comment
Да то же самое, скриншот - это то, что он дает не так, как я ожидал.   -  person Priyanka Rathee    schedule 29.03.2016
comment
Виноват. Я думал, что это настоящие значения   -  person Eminem    schedule 29.03.2016
comment
Может показаться, что он выводит свойства типа? Можете ли вы подтвердить, что ваш контент проходит правильно?   -  person Eminem    schedule 29.03.2016
comment
Да, подтверждаю. Я проверил в режиме отладки и распечатал json на консоли как строку, которая выглядит хорошо   -  person Priyanka Rathee    schedule 29.03.2016
comment
Смотрите мой ответ на другой похожий вопрос. Единственная разница в том, что OP конвертировал DataTable в JSON вместо CSV. stackoverflow.com/questions/36272054/   -  person Saleem    schedule 29.03.2016
comment
Я хочу использовать библиотеку csvhelper или ServiceStack.Text вместо того, чтобы писать много кода, потому что CSV сложен, а одна неуместная запятая и т. Д. Может сломать код   -  person Priyanka Rathee    schedule 29.03.2016
comment
Вы имеете в виду динамическое количество столбцов в вашем объекте или динамическое количество элементов в массиве?   -  person drneel    schedule 31.03.2016
comment
Поскольку вы, кажется, используете Excel, рассматривали ли вы встроенную функцию преобразования данных? Ознакомьтесь с подробностями в руководстве по YouTube. Вы можете импортировать и преобразовывать данные JSON в Excel, а затем сохранять их как CSV.   -  person Matt    schedule 08.01.2020


Ответы (6)


Мне удалось решить эту проблему с помощью 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();
        }

Окончательное использование в веб-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;
person Priyanka Rathee    schedule 01.04.2016
comment
Именно то, что я пытался достичь. Работает отлично! - person Cosmin Cretu; 18.10.2016
comment
Отлично работает? Мой jsonStringToTable разбился из-за форматирования в newtonsoft. - person stian; 19.03.2018
comment
Когда я ищу в библиотеке NuGet для Json.NET, я возвращаю Newtonsoft.Json в окне результатов. Я думаю, это то же самое. Он уже установлен в моем проекте, но кажется, что CsvWriter отсутствует. В проекте используется .NET v4.6.2. Есть идеи, как заставить его работать? - person Victor_Tlepshev; 26.12.2018
comment
CsvWriter доступен в другом пакете под названием CsvHelper - github.com/JoshClose/CsvHelper вы можете установить ›Install- Пакет CsvHelper - person Priyanka Rathee; 02.01.2019
comment
что вы делаете, когда у вас есть объект Json в качестве поля? десериализация в DataTable вызовет ошибку - person Avi Meltser; 30.03.2021

Я не знаю, слишком ли поздно сообщать о решении вашего вопроса. На всякий случай, если вы хотите изучить библиотеку с открытым исходным кодом, чтобы выполнить эту работу, вот один

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

Полное раскрытие информации: я являюсь автором этой библиотеки.

person Cinchoo    schedule 03.07.2017
comment
понял. К вашему сведению, это библиотека с открытым исходным кодом, показывающая, как решить проблему с ее помощью. Не более того. - person Cinchoo; 03.07.2017
comment
Я понимаю. Я просто говорю, как это воспринимается сообществом. Просто укажите свое отношение к библиотеке, и все будет в порядке. - person Nkosi; 03.07.2017
comment
Я установил ваш Install-Package ChoETL, а затем попытался добавить его пространство имен. Но система выдает ошибку отсутствует ссылка. Раствор тоже чистил, но напрасно. Не могли бы вы помочь !! @RajN - person Arsman Ahmad; 29.05.2018
comment
Это ваш проект .net framework или .net core? Если ядро ​​.net использует пакет ChoETL.JSON.NETStandard. Если платформа .net, используйте ChoETL.JSON - person Cinchoo; 29.05.2018
comment
Метод получения @RajN не найден: 'Void ChoETL.ChoRecordReader..ctor (System.Type, Boolean)'. об использовании вашего пакета. - person pso; 11.01.2019
comment
Обнаружил несовместимые зависимости в пакете. Поправил, запихнул новую версию 1.0.9. - person Cinchoo; 11.01.2019
comment
Эта библиотека великолепна. Он распаковывает даже вложенные уровни json в csv, собирая все данные. - person user890332; 18.11.2019

Недавно была такая же проблема, и я считаю, что есть немного более элегантное решение с использованием 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();
        }
    }
person Slobodan Savkovic    schedule 20.09.2019
comment
Я нашел это решение лучшим из всех. :-) - person Varun Nair; 17.03.2021

string path = ""; // YOU .JSON PATH HERE
using (var r = new ChoJSONReader(path))
{
    using (var w = new ChoCSVWriter("csv_file_name_here.csv").WithFirstLineHeader())
    {
        w.Write(r);
    }
}

Просто установите этот пакет 'ChoETL.JSON'

Тогда тебе должно быть хорошо. Хорошего дня!

person Supreme Gang Certified Member    schedule 25.11.2020

Этот код мне подходит:

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; }
    }
person Ángel Ibáñez    schedule 03.03.2021

person    schedule
comment
Вы используете line.Split (','), что не очень хорошая идея. Лучше использовать csv-ридер. - person user890332; 18.11.2019