1
我想解析一個CSV並構造出一個DataTable。現在棘手的部分是我想在構建數據表之前分配數據類型。 對於例如考慮下面的CSV文件解析CSV文件的類型
Name,Age,Salary
A,30,1000
B,35,1500
C,40,2000
我想有名稱存儲爲字符串,年齡爲INT和薪資在我構建的數據表小數。任何建議最好的方式來做到這一點?
我想解析一個CSV並構造出一個DataTable。現在棘手的部分是我想在構建數據表之前分配數據類型。 對於例如考慮下面的CSV文件解析CSV文件的類型
Name,Age,Salary
A,30,1000
B,35,1500
C,40,2000
我想有名稱存儲爲字符串,年齡爲INT和薪資在我構建的數據表小數。任何建議最好的方式來做到這一點?
這裏有一個天真的實現,它忽略了大多數錯誤檢查,以及一些好的編碼做法:
namespace StackOverflowConsole
{
using System;
using System.IO;
using System.Data;
class Program
{
static void Main(string[] args)
{
var path = @"C:\temp\test.csv";
CreateTestFile(path);
var dataTable = new DataTable();
dataTable.Columns.Add("Name", typeof(string));
dataTable.Columns.Add("Age", typeof(int));
dataTable.Columns.Add("Salary", typeof(decimal));
// TODO: add checks, exception handling
using (var reader = new StreamReader(path))
{
// reads all lines into a single string
var lines = reader.ReadToEnd().Split(new char[] { '\n' });
if (lines.Length > 0)
{
// you may wanna skip the first line, if you're using a file header
foreach (string line in lines)
{
if (string.IsNullOrWhiteSpace(line))
{
continue;
}
// split the current line using the separator
var tokens = line.Trim().Split(new char[] { ',' });
// check your assumptions on the CSV contents
// ex: only process lines with the correct number of fields
if (tokens.Length == 3)
{
var person = new Person();
person.Name = tokens[0];
// a better implementation would use TryParse()
person.Age = Int32.Parse(tokens[1]);
person.Salary = Decimal.Parse(tokens[2]);
dataTable.Rows.Add(person.Name, person.Age, person.Salary);
}
}
}
}
}
private static void CreateTestFile(string path)
{
if (File.Exists(path))
{
File.Delete(path);
}
using (var writer = new StreamWriter(path))
{
writer.WriteLine("A,30,1000");
writer.WriteLine("B,35,1500");
writer.WriteLine("C,40,2000");
}
}
}
public class Person
{
public string Name;
public int Age;
public decimal Salary;
}
}
試試這個:
保持CSV文件中的代碼目錄
string path = Server.MapPath("emp.csv");
string header = "Yes";
string sql = string.Empty;
DataTable dt = null;
string fullpath = Path.GetDirectoryName(path);
string fileName = Path.GetFileName(path);
OleDbConnection connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + fullpath + ";Extended Properties=\"Text;HDR=" + header + "\"");
OleDbDataAdapter da = new OleDbDataAdapter("select * from [" + fileName + "]", connection);
dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Age", typeof(int));
dt.Columns.Add("Salary", typeof(decimal));
da.Fill(dt);
GridView1.DataSource = dt;
GridView1.DataBind();
怎麼可能程序區分'30'和'1000',並將前者看作int,將後者看作decimal。在提供其他一些信息之前,這是無法完成的。例如列名和數據類型之間的映射。 – 2012-02-03 05:41:59
如果你可以使用oledb。你可以使用schema.ini來定義列類型。檢查這個http://stackoverflow.com/questions/8683180/data-error-when-reading-csv-file-in-c-sharp-winforms/8683365#8683365 – 2012-02-03 05:44:40
謝謝Shoaib。它以我想要的方式工作。 Schema.ini是答案。 – Nishant 2012-02-03 08:30:45