【发布时间】:2011-05-21 14:14:00
【问题描述】:
我有一个要求,我必须从存储在我的磁盘中的 CSV 文件中读取数据,并将 CSV 中的所有数据放入 .Net DataTable 中。
我该怎么做?
【问题讨论】:
标签: .net csv datatable import-from-csv
我有一个要求,我必须从存储在我的磁盘中的 CSV 文件中读取数据,并将 CSV 中的所有数据放入 .Net DataTable 中。
我该怎么做?
【问题讨论】:
标签: .net csv datatable import-from-csv
我在下面编写了五种方法,可以将 Csv 文件转换为 DataTable。
它们的设计考虑了可选引号(例如 " 符号),并且在不使用其他库的情况下尽可能多用途:
public static DataTable GetDataTabletFromCSVFile(string filePath, bool isHeadings)
{
DataTable MethodResult = null;
try
{
using (TextFieldParser TextFieldParser = new TextFieldParser(filePath))
{
if (isHeadings)
{
MethodResult = GetDataTableFromTextFieldParser(TextFieldParser);
}
else
{
MethodResult = GetDataTableFromTextFieldParserNoHeadings(TextFieldParser);
}
}
}
catch (Exception ex)
{
ex.HandleException();
}
return MethodResult;
}
public static DataTable GetDataTableFromCsvString(string csvBody, bool isHeadings)
{
DataTable MethodResult = null;
try
{
MemoryStream MemoryStream = new MemoryStream();
StreamWriter StreamWriter = new StreamWriter(MemoryStream);
StreamWriter.Write(csvBody);
StreamWriter.Flush();
MemoryStream.Position = 0;
using (TextFieldParser TextFieldParser = new TextFieldParser(MemoryStream))
{
if (isHeadings)
{
MethodResult = GetDataTableFromTextFieldParser(TextFieldParser);
}
else
{
MethodResult = GetDataTableFromTextFieldParserNoHeadings(TextFieldParser);
}
}
}
catch (Exception ex)
{
ex.HandleException();
}
return MethodResult;
}
public static DataTable GetDataTableFromRemoteCsv(string url, bool isHeadings)
{
DataTable MethodResult = null;
try
{
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
StreamReader StreamReader = new StreamReader(httpWebResponse.GetResponseStream());
using (TextFieldParser TextFieldParser = new TextFieldParser(StreamReader))
{
if (isHeadings)
{
MethodResult = GetDataTableFromTextFieldParser(TextFieldParser);
}
else
{
MethodResult = GetDataTableFromTextFieldParserNoHeadings(TextFieldParser);
}
}
}
catch (Exception ex)
{
ex.HandleException();
}
return MethodResult;
}
private static DataTable GetDataTableFromTextFieldParser(TextFieldParser textFieldParser)
{
DataTable MethodResult = null;
try
{
textFieldParser.SetDelimiters(new string[] { "," });
textFieldParser.HasFieldsEnclosedInQuotes = true;
string[] ColumnFields = textFieldParser.ReadFields();
DataTable dt = new DataTable();
foreach (string ColumnField in ColumnFields)
{
DataColumn DataColumn = new DataColumn(ColumnField);
DataColumn.AllowDBNull = true;
dt.Columns.Add(DataColumn);
}
while (!textFieldParser.EndOfData)
{
string[] Fields = textFieldParser.ReadFields();
for (int i = 0; i < Fields.Length; i++)
{
if (Fields[i] == "")
{
Fields[i] = null;
}
}
dt.Rows.Add(Fields);
}
MethodResult = dt;
}
catch (Exception ex)
{
ex.HandleException();
}
return MethodResult;
}
private static DataTable GetDataTableFromTextFieldParserNoHeadings(TextFieldParser textFieldParser)
{
DataTable MethodResult = null;
try
{
textFieldParser.SetDelimiters(new string[] { "," });
textFieldParser.HasFieldsEnclosedInQuotes = true;
bool FirstPass = true;
DataTable dt = new DataTable();
while (!textFieldParser.EndOfData)
{
string[] Fields = textFieldParser.ReadFields();
if(FirstPass)
{
for (int i = 0; i < Fields.Length; i++)
{
DataColumn DataColumn = new DataColumn("Column " + i);
DataColumn.AllowDBNull = true;
dt.Columns.Add(DataColumn);
}
FirstPass = false;
}
for (int i = 0; i < Fields.Length; i++)
{
if (Fields[i] == "")
{
Fields[i] = null;
}
}
dt.Rows.Add(Fields);
}
MethodResult = dt;
}
catch (Exception ex)
{
ex.HandleException();
}
return MethodResult;
}
如果您像我一样从报告服务中保存,那么您应该像这样使用它:
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string filenameExtension;
byte[] bytes = rvMain.ServerReport.Render("csv", null, out mimeType, out encoding, out filenameExtension, out streamids, out warnings);
string CsvBody = System.Text.Encoding.UTF8.GetString(bytes);
DataTable dt = GetDataTableFromCsvString(CsvBody,true);
否则,您只需:
bool IsHeadings = true; //Does the data include a heading row?
DataTable dt = GetDataTableFromCsvString(CsvBody, IsHeadings);
或者直接从 csv 文件中使用
bool IsHeadings = true; //Does the data include a heading row?
DataTable dt = GetDataTabletFromCsvFile(FilePath, IsHeadings)
或者使用远程存储的 csv 文件
bool IsHeadings = true; //Does the data include a heading row?
DataTable dt = GetDataTabletFromRemoteCsv(Url, IsHeadings)
【讨论】:
试试Filehelpers。它将帮助您将数据以及强类型对象放入数据表中
【讨论】:
FastCsvReader on code-project 做得很好; IIRC 它应该是:
var table = new DataTable();
using(var reader = new CsvReader(path)) {
table.Load(reader);
}
(但那是凭记忆)
【讨论】:
Microsoft 论坛上有 a thread about this,它使用 CSV 文件的数据连接字符串,这可能是最简单/最快的方法。
或者,您可以一次读取一行文件并为每一行创建一个 DataRow,将其添加到 DataTable。这是更多的手动工作,可能需要您对文件做出假设(列数、列名、数据类型等),但如果它只是针对一个已知文件,那么这应该不是什么大问题。
【讨论】: