使用 C# 将 csv 文件转换为 json
Posted
技术标签:
【中文标题】使用 C# 将 csv 文件转换为 json【英文标题】:Converting a csv file to json using C# 【发布时间】:2012-06-05 03:40:49 【问题描述】:我想知道是否有人编写了一个实用程序来使用 C# 将 CSV 文件转换为 Json。从上一个关于 *** 的问题中,我知道了这个不错的实用程序 - https://github.com/cparker15/csv-to-json,目前我打算参考它,但现有的 C# 实现会非常有帮助!谢谢!
【问题讨论】:
您可以轻松地将 JS 代码音译为 C#,也可以保留var
关键字。
是的,这就是我计划做的,但我能找到的唯一一篇文章,msdn social.msdn.microsoft.com/Forums/en-US/vsto/thread/… 上的这篇文章使用 Office.Interop,我是 C# 的新手,不太熟悉它。我需要使用它还是应该很好地尝试翻译 js 实用程序?谢谢!
我会避免在 CSV 文件上使用 Office.Interop,因为 CSV 只是文本。
【参考方案1】:
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"
]
小提琴样例:https://dotnetfiddle.net/pclnsT
查看CodeProject 文章以获得更多帮助。
更新: 如果您的 CSV 文件有重复的列名或没有名称,请使用以下步骤生成 JSON 文件
string csv = @"Id, Name,
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)
.WithField("Id", position: 1)
.WithField("Name", position: 2)
.WithField("City", position: 3)
.WithFirstLineHeader(true)
)
using (var w = new ChoJSONWriter(sb))
w.Write(p);
Console.WriteLine(sb.ToString());
小提琴样例:https://dotnetfiddle.net/pP5Du6
免责声明:我是这个库的作者。
【讨论】:
使用 ChoCSVReader / ChoJSONReader 构造函数。 此方法使用动态模型。foreach (dynamic e in new ChoCSVReader(csv).WithFirstLineHeader()) System.Diagnostics.Debug.Write(e.CSVColumnName);
。欲了解更多信息,请访问 CodeProject 文章/GitHub wiki。
这个库很好,它做了它的用途。但是当 CSV 的键中有一些特殊字符时,比如我有 loerem.lipsm,它会将我的键转换为 loerem_lipsm。有什么解决办法吗
这为我节省了很多时间,将一堆 csv 文件转换为 json。使用极其简单。感谢您的图书馆。
这是一个更好的答案,因为几乎所有其他解决方案都假定唯一的逗号是分隔符。在 csv 中,引用包含分隔符的值是很常见的。下面有一个示例可以使用此库执行此操作,但我使用了上面的示例并将“.WithFirstLineHeader()”更改为“.WithFirstLineHeader().QuoteAllFields()”,它非常适合我的测试数据。话虽如此,如果该值包含行分隔符,则它不起作用,但也可能有一些东西可以控制它,我只是没有寻找它。干得好 Cinchoo...【参考方案2】:
bc3tech 解决方案的小变化,即避免外部依赖(在 Newtonsoft.Json 上),而是使用 System.Text.Json(dotnet core 3+)
public static IEnumerable<string> CsvToJson(string fileName, char delim = '|')
var lines = File.ReadLines(fileName);
var hdr = new List<string>(lines.First().Trim().Split(delim));
foreach (var l in lines.Skip(1).Where(l => (l.Trim() != String.Empty)))
var val = l.Trim().Split(delim);
var ds = hdr.Zip(val, (k, v) => new k, v ).ToDictionary(x => x.k, x => x.v);
yield return JsonSerializer.Serialize(ds);
【讨论】:
【参考方案3】:如果您正在寻找仅限 C# 的解决方案,这可能对您有用。我最近遇到了同样的问题,并创建了这种方法来克服。
public static string ConvertToJsonStructure(string csvDataAsString, char delimiter = ',', bool hasHeaders = true)
var output = string.Empty;
if (string.IsNullOrEmpty(csvDataAsString))
return "";
var rows = csvDataAsString.Split(new string[] Environment.NewLine , StringSplitOptions.None);
var headers = hasHeaders ? rows[0].Split(delimiter) : null;
var colCount = headers?.Length;
var jsonStart = "";
var jsonEnd = "";
if (rows.Length > (1 + (hasHeaders ? 1 : 0)))
jsonStart = "[";
jsonEnd = "]";
output = output + jsonStart;
int startIndex = hasHeaders ? 1 : 0;
for (int i = startIndex; i < rows.Length; i++)
var cols = rows[i].Split(delimiter);
if (colCount == null)
colCount = cols.Length;
var tempJson = "";
for (int j = 0; j < colCount.Value; j++)
if (hasHeaders)
tempJson = tempJson + $"\"headers[j]\":";
var isNumber = Regex.IsMatch(cols[j], @"^\d + $");
var val = isNumber ? cols[j] : $"\"cols[j]\"";
tempJson = tempJson + val;
if (j < colCount.Value - 1)
tempJson = tempJson + ",";
tempJson = tempJson + "";
if (i < rows.Length - 1)
tempJson = tempJson + ",";
output = output + tempJson;
output = output + jsonEnd;
return output;
你需要将你的内容作为字符串传递给这个方法,你可以做这样的事情来读取你的 csv
var csvAsString = File.ReadAllText("TestCsv.csv");
var result = CsvToJson.ConvertToJsonStructure(csvAsString);
【讨论】:
【参考方案4】:将平面 csv 文件转换为简单 json 格式对象集合的简单方法。适用于第一行带有标题行的文件。这种方法的一部分是在 SO 的其他地方找到的。 添加对 Microsoft.VisualBasic 的引用。
using Microsoft.VisualBasic.FileIO;
public static StringBuilder ReadCsv()
var path = @"X:\...\input.csv";
using (TextFieldParser csvParser = new TextFieldParser(path))
csvParser.CommentTokens = new string[] "#" ;
//Remember to use your own separator
csvParser.SetDelimiters(new string[] ";" );
csvParser.HasFieldsEnclosedInQuotes = false;
StringBuilder json = new StringBuilder();
string[] colNames = new string[0];
string[] fields = new string[0];
json.Append("[");
int counter = 0;
while (!csvParser.EndOfData)
if (counter == 0)
//Read properies' names
colNames = csvParser.ReadFields();
counter++;
Console.WriteLine($"colNames.Length columns detected!");
else
// Read current line fields, pointer moves to the next line.
// Read the properties' values
fields = csvParser.ReadFields();
json.Append("");
for (int i = 0; i < colNames.Length; i++)
json.Append($"\"colNames[i]\":TryParse(fields[i])");
if (i != colNames.Length - 1)
json.Append(",");
json.Append(",");
Console.WriteLine($"Writing record nr.: counter");
counter++;
json.Length--; //Remove trailing comma
json.Append("]");
return json;
string TryParse(string s)
if (string.IsNullOrEmpty(s)) return "null";
//Remember to set your decimal character here!
if (s.Contains('.'))
double dResult;
//This works on my computer, could be different on your machine
if (double.TryParse(s, NumberStyles.AllowDecimalPoint,
CultureInfo.InvariantCulture, out dResult))
return dResult.ToString(CultureInfo.InvariantCulture);
else
int intResult;
if (int.TryParse(s, out intResult))
return intResult.ToString(CultureInfo.InvariantCulture);
return "\"" + s + "\"";
这应该会给你一个简单的 json 对象列表。
【讨论】:
【参考方案5】:首先,将 csv 文件加载到数据表中,并将其序列化为 Json 文档。它使用可以明智地解析 csv 的 OLEDB Provider,
感谢 Jim Scott,https://***.com/a/1050278/6928056
感谢 K_B,https://***.com/a/2979938/6928056
using System.Data;
using System.Data.OleDb;
using System.Globalization;
using System.IO;
using Newtonsoft.Json;
static string ConvertCsvToJson(string path, bool isFirstRowHeader)
string header = isFirstRowHeader ? "Yes" : "No";
string pathOnly = Path.GetDirectoryName(path);
string fileName = Path.GetFileName(path);
string sql = @"SELECT * FROM [" + fileName + "]";
using(OleDbConnection connection = new OleDbConnection(
@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly +
";Extended Properties=\"Text;HDR=" + header + "\""))
using(OleDbCommand command = new OleDbCommand(sql, connection))
using(OleDbDataAdapter adapter = new OleDbDataAdapter(command))
var dataTable = new DataTable();
dataTable.Locale = CultureInfo.CurrentCulture;
adapter.Fill(dataTable);
return JsonConvert.SerializeObject(dataTable, Formatting.Indented);
【讨论】:
【参考方案6】:这是我的.. 它可以解析几个世纪以来的 9k CSV 记录。哈哈
class CSVTOJSON
public string ConvertToJSON()
string json = string.Empty;
string csv = string.Empty;
using (StreamReader reader = new StreamReader("data.csv"))
csv = reader.ReadToEnd();
string[] lines = csv.Split(new string[] "\n" , System.StringSplitOptions.None);
if (lines.Length > 1)
// parse headers
string[] headers = lines[0].Split(',');
StringBuilder sbjson = new StringBuilder();
sbjson.Clear();
sbjson.Append("[");
// parse data
for (int i = 1; i < lines.Length; i++)
if (string.IsNullOrWhiteSpace(lines[i])) continue;
if (string.IsNullOrEmpty(lines[i])) continue;
sbjson.Append("");
string[] data = lines[i].Split(',');
for (int h = 0; h < headers.Length; h++)
sbjson.Append(
$"\"headers[h]\": \"data[h]\"" + (h < headers.Length - 1 ? "," : null)
);
sbjson.Append("" + (i < lines.Length - 1 ? "," : null));
sbjson.Append("]");
json = sbjson.ToString();
return json;
但它有效。
控制台日志:
Converting CSV to JSON
CSV has 9486 data
Total duration converting CSV to JSON: 00:00:00.0775373
【讨论】:
【参考方案7】:我用ChoETL:
using ChoETL;
using System.IO;
public class FromCSVtoJSON
public FromCSVtoJSON()
public void convertFile(string inputFile, string outputFile)
using (var writer = new ChoJSONWriter(outputFile))
using (var reader = new ChoCSVReader(inputFile).WithFirstLineHeader())
writer.Write(reader);
【讨论】:
当两个标头具有相同名称或没有名称时,此操作将失败 你使用哪个版本的 ChoETL 因为对我来说 ChoJSONWriter 无法识别它会导致错误 安装 ChoETL.JSON 包【参考方案8】:试试这个并将CSV
转换为JSON
对象:
public static List<object> CsvToJson( string body, string[] column )
if ( string.IsNullOrEmpty( body ) ) return null;
string[] rowSeparators = new string[] "\r\n" ;
string[] rows = body.Split( rowSeparators, StringSplitOptions.None );
body = null;
if ( rows == null || ( rows != null && rows.Length == 0 ) ) return null;
string[] cellSeparator = new string[] "," ;
List<object> data = new List<object>( );
int clen = column.Length;
rows.Select( row =>
if ( string.IsNullOrEmpty( row ) ) return row;
string[] cells = row.Trim( ).Split( cellSeparator, StringSplitOptions.None );
if ( cells == null ) return row;
if ( cells.Length < clen ) return row;
Dictionary<object, object> jrows = new Dictionary<object, object>( );
for ( int i = 0; i < clen; i++ )
jrows.Add( column[i], cells[i]?.Trim( ) );
data.Add( jrows );
return row;
).ToList( );
rowSeparators = null; rows = null;
cellSeparator = null;
return data;
var data = CsvToJson("csv_input_str", new string[] "column_map" )
string jsonStr = new javascriptSerializer MaxJsonLength = int.MaxValue .Serialize( data );
【讨论】:
【参考方案9】: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;
【讨论】:
谢谢。你能分享函数'GetFileds'吗?好像不见了。 @AlexJavarotti Missing 方法已添加到代码中。TextFieldParser
方法不见了?你能把这个添加到你的答案中吗【参考方案10】:
试试这个:
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);
【讨论】:
【参考方案11】:我使用了 Dictionary 并使用 newtonsoft 返回了 json
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);
【讨论】:
我喜欢这个答案。它使用字典并保持通用的事实使其几乎可以与任何 CSV 一起使用。干得好!!! 谢谢@justdan23 =) 如何处理 CSV 中的转义逗号? 这是一个特定的风景和可能的。可能,会用逗号切断句子。我会考虑的【参考方案12】:仅依赖于 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)));
【讨论】:
【参考方案13】:确保在解析大型 csv 文件之前在 web.config 中添加以下内容。
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization maxJsonLength="50000000"/>
</webServices>
</scripting>
</system.web.extensions>
【讨论】:
【参考方案14】:我在寻找这个问题的答案,最后我用字典解决了它
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);
【讨论】:
【参考方案15】:从那个same SO answer,有一个指向this post的链接。
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();
在上述扩展中调用的某些方法在哪里存在似乎存在问题(请参阅原始博客文章的 cmets),但它应该可以帮助您完成大部分工作。
编辑 这是another SO answer 关于拆分 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 is a LINQ extension method 似乎可以解决这个问题。
【讨论】:
是的,但是 SplitQuotedLine - 这是博客文章中缺少的用户定义方法 即使没有看到该方法中发生了什么,也很容易看出它只是在拆分一个字符串。lines.First().Split(',')
基本上会做同样的事情——它可能只是测试任何引用的逗号,也可能会去掉引号。 Zip
扩展名可能需要更多了解。就像我说的那样,它可以让你大部分时间到达那里。我猜您正在寻找 100% 完整的东西,因为您是 C# 新手,对吧?
当然,我希望它能成功。就像我说的,我只是作为示例发布,我没有尝试过。它应该可以工作,但可能需要一些小的调整,但不能保证! :)
SplitQuotedLine
是return string []
吗?【参考方案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 文件有更复杂的解析要求,并且您可能有一个封装一行数据的类,但关键是,一旦您有一个 Collection of lines,您就可以用一行代码序列化为 JSON .
【讨论】:
如果文件很大,这通常会导致错误。例如:使用 JSON JavaScriptSerializer 进行序列化或反序列化时出错。字符串长度超过 maxJsonLength 属性设置的值以上是关于使用 C# 将 csv 文件转换为 json的主要内容,如果未能解决你的问题,请参考以下文章