C# 使用特定的列分隔符解析csv文件&;使用CsvHelper库的字符串存储模块
我在.NETC#项目中使用这个很棒的库来满足CSV解析需求 如果我有一个如下所示的CSV文件:C# 使用特定的列分隔符解析csv文件&;使用CsvHelper库的字符串存储模块,c#,csv,C#,Csv,我在.NETC#项目中使用这个很棒的库来满足CSV解析需求 如果我有一个如下所示的CSV文件: SupplierSku,MappedSageSku EG1234,EGCD1234 EG4567,EG-XZ567 public class SkuMapping { public string SupplierSku { get; set; } public string MappedSageSku { get; set; } } // Open & parse sele
SupplierSku,MappedSageSku
EG1234,EGCD1234
EG4567,EG-XZ567
public class SkuMapping
{
public string SupplierSku { get; set; }
public string MappedSageSku { get; set; }
}
// Open & parse selected csv file
var csvReader = new CsvReader(File.OpenText(selectSkuMapping.Text));
var skuMappings = csvReader.GetRecords<SkuMapping>();
// Do something with each row
foreach (SkuMapping skuMapping in skuMappings)
{
// ...
}
我通常创建一个DTO类,如下所示:
SupplierSku,MappedSageSku
EG1234,EGCD1234
EG4567,EG-XZ567
public class SkuMapping
{
public string SupplierSku { get; set; }
public string MappedSageSku { get; set; }
}
// Open & parse selected csv file
var csvReader = new CsvReader(File.OpenText(selectSkuMapping.Text));
var skuMappings = csvReader.GetRecords<SkuMapping>();
// Do something with each row
foreach (SkuMapping skuMapping in skuMappings)
{
// ...
}
并按如下方式解析csv文件:
SupplierSku,MappedSageSku
EG1234,EGCD1234
EG4567,EG-XZ567
public class SkuMapping
{
public string SupplierSku { get; set; }
public string MappedSageSku { get; set; }
}
// Open & parse selected csv file
var csvReader = new CsvReader(File.OpenText(selectSkuMapping.Text));
var skuMappings = csvReader.GetRecords<SkuMapping>();
// Do something with each row
foreach (SkuMapping skuMapping in skuMappings)
{
// ...
}
在哪里<代码>列分隔符=,
和字符串附件
=“
我需要的数据:列索引0
(PartNumb)和列索引1
(InStock)
示例2
其中;列分隔符
=|
和字符串附件
=%
我需要的数据:列索引0
(供应商SKU)和列索引2
(库存状态)
鉴于上述情况,使用
CsvHelper
库解析任意csv文件的最佳方法是什么(其中列分隔符
,字符串附件
和列索引
已知)?我还需要跳过csv上的第一行的选项(有时csv包含标题行,有时不包含标题行).使用CsvHelper,这似乎有效:
var textToParse = @"SupplierSku,CatIds,StockStatus,Active
%ADA-BB-124%|4,5,1|%AV%|1
%XAS-E4-S11%|97,41,65|%OS%|0";
string supplierSku;
string stockStatus;
using (var stringReader = new StringReader(textToParse))
{
using (var reader = new CsvReader(stringReader))
{
reader.Configuration.Delimiter = ",";
reader.Configuration.HasHeaderRecord = true; // If there is no header, set to false.
while (reader.Read())
{
supplierSku = reader.GetField("SupplierSku"); // Or reader.GetField(0)
stockStatus = reader.GetField("StockStatus"); // Or reader.GetField(2)
Console.WriteLine($"SKU: {supplierSku}; Status: {stockStatus}");
}
}
}
但是,它不会自动修剪/删除引号字符-您可以使用
trim()
或Substring()
轻松地进行修剪/删除。需要更多的手动操作,但仍然比手动操作简单。使用CsvHelper,这似乎很有效:
var textToParse = @"SupplierSku,CatIds,StockStatus,Active
%ADA-BB-124%|4,5,1|%AV%|1
%XAS-E4-S11%|97,41,65|%OS%|0";
string supplierSku;
string stockStatus;
using (var stringReader = new StringReader(textToParse))
{
using (var reader = new CsvReader(stringReader))
{
reader.Configuration.Delimiter = ",";
reader.Configuration.HasHeaderRecord = true; // If there is no header, set to false.
while (reader.Read())
{
supplierSku = reader.GetField("SupplierSku"); // Or reader.GetField(0)
stockStatus = reader.GetField("StockStatus"); // Or reader.GetField(2)
Console.WriteLine($"SKU: {supplierSku}; Status: {stockStatus}");
}
}
}
但是,它不会自动修剪/删除引号字符-您可以使用
trim()
或Substring()
轻松地修剪/删除引号字符。手动操作要多一些,但仍然比手动操作简单。答案取决于您想要什么:
- 在开始解析之前,您知道允许使用哪些分隔符吗
- 是否要按名称按列数选择列
private sealed class MyCsvConverterMap : CsvClassMap<MyDestinationType>
{
public MyCsvConverterMap()
{
Map(item => item.YourProperty).Name("MyColumn");
// map all properties in your destination to a column
}
}
using (TextReader txtReader = new StringReader(...))
{
CsvReader csvReader = new CsvReader(txtReader);
csvReader.Configuration.Delimiter = ";";
csvReader.Configuration.HasHeaderRecord = true;
csvReader.Configuration.RegisterClassMap(new MyCsvConverterMap());
while (csvReader.Read())
{
MyDestinationType convertedRecord = csvReader.GetRecord<MyDestinationType>();
...
私有密封类MyCsvConverterMap:CsvClassMap
{
公共MyCsvConverterMap()
{
Map(item=>item.YourProperty).Name(“MyColumn”);
//将目标中的所有属性映射到列
}
}
使用(TextReader txtReader=新的StringReader(…)
{
CsvReader CsvReader=新的CsvReader(txtReader);
csvReader.Configuration.Delimiter=“;”;
csvReader.Configuration.HasHeaderRecord=true;
RegisterClassMap(新的MyCsvConverterMap());
while(csvReader.Read())
{
MyDestinationType convertedRecord=csvReader.GetRecord();
...
添加
也可以按列编号映射,而不是按列名映射。请参阅各种映射的说明:
答案取决于你想要什么:
- 在开始解析之前,您知道允许使用哪些分隔符吗
- 是否要按名称按列数选择列
private sealed class MyCsvConverterMap : CsvClassMap<MyDestinationType>
{
public MyCsvConverterMap()
{
Map(item => item.YourProperty).Name("MyColumn");
// map all properties in your destination to a column
}
}
using (TextReader txtReader = new StringReader(...))
{
CsvReader csvReader = new CsvReader(txtReader);
csvReader.Configuration.Delimiter = ";";
csvReader.Configuration.HasHeaderRecord = true;
csvReader.Configuration.RegisterClassMap(new MyCsvConverterMap());
while (csvReader.Read())
{
MyDestinationType convertedRecord = csvReader.GetRecord<MyDestinationType>();
...
私有密封类MyCsvConverterMap:CsvClassMap
{
公共MyCsvConverterMap()
{
Map(item=>item.YourProperty).Name(“MyColumn”);
//将目标中的所有属性映射到列
}
}
使用(TextReader txtReader=新的StringReader(…)
{
CsvReader CsvReader=新的CsvReader(txtReader);
csvReader.Configuration.Delimiter=“;”;
csvReader.Configuration.HasHeaderRecord=true;
RegisterClassMap(新的MyCsvConverterMap());
while(csvReader.Read())
{
MyDestinationType convertedRecord=csvReader.GetRecord();
...
添加
也可以按列编号映射,而不是按列名映射。请参阅各种映射的说明:
您还可以通过
CsvClassMap
创建类型安全映射,并从DefaultTypeConverter
类继承以创建CATID的转换器(逗号分隔)
下面的示例适用于您的示例#2:
[TestClass]
公共类CsvHelperTest
{
[测试方法]
公开无效测试()
{
var textToParse=“供应商SKU、CATID、库存状态、活动”+Environment.NewLine;
textToParse+=%ADA-BB-124%| 4,5,1 |%AV%| 1“+Environment.NewLine;
textToParse+=%XAS-E4-S11%| 97,41,65 |%OS%| 0;
使用(var stringReader=newstringreader(textToParse))
{
使用(变量读取器=新CsvReader(stringReader))
{
reader.Configuration.Quote='%';
reader.Configuration.Delimiter=“|”;
reader.Configuration.HasHeaderRecord=true;//如果存在n