Je me demandais si quelqu'un avait écrit un utilitaire permettant de convertir un fichier CSV en Json à l'aide de C #. D'une question précédente sur stackoverflow, je connais cet utilitaire Nice - https://github.com/cparker15/csv-to-json et je prévois d'y faire référence, mais avec une implémentation C # existante serait très utile! Merci!
Si vous pouvez utiliser System.Web.Extensions
, ceci pourrait fonctionner:
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);
Vous avez peut-être des exigences d'analyse plus complexes pour le fichier csv et une classe qui encapsule les données d'une ligne, mais vous pouvez sérialiser en JSON avec une ligne de code une fois que vous avez une collection.
Cinchoo ETL - une bibliothèque open source disponible pour faire la conversion de CSV à JSON facilement avec quelques lignes de code
Pour un exemple de CSV:
Id, Name, City
1, Tom, NY
2, Mark, NJ
3, Lou, FL
4, Smith, PA
5, Raj, DC
Exemple de code,
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 de sortie:
[
{
"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"
}
]
Commander CodeProject article pour une aide supplémentaire.
Disclaimer: Je suis l'auteur de cette bibliothèque.
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 = GetHeaders(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;
}
}
}
J'ai utilisé Dictionary et renvoyé json avec 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);
}
À partir de cette même réponse SO , il existe un lien vers ce post .
Méthode d'extension 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();
}
Il semble y avoir un problème avec l'emplacement de certaines méthodes appelées dans l'extension ci-dessus (voir les commentaires du billet de blog d'origine), mais cela devrait vous rendre la plupart du temps.
EDIT Voici une autre SO réponse à propos du fractionnement d'une ligne CSV. Vous pouvez utiliser l’une des solutions de regex suggérées pour créer votre propre méthode 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();
}
Je n'ai pas testé ce qui précède, alors pardonnez-moi si j'ai commis des erreurs.
De plus, il semblerait que Zip est une méthode d’extension LINQ , donc cela prend en charge ce problème.
J'utilise 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();
}
}
}
Prenant seulement une dépendance de Newtonsoft.Json, voici une méthode d'assistance à partir d'un tableau de lignes CSV, la première étant l'en-tête.
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)));
}
}
J'ai cherché la réponse à cette question, finalement je l'ai résolue en utilisant Dictionary
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);
}
}
Essaye ça:
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);
}
Assurez-vous d’ajouter ce qui suit dans web.config avant d’analyser des fichiers csv volumineux.
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="50000000"/>
</webServices>
</scripting>
</system.web.extensions>