Вопрос по json, c# – Преобразование CSV-файла в JSON с помощью C #

20

Мне было интересно, если кто-то написал утилиту для преобразования файла CSV в Json с использованием C #. Из предыдущего вопроса о stackoverflow я знаю об этой хорошей утилите -https://github.com/cparker15/csv-to-json и на данный момент я планирую обратиться к нему, но существующая реализация C # будет очень полезна! Спасибо!

Да, это то, что я планировал сделать, но единственная статья, которую я смог найти, эта на msdn Social.msdn.microsoft.com / Форумы / EN-US / VSTO / резьба / ... использует Office.Interop, и я новичок в C # и не очень знаком с ним. Нужно ли мне его использовать или стоит попытаться перевести утилиту js? Благодарность user1427026
Вы можете легко транслитерировать этот JS-код на C #, вы можете оставить его вvar ключевые слова тоже. tlehman
Я бы не использовал Office.Interop для файла CSV, это было бы излишним, поскольку CSV - это просто текст. tlehman

Ваш Ответ

10   ответов
16

Если ты можешь использоватьSystem.Web.Extensions, что-то вроде этого может сработать:

var csv = new List<string[]>(); // or, List<YourClass>
var lines = System.IO.File.ReadAllLines(@"C:\file.txt");
foreach (string line in lines)
    csv.Add(line.Split(',')); // or, populate YourClass          
string json = new 
    System.Web.Script.Serialization.JavaScriptSerializer().Serialize(csv);

У вас могут быть более сложные требования к разбору файла csv, и у вас может быть класс, который инкапсулирует данные из одной строки, но дело в том, что вы можете сериализовать в JSON одну строку кода, как только у вас будет коллекция строк.

В большинстве случаев это приводит к ошибке, если файл огромен. Пример: ошибка во время сериализации или десериализации с использованием JSON JavaScriptSerializer. Длина строки превышает значение, установленное в свойстве maxJsonLength Kurkula
5

Cinchoo ETL - библиотека с открытым исходным кодом, позволяющая легко конвертировать CSV в JSON с помощью нескольких строк кода

Для образца CSV:

Id, Name, City
1, Tom, NY
2, Mark, NJ
3, Lou, FL
4, Smith, PA
5, Raj, DC

Образец кода

string csv = @"Id, Name, City
1, Tom, NY
2, Mark, NJ
3, Lou, FL
4, Smith, PA
5, Raj, DC
";

StringBuilder sb = new StringBuilder();
using (var p = ChoCSVReader.LoadText(csv)
    .WithFirstLineHeader()
    )
{
    using (var w = new ChoJSONWriter(sb))
        w.Write(p);
}

Console.WriteLine(sb.ToString());

Выход JSON:

[
 {
  "Id": "1",
  "Name": "Tom",
  "City": "NY"
 },
 {
  "Id": "2",
  "Name": "Mark",
  "City": "NJ"
 },
 {
  "Id": "3",
  "Name": "Lou",
  "City": "FL"
 },
 {
  "Id": "4",
  "Name": "Smith",
  "City": "PA"
 },
 {
  "Id": "5",
  "Name": "Raj",
  "City": "DC"
 }
]

Закажите статью CodeProject для получения дополнительной помощи.

Отказ от ответственности: я автор этой библиотеки.

Спасибо за написание этой библиотеки @ RajN vibs2006
hi, я попробовал твой код, я установил choetl, но мой код обнаружил ошибку в "ChoJSONWriter" .. "не удалось найти, ты пропустил директиву using или сборку". Не могли бы вы сказать мне, как его использовать? что я пропустил Raspi Surya
установить библиотеку расширений JSON (ChoETL.JSON). Исправил ссылку в SO ответе. RajN
Используйте конструкторы ChoCSVReader / ChoJSONReader. RajN
этот подход использует динамическую модель.foreach (dynamic e in new ChoCSVReader(csv).WithFirstLineHeader()) { System.Diagnostics.Debug.Write(e.CSVColumnName); }. Для получения дополнительной информации посетите статью CodeProject / GitHub wiki. RajN
4
Install Nuget package NewtonSoft.Json
Add reference dll Microsoft.VisualBasic

using System.Linq;
using Newtonsoft.Json;
using Microsoft.VisualBasic.FileIO;
using System.IO;
using System;
using System.Collections.Generic;
using System.Globalization;

namespace Project
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            string CSVpath = @"D:\New Folder\information.csv";
            string analyticsData = ReadFile(CSVpath);
        }

        private static string ReadFile(string filePath)
        {
            string payload = "";
            try
            {
                if (!string.IsNullOrWhiteSpace(filePath) && File.Exists(filePath) && Path.GetExtension(filePath).Equals(".csv", StringComparison.InvariantCultureIgnoreCase))
                {
                    string[] lines = File.ReadAllLines(filePath);

                    if (lines != null && lines.Length > 1)
                    {
                        var headers = GetH,eaders(lines.First());
                        payload = GetPayload(headers, lines.Skip(1));
                    }
                }
            }
            catch (Exception exp)
            {
            }
            return payload;
        }

        private static IEnumerable<string> GetHeaders(string data)
        {
            IEnumerable<string> headers = null;

            if (!string.IsNullOrWhiteSpace(data) && data.Contains(','))
            {
                headers = GetFields(data).Select(x => x.Replace(" ", ""));
            }
            return headers;
        }

        private static string GetPayload(IEnumerable<string> headers, IEnumerable<string> fields)
        {
            string jsonObject = "";
            try
            {
                var dictionaryList = fields.Select(x => GetField(headers, x));
                jsonObject = JsonConvert.SerializeObject(dictionaryList);
            }
            catch (Exception ex)
            {
            }
            return jsonObject;
        }

        private static Dictionary<string, string> GetField(IEnumerable<string> headers, string fields)
        {
            Dictionary<string, string> dictionary = null;

            if (!string.IsNullOrWhiteSpace(fields))
            {
                var columns = GetFields(fields);

                if (columns != null && headers != null && columns.Count() == headers.Count())
                {
                    dictionary = headers.Zip(columns, (x, y) => new { x, y }).ToDictionary(item => item.x, item => item.y);
                }
            }
            return dictionary;
        }

        public static IEnumerable<string> GetFields(string line)
        {
            IEnumerable<string> fields = null;
            using (TextReader reader = new StringReader(line))
            {
                using (TextFieldParser parser = new TextFieldParser(reader))
                {
                    parser.TextFieldType = FieldType.Delimited; parser.SetDelimiters(","); fields = parser.ReadFields();
                }
            }
            return fields;
        }
    }
}
Спасибо. Не могли бы вы поделиться функцией «GetFileds»? Похоже, это отсутствует. Alex Javarotti
@ AlexJavarotti В коде добавлен недостающий метод. Anand Kishore
2

используя newtonsoft

public string ConvertCsvFileToJsonObject(string path) 
{
    var csv = new List<string[]>();
    var lines = File.ReadAllLines(path);

    foreach (string line in lines)
        csv.Add(line.Split(','));

    var properties = lines[0].Split(',');

    var listObjResult = new List<Dictionary<string, string>>();

    for (int i = 1; i < lines.Length; i++)
    {
        var objResult = new Dictionary<string, string>();
        for (int j = 0; j < properties.Length; j++)
            objResult.Add(properties[j], csv[i][j]);

        listObjResult.Add(objResult);
    }

    return JsonConvert.SerializeObject(listObjResult); 
}
1

такой же ответ, есть ссылка наэта почт.

CsvToJson метод расширения

/// <summary>
/// Converts a CSV string to a Json array format.
/// </summary>
/// <remarks>First line in CSV must be a header with field name columns.</remarks>
/// <param name="value"></param>
/// <returns></returns>
public static string CsvToJson(this string value)
{
    // Get lines.
    if (value == null) return null;
    string[] lines = value.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
    if (lines.Length < 2) throw new InvalidDataException("Must have header line.");

    // Get headers.
    string[] headers = lines.First().SplitQuotedLine(new char[] { ',' }, false);

    // Build JSON array.
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("[");
    for (int i = 1; i < lines.Length; i++)
    {
        string[] fields = lines[i].SplitQuotedLine(new char[] { ',', ' ' }, true, '"', false);
        if (fields.Length != headers.Length) throw new InvalidDataException("Field count must match header count.");
        var jsonElements = headers.Zip(fields, (header, field) => string.Format("{0}: {1}", header, field)).ToArray();
        string jsonObject = "{" + string.Format("{0}", string.Join(",", jsonElements)) + "}";
        if (i < lines.Length - 1)
            jsonObject += ",";
        sb.AppendLine(jsonObject);
    }
    sb.AppendLine("]");
    return sb.ToString();
}

Похоже, существует проблема, связанная с тем, что некоторые методы, вызываемые в вышеуказанном расширении, живут (см. Комментарии к исходному сообщению в блоге), но это должно помочь вам в этом.

РЕДАКТИРОВАТ Вот другой ответ о разделении линии CSV. Вы можете использовать одно из предложенных решений для регулярных выражений, чтобы создать свой собственныйSplitQuotedLine метод:

public static string SplitQuotedLine(this string value, char separator, bool quotes) {
    // Use the "quotes" bool if you need to keep/strip the quotes or something...
    var s = new StringBuilder();
    var regex = new Regex("(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)");
    foreach (Match m in regex.Matches(value)) {
        s.Append(m.Value);
    }
    return s.ToString();
}

Я не проверял вышеизложенное, поэтому прости меня, если я допустил какие-либо ошибки.

Также может показаться, чтоZip - это метод расширения LINQ, так что это решит эту проблему.

yes, но SplitQuotedLine - это метод, определенный пользователем, который отсутствует в записи блога user1427026
Даже не видя, что происходит в этом методе, довольно легко сказать, что это просто разделение строки.lines.First().Split(',')о сути, @ будет делать то же самое - скорее всего, он проверяет любые запятые в кавычках и, возможно, удаляет кавычки тоже.Zip extension может быть немного больше, чтобы выяснить. Как я уже сказал, это даст вам большую часть пути туда. Я думаю, вы ищете что-то на 100% завершенное, хотя, поскольку вы новичок в C #, верно? Tim Hobbs
Конечно, я надеюсь, что это сработает. Как я уже сказал, я просто опубликовал в качестве примера, я не пробовал. Это должно работать, но может потребовать небольших настроек, но никаких гарантий! :) Tim Hobbs
1

Я использую ChoETL:

using ChoETL;
using System.IO;

public class FromCSVtoJSON
{
    public FromCSVtoJSON()
    {

    }

    public void convertFile(string inputFile, string outputFile)
    {
        using (var writer = new StreamWriter(outputFile))
        {
            int row = 0;
            writer.Write("[\r\n");

            foreach (var e in new ChoCSVReader(inputFile).WithHeaderLineAt())
            {
                writer.Write((row > 0 ? ",\r\n" : "") + e.DumpAsJson());
                writer.Flush();
                row++;
            }
            writer.Write("]");
            writer.Flush();
            writer.Close();
        }

    }
}
0

наконец, я решил его, используя словарь

public static void CreateJsonFromCSV()
{
    string path = "C:\\Users\\xx\\xx\\xx\\xx\\lang.csv";
    string textFilePath = path;
    const Int32 BufferSize = 128;

    using (var fileStream = File.OpenRead(textFilePath))
    using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize))
    {
        String line;
        Dictionary<string, string> jsonRow = new Dictionary<string, string>();

        while ((line = streamReader.ReadLine()) != null)
        {

            string[] parts = line.Split(',');

            string key_ = parts[0];
            string value = parts[1];


            if (!jsonRow.Keys.Contains(key_))
            {
                jsonRow.Add(key_, value );
            }

        }
        var json = new JavaScriptSerializer().Serialize(jsonRow);
        string path_ = "C:\\XX\\XX\\XX\\XX\\XX.csv";
        File.WriteAllText(path_, json);
    }

} 
ты Анак ... Leon
0

что вы добавили ниже в web.config, прежде чем анализировать большие CSV-файлы.

 <system.web.extensions>
       <scripting>
           <webServices>
               <jsonSerialization maxJsonLength="50000000"/>
           </webServices>
       </scripting>
   </system.web.extensions>
0

Takingтольк зависимость от Newtonsoft.Json, вот вспомогательный метод с массивом строк CSV, первая из которых является заголовком.

    public static IEnumerable<JObject> CsvToJson(IEnumerable<string> csvLines)
    {
        var csvLinesList = csvLines.ToList();

        var header = csvLinesList[0].Split(',');
        for (int i = 1; i < csvLinesList.Count; i++)
        {
            var thisLineSplit = csvLinesList[i].Split(',');
            var pairedWithHeader = header.Zip(thisLineSplit, (h, v) => new KeyValuePair<string, string>(h, v));

            yield return new JObject(pairedWithHeader.Select(j => new JProperty(j.Key, j.Value)));
        }
    }
0

Попробуй это

 StreamReader sr = new StreamReader(filePath);
 while ((line = sr.ReadLine()) != null)
 {
      //Console.WriteLine(line);
      string[] csv = line.Split(',');
      var dictionary = new Dictionary<string, string>();
      dictionary.Add("dispatching_base_number",csv[0]);
      dictionary.Add("available_vehicles", csv[1]);
      dictionary.Add("vehicles_in_trips", csv[2]);
      dictionary.Add("Cancellations", csv[3]);
      string jsonN = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(dictionary);
      Console.WriteLine("Sending message: {0}",jsonN);
 }

Похожие вопросы