Bagaimana ini mungkin 'di luar topik'? Ini pertanyaan khusus dan 100 orang merasa berguna
Ryan
10
@Ryan: Sesungguhnya aku berkata kepadamu ... StackOverflow moderator adalah induk dari ular berbisa. Dapatkan di belakang saya, moderator StackOverflow!
Ronnie Overby
Jawaban:
89
Berikut adalah kelas yang sangat baik yang akan menyalin data CSV ke dalam datatable menggunakan struktur data untuk membuat DataTable:
Sangat bagus. Ini bekerja dengan baik bagi saya di luar kotak, bahkan tanpa membaca dokumentasi.
Senyum
Apakah ini akan berfungsi pada file CSV di mana setiap baris mungkin memiliki struktur yang berbeda? Saya memiliki file log dengan berbagai jenis acara log yang perlu dipisahkan menjadi beberapa tabel.
gonzobrains
2
@gonzobrains - Mungkin tidak; asumsi dasar file CSV adalah struktur data persegi panjang berdasarkan satu set header kolom yang ditentukan pada baris pertama. Apa yang Anda miliki tampaknya lebih umum dibatasi koma, data terdiskriminasi, membutuhkan "ETL" yang lebih canggih untuk mem-parsing dari file ke instance objek dari berbagai jenis (yang dapat mencakup DataRows dari berbagai Tabel Data).
KeithS
93
Saya telah menggunakan OleDbprovider. Namun, itu memiliki masalah jika Anda membaca dalam baris yang memiliki nilai numerik tetapi Anda ingin mereka diperlakukan sebagai teks. Namun, Anda dapat mengatasi masalah itu dengan membuat schema.inifile. Inilah metode yang saya gunakan:
// using System.Data;// using System.Data.OleDb;// using System.Globalization;// using System.IO;staticDataTableGetDataTableFromCsv(string path,bool isFirstRowHeader){string header = isFirstRowHeader ?"Yes":"No";string pathOnly =Path.GetDirectoryName(path);string fileName =Path.GetFileName(path);string sql =@"SELECT * FROM ["+ fileName +"]";
using(OleDbConnection connection =newOleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+ pathOnly +";Extended Properties=\"Text;HDR="+ header +"\""))
using(OleDbCommand command =newOleDbCommand(sql, connection))
using(OleDbDataAdapter adapter =newOleDbDataAdapter(command)){DataTable dataTable =newDataTable();
dataTable.Locale=CultureInfo.CurrentCulture;
adapter.Fill(dataTable);return dataTable;}}
Terimakasih kawan. Itu membantu saya. Saya memiliki file CSV di mana koma bukan hanya pemisah, mereka ada di mana-mana di dalam banyak nilai kolom, jadi membuat regex yang akan membagi garis agak sulit. OleDbProvider menyimpulkan skema dengan benar.
Galilyou
Implementasinya masuk akal tetapi bagaimana kita menangani sel yang berisi tipe data campuran. Misalnya, 40C dan lain-lain?
GKED
GKED, jika data yang Anda baca selalu memiliki kumpulan kolom dan jenis yang Anda harapkan, Anda dapat menempatkan di folder yang sama file shema.ini yang memberi tahu informasi penyedia OleDb tentang kolom. Berikut ini adalah tautan ke artikel Microsoft yang menyediakan detail tentang bagaimana menyusun file. msdn.microsoft.com/en-us/library/…
Jim Scott
4
Sementara jawaban ini akan berhasil, saya akan sangat menyarankan untuk tidak melakukannya. Anda memperkenalkan ketergantungan eksternal yang mungkin bertentangan dengan instalasi kantor lainnya pada mesin yang sama (menggunakan Excel di lingkungan pengembang lokal Anda?), Tergantung pada versi yang diinstal. Ada paket NuGet di luar sana (ExcelDataReader, CsvHelper) yang melakukan ini dengan cara yang lebih efisien dan lebih portabel.
A. Murray
1
@ A.Murray - Apa maksud Anda sebenarnya? Ini menggunakan penyedia OleDb bawaan di System.Data.dll. Anda tidak perlu menginstal "driver" tambahan. Dan saya akan terkejut pada hari ini dan usia jika instalasi windows tidak memiliki driver Jet dasar diinstal. Ini CSV tahun 1990 ....
Saran Jay Riggs juga merupakan solusi yang hebat, tetapi saya tidak membutuhkan semua fitur yang disediakan Generic Parser dari Andrew Rissing .
UPDATE 10/25/2010
Setelah menggunakan Pembaca Csv Sebastien Lorion dalam proyek saya selama hampir satu setengah tahun, saya telah menemukan bahwa ia melempar pengecualian ketika mem-parsing beberapa file csv yang saya yakini terbentuk dengan baik.
var csv =@"Name, Age
Ronnie, 30
Mark, 40
Ace, 50";TextReader reader =newStringReader(csv);var table =newDataTable();
using(var it = reader.ReadCsvWithHeader().GetEnumerator()){if(!it.MoveNext())return;foreach(var k in it.Current.Keys)
table.Columns.Add(k);do{var row = table.NewRow();foreach(var k in it.Current.Keys)
row[k]= it.Current[k];
table.Rows.Add(row);}while(it.MoveNext());}
Saya setuju bahwa pembaca CSV Sebastien Lorien hebat. Saya menggunakannya untuk pemrosesan CSV yang berat, tetapi saya juga menggunakan Andrew's Rissing untuk pekerjaan kecil dan ini sangat membantu saya. Selamat bersenang-senang!
Jay Riggs
Bagaimana saya bisa menggunakan kelas ini untuk memuat CSV ke DATATABLE?
Muflix
Saya mencoba ini tetapi koleksi it.Current.Keys kembali dengan "System.Linq.Enumerable + WhereSelectListIterator`2 [System.Int32, System.Char]" daripada nama kolom. Ada pemikiran mengapa?
user3658298
Bisakah Anda menggunakan pembatas multi-karakter?
menggulung
Tidak, tapi saya berpikir untuk mengaktifkannya.
Ronnie Overby
32
Hei ini bekerja 100%
publicstaticDataTableConvertCSVtoDataTable(string strFilePath){DataTable dt =newDataTable();
using (StreamReader sr =newStreamReader(strFilePath)){string[] headers = sr.ReadLine().Split(',');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);}}return dt;}
@ShivamSrivastava Saya mendapatkan kesalahan di baris terakhir apakah Anda di sana kemudian memberi Anda info kontak lainnya
Sunil Acharya
Meskipun saya tidak menggunakan versi ini persis, itu didasarkan pada itu saya menyelesaikan masalah saya. Terima kasih. Bekerja dengan sangat baik.
nrod
13
Kami selalu menggunakan driver Jet.OLEDB, sampai kami mulai membuka aplikasi 64 bit. Microsoft belum dan tidak akan merilis driver Jet 64 bit. Berikut ini adalah solusi sederhana yang kami buat dengan menggunakan File.ReadAllLines dan String.Split untuk membaca dan mem-parsing file CSV dan secara manual memuat DataTable. Seperti disebutkan di atas, itu TIDAK menangani situasi di mana salah satu nilai kolom berisi koma. Kami menggunakan ini sebagian besar untuk membaca file konfigurasi khusus - bagian yang menyenangkan tentang menggunakan file CSV adalah kami dapat mengeditnya di Excel.
stringCSVFilePathName=@"C:\test.csv";string[]Lines=File.ReadAllLines(CSVFilePathName);string[]Fields;Fields=Lines[0].Split(newchar[]{','});intCols=Fields.GetLength(0);DataTable dt =newDataTable();//1st row must be column names; force lower case to ensure matching later on.for(int i =0; i <Cols; i++)
dt.Columns.Add(Fields[i].ToLower(),typeof(string));DataRowRow;for(int i =1; i <Lines.GetLength(0); i++){Fields=Lines[i].Split(newchar[]{','});Row= dt.NewRow();for(int f =0; f <Cols; f++)Row[f]=Fields[f];
dt.Rows.Add(Row);}
ini adalah kode yang saya gunakan tetapi aplikasi Anda harus berjalan dengan versi net 3.5
privatevoid txtRead_Click(object sender,EventArgs e){// var filename = @"d:\shiptest.txt";
openFileDialog1.InitialDirectory="d:\\";
openFileDialog1.Filter="txt files (*.txt)|*.txt|All files (*.*)|*.*";DialogResult result = openFileDialog1.ShowDialog();if(result ==DialogResult.OK){if(openFileDialog1.FileName!=""){var reader =ReadAsLines(openFileDialog1.FileName);var data =newDataTable();//this assume the first record is filled with the column namesvar headers = reader.First().Split(',');foreach(var header in headers){
data.Columns.Add(header);}var records = reader.Skip(1);foreach(var record in records){
data.Rows.Add(record.Split(','));}
dgList.DataSource= data;}}}staticIEnumerable<string>ReadAsLines(string filename){
using (StreamReader reader =newStreamReader(filename))while(!reader.EndOfStream)yieldreturn reader.ReadLine();}
Saya menemukan potongan kode ini yang menggunakan Linq dan regex untuk mem-parsing file CSV. Artikel referensi sekarang sudah berusia lebih dari satu setengah tahun, tetapi belum menemukan cara yang lebih rapi untuk mem-parsing CSV menggunakan Linq (dan regex) daripada ini. Peringatannya adalah regex yang diterapkan di sini adalah untuk file yang dibatasi koma (akan mendeteksi tanda koma di dalam tanda kutip!) Dan mungkin tidak perlu dengan baik untuk header, tetapi ada cara untuk mengatasi ini). Ambil puncak:
Dim lines AsString()=System.IO.File.ReadAllLines(strCustomerFile)Dim pattern AsString=",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))"Dim r AsSystem.Text.RegularExpressions.Regex=NewSystem.Text.RegularExpressions.Regex(pattern)Dim custs =From line In lines _
Let data = r.Split(line) _
SelectNewWith{.custnmbr = data(0), _
.custname = data(1)}ForEach cust In custs
strCUSTNMBR =Replace(cust.custnmbr,Chr(34),"")
strCUSTNAME =Replace(cust.custname,Chr(34),"")Next
Opsi terbaik yang saya temukan, dan itu menyelesaikan masalah di mana Anda mungkin memiliki versi Office yang berbeda diinstal, dan juga masalah 32/64-bit seperti yang disebutkan Chuck Bevitt , adalah FileHelpers .
Itu dapat ditambahkan ke referensi proyek Anda menggunakan NuGet dan itu memberikan solusi satu-liner:
bisakah kamu tahu apa itu CommonEngine? Apakah NuGet sama dengan NuGet.Core. Saya hanya menemukan NuGet.Core dalam referensi
sindhu jampani
FileHelpers yang Anda butuhkan. Jika Anda memiliki NuGet, tambahkan dengan NuGet. Jika tidak, tambahkan saja sebagai rakitan di proyek Anda. CommonEngine adalah bagian dari FileHelpers.
Neo
3
Bagi Anda yang ingin tidak menggunakan perpustakaan eksternal, dan memilih untuk tidak menggunakan OleDB, lihat contoh di bawah ini. Semua yang saya temukan adalah OleDB, perpustakaan eksternal, atau hanya pemisahan berdasarkan koma! Untuk kasus saya OleDB tidak berfungsi jadi saya ingin sesuatu yang berbeda.
Saya menemukan sebuah artikel oleh MarkJ yang mereferensikan metode Microsoft.VisualBasic.FileIO.TextFieldParser seperti yang terlihat di sini . Artikel ini ditulis dalam VB dan tidak menghasilkan data, jadi lihat contoh saya di bawah ini.
publicstaticDataTableLoadCSV(string path,bool hasHeader){DataTable dt =newDataTable();
using (varMyReader=newMicrosoft.VisualBasic.FileIO.TextFieldParser(path)){MyReader.TextFieldType=Microsoft.VisualBasic.FileIO.FieldType.Delimited;MyReader.Delimiters=newString[]{","};string[] currentRow;//'Loop through all of the fields in the file. //'If any lines are corrupt, report an error and continue parsing. bool firstRow =true;while(!MyReader.EndOfData){try{
currentRow =MyReader.ReadFields();//Add the header columnsif(hasHeader && firstRow){foreach(string c in currentRow){
dt.Columns.Add(c,typeof(string));}
firstRow =false;continue;}//Create a new rowDataRow dr = dt.NewRow();
dt.Rows.Add(dr);//Loop thru the current line and fill the data outfor(int c =0; c < currentRow.Count(); c++){
dr[c]= currentRow[c];}}catch(Microsoft.VisualBasic.FileIO.MalformedLineException ex){//Handle the exception here}}}return dt;}
Jawaban yang sangat mendasar: jika Anda tidak memiliki csv kompleks yang dapat menggunakan fungsi pemisahan sederhana ini akan berfungsi dengan baik untuk mengimpor (perhatikan impor ini sebagai string, saya melakukan konversi datatype nanti jika saya perlu)
privateDataTable csvToDataTable(string fileName,char splitCharacter){StreamReader sr =newStreamReader(fileName);string myStringRow = sr.ReadLine();var rows = myStringRow.Split(splitCharacter);DataTableCsvData=newDataTable();foreach(string column in rows){//creates the columns of new datatable based on first row of csvCsvData.Columns.Add(column);}
myStringRow = sr.ReadLine();while(myStringRow !=null){//runs until string reader returns null and adds rows to dt
rows = myStringRow.Split(splitCharacter);CsvData.Rows.Add(rows);
myStringRow = sr.ReadLine();}
sr.Close();
sr.Dispose();returnCsvData;}
Metode saya jika saya mengimpor tabel dengan pemisah string [] dan menangani masalah di mana baris saat ini yang saya baca mungkin telah pergi ke baris berikutnya dalam file csv atau teks <- DALAM hal ini saya ingin mengulang sampai saya mendapatkan ke jumlah total baris di baris pertama (kolom)
publicstaticDataTableImportCSV(string fullPath,string[] sepString){DataTable dt =newDataTable();
using (StreamReader sr =newStreamReader(fullPath)){//stream uses using statement because it implements iDisposablestring firstLine = sr.ReadLine();var headers = firstLine.Split(sepString,StringSplitOptions.None);foreach(var header in headers){//create column headers
dt.Columns.Add(header);}int columnInterval = headers.Count();string newLine = sr.ReadLine();while(newLine !=null){//loop adds each row to the datatablevar fields = newLine.Split(sepString,StringSplitOptions.None);// csv delimiter var currentLength = fields.Count();if(currentLength < columnInterval){while(currentLength < columnInterval){//if the count of items in the row is less than the column row go to next line until count matches column number total
newLine += sr.ReadLine();
currentLength = newLine.Split(sepString,StringSplitOptions.None).Count();}
fields = newLine.Split(sepString,StringSplitOptions.None);}if(currentLength > columnInterval){//ideally never executes - but if csv row has too many separators, line is skipped
newLine = sr.ReadLine();continue;}
dt.Rows.Add(fields);
newLine = sr.ReadLine();}
sr.Close();}return dt;}
Bagusnya Anda belum mendeklarasikan baris sebagai string [].
Gaya Hewan
@AnimalStyle Anda benar - diperbarui dengan metode yang lebih kuat dan baris yang dideklarasikan
Matt Farguson
3
Diubah dari Bp ChuckBevitt
Solusi kerja:
stringCSVFilePathName= APP_PATH +"Facilities.csv";string[]Lines=File.ReadAllLines(CSVFilePathName);string[]Fields;Fields=Lines[0].Split(newchar[]{','});intCols=Fields.GetLength(0);DataTable dt =newDataTable();//1st row must be column names; force lower case to ensure matching later on.for(int i =0; i <Cols-1; i++)
dt.Columns.Add(Fields[i].ToLower(),typeof(string));DataRowRow;for(int i =0; i <Lines.GetLength(0)-1; i++){Fields=Lines[i].Split(newchar[]{','});Row= dt.NewRow();for(int f =0; f <Cols-1; f++)Row[f]=Fields[f];
dt.Rows.Add(Row);}
Jadi ini memecahkan masalah memori bukan? Ini adalah pemrosesan baris demi baris dan tidak bertahan dalam memori sehingga tidak boleh ada pengecualian? Saya suka cara ini diproses tetapi tidak File.ReadAllLines () menyimpan semua ke dalam memori? Saya pikir Anda seharusnya menggunakan File.ReadLines () untuk menghindari buffer memori yang besar? Ini adalah jawaban yang bagus untuk pertanyaan yang ada. Saya hanya ingin tahu tentang masalah ingatan.
DtechNet
2
Inilah solusi yang menggunakan driver teks ODBC ADO.Net:
Dim csvFileFolder AsString="C:\YourFileFolder"Dim csvFileName AsString="YourFile.csv"'Note that the folder is specified in the connection string,'not the file. That's specified in the SELECT query, later.Dim connString AsString="Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=" _
& csvFileFolder &";Extended Properties=""Text;HDR=No;FMT=Delimited"""Dim conn AsNewOdbc.OdbcConnection(connString)'Open a data adapter, specifying the file name to load
Dim da AsNewOdbc.OdbcDataAdapter("SELECT * FROM ["& csvFileName &"]", conn)'Then fill a data table, which can be bound to a grid
Dim dt AsNewDataTableda.Fill(dt)
grdCSVData.DataSource= dt
Setelah diisi, Anda dapat menilai properti yang bisa datatable, seperti ColumnName, untuk memanfaatkan semua kekuatan objek data ADO.Net.
Dalam VS2008 Anda dapat menggunakan Linq untuk mencapai efek yang sama.
CATATAN: Ini mungkin duplikat dari pertanyaan SO ini .
privatestaticDataTableLoadCsvData(string refPath){var cfg =newConfiguration(){Delimiter=",",HasHeaderRecord=true};var result =newDataTable();
using (var sr =newStreamReader(refPath,Encoding.UTF8,false,16384*2)){
using (var rdr =newCsvReader(sr, cfg))
using (var dataRdr =newCsvDataReader(rdr)){
result.Load(dataRdr);}}return result;}
Perhatikan bahwa dalam rilis 13Configuration diubah namanya menjadi CsvConfigurationuntuk menghindari konflik namespace. Demo jawaban ini berfungsi: dotnetfiddle.net/sdwc6i
dbc
2
Saya menggunakan perpustakaan bernama ExcelDataReader, Anda dapat menemukannya di NuGet. Pastikan untuk menginstal ekstensi ExcelDataReader dan ExcelDataReader.DataSet (yang terakhir menyediakan metode AsDataSet yang diperlukan yang dirujuk di bawah).
Saya merangkum semuanya dalam satu fungsi, Anda dapat menyalinnya dalam kode Anda secara langsung. Berikan path ke file CSV, itu memberi Anda dataset dengan satu tabel.
publicstaticDataSetGetDataSet(string filepath){var stream =File.OpenRead(filepath);try{var reader =ExcelReaderFactory.CreateCsvReader(stream,newExcelReaderConfiguration(){LeaveOpen=false});var result = reader.AsDataSet(newExcelDataSetConfiguration(){// Gets or sets a value indicating whether to set the DataColumn.DataType // property in a second pass.UseColumnDataType=true,// Gets or sets a callback to determine whether to include the current sheet// in the DataSet. Called once per sheet before ConfigureDataTable.FilterSheet=(tableReader, sheetIndex)=>true,// Gets or sets a callback to obtain configuration options for a DataTable. ConfigureDataTable=(tableReader)=>newExcelDataTableConfiguration(){// Gets or sets a value indicating the prefix of generated column names.EmptyColumnNamePrefix="Column",// Gets or sets a value indicating whether to use a row from the // data as column names.UseHeaderRow=true,// Gets or sets a callback to determine which row is the header row. // Only called when UseHeaderRow = true.ReadHeaderRow=(rowReader)=>{// F.ex skip the first row and use the 2nd row as column headers://rowReader.Read();},// Gets or sets a callback to determine whether to include the // current row in the DataTable.FilterRow=(rowReader)=>{returntrue;},// Gets or sets a callback to determine whether to include the specific// column in the DataTable. Called once per column after reading the // headers.FilterColumn=(rowReader, columnIndex)=>{returntrue;}}});return result;}catch(Exception ex){returnnull;}finally{
stream.Close();
stream.Dispose();}}
Ini tahun 2020 dan ini adalah solusi hebat dibandingkan dengan beberapa jawaban lama di sini. Ini dikemas dengan baik dan menggunakan perpustakaan populer dan ringan dari NuGet. Dan fleksibel - jika CSV Anda ada di memori, cukup letakkan sebagai MemoryStreamganti jalur file. DataTable yang diminta OP mudah diekstraksi dari DataSet seperti ini:result.Tables[0]
Tawab Wakil
1
Cukup membagikan metode ekstensi ini, saya harap ini dapat membantu seseorang.
publicstaticList<string>ToCSV(thisDataSet ds,char separator ='|'){List<string> lResult =newList<string>();foreach(DataTable dt in ds.Tables){StringBuilder sb =newStringBuilder();IEnumerable<string> columnNames = dt.Columns.Cast<DataColumn>().Select(column => column.ColumnName);
sb.AppendLine(string.Join(separator.ToString(), columnNames));foreach(DataRow row in dt.Rows){IEnumerable<string> fields = row.ItemArray.Select(field =>string.Concat("\"", field.ToString().Replace("\"","\"\""),"\""));
sb.AppendLine(string.Join(separator.ToString(), fields));}
lResult.Add(sb.ToString());}return lResult;}publicstaticDataSetCSVtoDataSet(thisList<string> collectionCSV,char separator ='|'){var ds =newDataSet();foreach(var csv in collectionCSV){var dt =newDataTable();var readHeader =false;foreach(var line in csv.Split(new[]{Environment.NewLine},StringSplitOptions.None)){if(!readHeader){foreach(var c in line.Split(separator))
dt.Columns.Add(c);}else{
dt.Rows.Add(line.Split(separator));}}
ds.Tables.Add(dt);}return ds;}
Menggunakan pustaka ini untuk memuat DataTablesangat mudah.
using var tr =File.OpenText("data.csv");
using var dr =CsvDataReader.Create(tr);var dt =newDataTable();
dt.Load(dr);
Dengan asumsi file Anda adalah file standar yang dipisahkan koma dengan header, itu saja yang Anda butuhkan. Ada juga opsi untuk memungkinkan membaca file tanpa header, dan menggunakan pembatas alternatif dll.
Dimungkinkan juga untuk menyediakan skema khusus untuk file CSV sehingga kolom dapat diperlakukan sebagai sesuatu selain stringnilai. Ini akan memungkinkan DataTablekolom untuk dimuat dengan nilai-nilai yang dapat lebih mudah untuk dikerjakan, karena Anda tidak perlu memaksa mereka ketika Anda mengaksesnya.
var schema =newTypedCsvSchema();
schema.Add(0,typeof(int));
schema.Add(1,typeof(string));
schema.Add(2,typeof(double?));
schema.Add(3,typeof(DateTime));
schema.Add(4,typeof(DateTime?));var options =newCsvDataReaderOptions{Schema= schema
};
using var tr =GetData();
using var dr =CsvDataReader.Create(tr, options);
TypedCsvSchemaadalah implementasi ICsvSchemaProvideryang menyediakan cara sederhana untuk menentukan jenis kolom. Namun, juga memungkinkan untuk memberikan kebiasaan ICsvSchemaProvidersaat Anda ingin memberikan lebih banyak metadata, seperti keunikan atau ukuran kolom terbatas, dll.
Jawaban:
Berikut adalah kelas yang sangat baik yang akan menyalin data CSV ke dalam datatable menggunakan struktur data untuk membuat DataTable:
Pengurai generik portabel dan efisien untuk file datar
Mudah dikonfigurasikan dan mudah digunakan. Saya mendorong Anda untuk melihatnya.
sumber
Saya telah menggunakan
OleDb
provider. Namun, itu memiliki masalah jika Anda membaca dalam baris yang memiliki nilai numerik tetapi Anda ingin mereka diperlakukan sebagai teks. Namun, Anda dapat mengatasi masalah itu dengan membuatschema.ini
file. Inilah metode yang saya gunakan:sumber
Saya telah memutuskan untuk menggunakan Csv Reader Sebastien Lorion .
Saran Jay Riggs juga merupakan solusi yang hebat, tetapi saya tidak membutuhkan semua fitur yang disediakan Generic Parser dari Andrew Rissing .
UPDATE 10/25/2010
Setelah menggunakan Pembaca Csv Sebastien Lorion dalam proyek saya selama hampir satu setengah tahun, saya telah menemukan bahwa ia melempar pengecualian ketika mem-parsing beberapa file csv yang saya yakini terbentuk dengan baik.
Jadi, saya beralih ke Generic Parser karya Andrew Rissing dan sepertinya akan jauh lebih baik.
UPDATE 9/22/2014
Saat ini, saya lebih banyak menggunakan metode ekstensi ini untuk membaca teks yang dibatasi:
https://github.com/Core-Techs/Common/blob/master/CoreTechs.Common/Text/DelimitedTextExtensions.cs#L22
https://www.nuget.org/packages/CoreTechs.Common/
UPDATE 2/20/2015
Contoh:
sumber
Hei ini bekerja 100%
Gambar CSV
Tabel data Diimpor
sumber
Kami selalu menggunakan driver Jet.OLEDB, sampai kami mulai membuka aplikasi 64 bit. Microsoft belum dan tidak akan merilis driver Jet 64 bit. Berikut ini adalah solusi sederhana yang kami buat dengan menggunakan File.ReadAllLines dan String.Split untuk membaca dan mem-parsing file CSV dan secara manual memuat DataTable. Seperti disebutkan di atas, itu TIDAK menangani situasi di mana salah satu nilai kolom berisi koma. Kami menggunakan ini sebagian besar untuk membaca file konfigurasi khusus - bagian yang menyenangkan tentang menggunakan file CSV adalah kami dapat mengeditnya di Excel.
sumber
ini adalah kode yang saya gunakan tetapi aplikasi Anda harus berjalan dengan versi net 3.5
sumber
Anda dapat mencapainya dengan menggunakan Microsoft.VisualBasic.FileIO.TextFieldParser dll di C #
sumber
sumber
Saya menemukan potongan kode ini yang menggunakan Linq dan regex untuk mem-parsing file CSV. Artikel referensi sekarang sudah berusia lebih dari satu setengah tahun, tetapi belum menemukan cara yang lebih rapi untuk mem-parsing CSV menggunakan Linq (dan regex) daripada ini. Peringatannya adalah regex yang diterapkan di sini adalah untuk file yang dibatasi koma (akan mendeteksi tanda koma di dalam tanda kutip!) Dan mungkin tidak perlu dengan baik untuk header, tetapi ada cara untuk mengatasi ini). Ambil puncak:
sumber
Opsi terbaik yang saya temukan, dan itu menyelesaikan masalah di mana Anda mungkin memiliki versi Office yang berbeda diinstal, dan juga masalah 32/64-bit seperti yang disebutkan Chuck Bevitt , adalah FileHelpers .
Itu dapat ditambahkan ke referensi proyek Anda menggunakan NuGet dan itu memberikan solusi satu-liner:
sumber
Bagi Anda yang ingin tidak menggunakan perpustakaan eksternal, dan memilih untuk tidak menggunakan OleDB, lihat contoh di bawah ini. Semua yang saya temukan adalah OleDB, perpustakaan eksternal, atau hanya pemisahan berdasarkan koma! Untuk kasus saya OleDB tidak berfungsi jadi saya ingin sesuatu yang berbeda.
Saya menemukan sebuah artikel oleh MarkJ yang mereferensikan metode Microsoft.VisualBasic.FileIO.TextFieldParser seperti yang terlihat di sini . Artikel ini ditulis dalam VB dan tidak menghasilkan data, jadi lihat contoh saya di bawah ini.
sumber
Jawaban yang sangat mendasar: jika Anda tidak memiliki csv kompleks yang dapat menggunakan fungsi pemisahan sederhana ini akan berfungsi dengan baik untuk mengimpor (perhatikan impor ini sebagai string, saya melakukan konversi datatype nanti jika saya perlu)
Metode saya jika saya mengimpor tabel dengan pemisah string [] dan menangani masalah di mana baris saat ini yang saya baca mungkin telah pergi ke baris berikutnya dalam file csv atau teks <- DALAM hal ini saya ingin mengulang sampai saya mendapatkan ke jumlah total baris di baris pertama (kolom)
sumber
Diubah dari Bp ChuckBevitt
Solusi kerja:
sumber
Inilah solusi yang menggunakan driver teks ODBC ADO.Net:
Setelah diisi, Anda dapat menilai properti yang bisa datatable, seperti ColumnName, untuk memanfaatkan semua kekuatan objek data ADO.Net.
Dalam VS2008 Anda dapat menggunakan Linq untuk mencapai efek yang sama.
CATATAN: Ini mungkin duplikat dari pertanyaan SO ini .
sumber
Tidak dapat menahan menambahkan putaran saya sendiri ke ini. Ini jauh lebih baik dan lebih kompak daripada apa yang saya gunakan di masa lalu.
Solusi ini:
Inilah yang saya pikirkan:
Itu tergantung pada metode ekstensi (
Unique
) untuk menangani nama kolom duplikat yang akan ditemukan sebagai jawaban saya di Cara menambahkan nomor unik ke daftar stringDan inilah
BlankToNothing
fungsi pembantu:sumber
Dengan Cinchoo ETL - pustaka sumber terbuka, Anda dapat dengan mudah mengkonversi file CSV ke DataTable dengan beberapa baris kode.
Untuk informasi lebih lanjut, silakan kunjungi proyek kode artikel .
Semoga ini bisa membantu.
sumber
menggunakan: https://joshclose.github.io/CsvHelper/
sumber
Configuration
diubah namanya menjadiCsvConfiguration
untuk menghindari konflik namespace. Demo jawaban ini berfungsi: dotnetfiddle.net/sdwc6iSaya menggunakan perpustakaan bernama ExcelDataReader, Anda dapat menemukannya di NuGet. Pastikan untuk menginstal ekstensi ExcelDataReader dan ExcelDataReader.DataSet (yang terakhir menyediakan metode AsDataSet yang diperlukan yang dirujuk di bawah).
Saya merangkum semuanya dalam satu fungsi, Anda dapat menyalinnya dalam kode Anda secara langsung. Berikan path ke file CSV, itu memberi Anda dataset dengan satu tabel.
sumber
MemoryStream
ganti jalur file. DataTable yang diminta OP mudah diekstraksi dari DataSet seperti ini:result.Tables[0]
Cukup membagikan metode ekstensi ini, saya harap ini dapat membantu seseorang.
sumber
Gunakan ini, satu fungsi menyelesaikan semua masalah koma dan kutipan:
sumber
sumber
Saya baru-baru ini menulis parser CSV untuk .NET yang saya klaim saat ini adalah yang tercepat yang tersedia sebagai paket nuget : Sylvan.Data.Csv .
Menggunakan pustaka ini untuk memuat
DataTable
sangat mudah.Dengan asumsi file Anda adalah file standar yang dipisahkan koma dengan header, itu saja yang Anda butuhkan. Ada juga opsi untuk memungkinkan membaca file tanpa header, dan menggunakan pembatas alternatif dll.
Dimungkinkan juga untuk menyediakan skema khusus untuk file CSV sehingga kolom dapat diperlakukan sebagai sesuatu selain
string
nilai. Ini akan memungkinkanDataTable
kolom untuk dimuat dengan nilai-nilai yang dapat lebih mudah untuk dikerjakan, karena Anda tidak perlu memaksa mereka ketika Anda mengaksesnya.TypedCsvSchema
adalah implementasiICsvSchemaProvider
yang menyediakan cara sederhana untuk menentukan jenis kolom. Namun, juga memungkinkan untuk memberikan kebiasaanICsvSchemaProvider
saat Anda ingin memberikan lebih banyak metadata, seperti keunikan atau ukuran kolom terbatas, dll.sumber