问题描述
我的 CSV 文件有问题。
我试图从 CSV 文件中获取列和行,但我的代码(如下)没有以正确的格式获取行和列。
CSV File 的示例
我现在使用的代码如下所示:
DataTable dt = new DataTable();
string FileName = strFilePath;
using (FileStream stream = File.Open(Path.Combine(@"C:\Users\mulus\Desktop","schema.ini"),FileMode.Create,FileAccess.Write,FileShare.None))
{
using (StreamWriter writer = new StreamWriter(stream))
{
writer.WriteLine(string.Format("[{0}]",FileName));
writer.WriteLine("Format=Delimited(;)");
writer.WriteLine("TextDelimiter=\"");
writer.WriteLine("ColNameHeader=True");
}
}
OleDbConnection conn = new OleDbConnection
("Provider=Microsoft.Jet.OleDb.4.0; Data Source = " +
Path.GetDirectoryName(FileName) +
"; Extended Properties = \"Text;FMT=Delimited(;)\"");
conn.open();
var abc = Path.GetFileName(FileName);
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM " + Path.GetFileName(FileName),conn);
adapter.Fill(dt);
conn.Close();
我尝试了很多东西:
- 在 FileStream 类上尝试了不同的格式
- 不使用 FileStream 类
- 将 "; Extended Properties = "Text;FMT=Delimited(;)"");" 更改为 Format=Delimited(;)、FMT=TabDelimiter 和 Format=TabDelimiter(它只是忽略它)
- 尝试在注册表中更改它,但出现了 error(无法编辑:写入值的新内容时出错)
- 我也尝试给我“完全控制”,但我没有足够的权限来执行此操作
但我也尝试用不同的代码来做到这一点,但这个忽略了“;” B 列中的符号(“45;43”)并将其视为 2 列而不是 1 列,总体而言,格式确实很混乱:
using (StreamReader sr = new StreamReader(strFilePath,Encoding.Default))
{
string[] headers = sr.ReadToEnd().Split(new string[] { "\r\n" },StringSplitOptions.None);
foreach (string header in headers)
{
dt.Columns.Add(header);
}
while (!sr.EndOfStream)
{
string[] rows = sr.ReadLine().Split(';');
DaTarow dr = dt.NewRow();
for (int i = 0; i < headers.Length; i++)
{
dr[i] = rows[i];
}
dt.Rows.Add(dr);
}
}
此外,似乎将此代码用于 CSV 文件很容易出错,而且根本不是一个好主意。
如果您对错误有任何想法或其他想法如何做到这一点,我将不胜感激。
系统:Winodws 7、Excel 2010、
解决方法
使用 CsvHelper 包 https://joshclose.github.io/CsvHelper/
JET 引擎和您自己的自制解决方案都无法超越 CsvHelper 为您提供的开箱即用功能。
根据您的屏幕截图使用此 MCVE:
var sb = new StringBuilder();
sb.AppendLine("A;B;C;D;E;");
sb.AppendLine("1;\"45;43\";\"-A\n-B\n-C\";tomato;potato;");
sb.AppendLine("2;\"55;34\";\"-D\n-E\n-F\";carrot;parrot;");
var config = new CsvHelper.Configuration.CsvConfiguration{ Delimiter =";"};
using (var reader = new StringReader(sb.ToString()))
using (var csv = new CsvReader(reader,config))
{
var cnt =1;
var records = csv.GetRecords<Row>();
foreach(var rec in records)
{
cnt++.Dump("record");
rec.A.Dump("A");
rec.B.Dump("B");
rec.C.Dump("C");
rec.D.Dump("D");
rec.E.Dump("E");
}
}
我得到这个输出:
我使用了这个 DTO 类:
class Row
{
public string A {get;set;}
public string B {get;set;}
public string C {get;set;}
public string D {get;set;}
public string E {get;set;}
};
声明:JET 引擎永远不会以有意义的方式为您读取该示例 CSV 文件。它不是为了处理文本字段内的换行符而构建的。