專案需求:從 Excel/CSV 匯入 DataTable 顯示於 DataGridView,並支援右鍵另存為 CSV。利用 OLEDB Provider 將 Excel/CSV 視為資料來源,配合 StreamWriter 輸出 CSV,達成雙向轉換。
public static DataTable CsvToDataTable(string filePath) {
string connStr;
if (filePath.EndsWith(".csv")) {
string dir = Path.GetDirectoryName(filePath);
string file = Path.GetFileName(filePath);
connStr = $@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={dir};Extended Properties='TEXT;HDR=Yes;FMT=Delimited;'";
// 注意:CSV 需指定目錄而非檔案,Extended Properties 設定標題列、分隔符
} else {
connStr = $@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filePath};Extended Properties='Excel 8.0;'";
}
using (var conn = new OleDbConnection(connStr)) {
conn.Open();
var schema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
if (schema == null || schema.Rows.Count == 0) return null;
string tableName = schema.Rows[0]["TABLE_NAME"].ToString();
if (filePath.EndsWith(".csv")) tableName = Path.GetFileName(filePath); // CSV 表名即檔名
string sql = $"SELECT * FROM [{tableName}]";
using (var cmd = new OleDbCommand(sql, conn))
using (var adapter = new OleDbDataAdapter(cmd)) {
var ds = new DataSet();
adapter.Fill(ds);
return ds.Tables[0];
}
}
}
Extended Properties 宣告格式。HDR=Yes 表示第一列為標題。GetOleDbSchemaTable 取得第一個工作表/檔案名稱。public static void DataTableToCsv(DataTable table, string filePath) {
using (var fs = new FileStream(filePath, FileMode.Create))
using (var sw = new StreamWriter(new BufferedStream(fs), Encoding.Default)) {
// 標題列
var header = string.Join(",", table.Columns.Cast().Select(c => c.ColumnName));
sw.WriteLine(header);
// 資料列
foreach (DataRow row in table.Rows) {
var line = string.Join(",", row.ItemArray.Select(v => v.ToString()));
sw.WriteLine(line);
}
}
}
TextFieldParser 或第三方 CsvHelper。Microsoft.ACE.OLEDB.12.0 Provider。輕量級匯入匯出、無需 Office 安裝、跨平台相容性佳(CSV 為純文字)。