Excellent en effet. Cela a parfaitement fonctionné pour moi hors de la boîte, sans même lire la documentation.
Smirkingman
Cela fonctionnera-t-il sur les fichiers CSV où chaque ligne peut avoir une structure différente? J'ai un fichier journal avec différents types d'événements enregistrés qui devraient être séparés en plusieurs tables.
gonzobrains
2
@gonzobrains - Probablement pas; L'hypothèse de base d'un fichier CSV est une structure de données rectangulaire basée sur un seul ensemble d'en-têtes de colonne spécifié dans la première ligne. Ce que vous avez semble être des données plus génériques délimitées par des virgules et discriminées, nécessitant un «ETL» plus sophistiqué pour analyser le fichier en instances d'objet de différents types (qui pourraient inclure des DataRows de différents DataTables).
KeithS
93
J'utilise le OleDbfournisseur. Cependant, cela pose des problèmes si vous lisez des lignes contenant des valeurs numériques mais que vous souhaitez qu'elles soient traitées comme du texte. Cependant, vous pouvez contourner ce problème en créant un schema.inifichier. Voici ma méthode que j'ai utilisée:
// 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;}}
Merci mon pote. Cela m'a aidé. J'avais un fichier CSV dans lequel les virgules n'étaient pas seulement des séparateurs, elles étaient partout dans de nombreuses valeurs de colonnes, donc trouver une expression régulière qui diviserait la ligne était un peu difficile. OleDbProvider a correctement déduit le schéma.
Galilyou
L'implémentation a du sens, mais comment traiter les cellules contenant des types de données mixtes. Par exemple, 40C et etc.?
GKED
GKED, si les données que vous lisez ont toujours un ensemble attendu de colonnes et de types, vous pouvez placer dans le même dossier un fichier shema.ini qui indique les informations du fournisseur OleDb sur les colonnes. Voici un lien vers un article Microsoft qui fournit des détails sur la structure du fichier. msdn.microsoft.com/en-us/library/…
Jim Scott
4
Bien que cette réponse fonctionne, je vous déconseille fortement. Vous introduisez une dépendance externe qui peut entrer en conflit avec d'autres installations de bureau sur la même machine (utiliser Excel sur votre environnement de développement local?), En fonction des versions installées. Il existe des packages NuGet (ExcelDataReader, CsvHelper) qui le font de manière plus efficace et plus portable.
A. Murray
1
@ A.Murray - Que voulez-vous dire exactement? Cela utilise le fournisseur OleDb intégré dans System.Data.dll. Vous n'avez pas besoin d'installer de "pilotes" supplémentaires. Et je serais choqué à cette époque si une installation de Windows n'avait pas le pilote Jet de base installé. Ceci est le CSV des années 1990 ....
La suggestion de Jay Riggs est également une excellente solution, mais je n'avais tout simplement pas besoin de toutes les fonctionnalités fournies par Generic Parser d'Andrew Rissing .
MISE À JOUR 25/10/2010
Après avoir utilisé le lecteur Csv de Sébastien Lorion dans mon projet pendant près d'un an et demi, j'ai constaté qu'il lançait des exceptions lors de l'analyse de certains fichiers csv que je pense être bien formés.
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());}
Je suis d'accord que le lecteur CSV de Sébastien Lorien est génial. Je l'utilise pour le traitement CSV lourd, mais j'ai également utilisé Andrew's Rissing's pour les petits travaux et cela m'a bien servi. S'amuser!
Jay Riggs
Comment puis-je utiliser ces classes pour charger CSV dans DATATABLE?
Muflix
J'ai essayé cela mais la collection it.Current.Keys retourne avec "System.Linq.Enumerable + WhereSelectListIterator`2 [System.Int32, System.Char]" plutôt que le nom de la colonne. Des pensées sur pourquoi?
user3658298
Pouvez-vous utiliser des délimiteurs à plusieurs caractères?
lance le
Non, mais j'ai pensé à permettre cela.
Ronnie Over par
32
Hey ça marche à 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 J'obtiens l'erreur dans la dernière ligne êtes-vous là alors donnez-vous d'autres informations de contact
Sunil Acharya
Bien que je n'ai pas utilisé exactement cette version, c'est sur cette base que j'ai résolu mon problème. Je vous remercie. Fonctionne très bien.
nrod
13
Nous avons toujours utilisé le pilote Jet.OLEDB, jusqu'à ce que nous commencions à passer aux applications 64 bits. Microsoft n'a pas et ne publiera pas de pilote Jet 64 bits. Voici une solution simple que nous avons proposée qui utilise File.ReadAllLines et String.Split pour lire et analyser le fichier CSV et charger manuellement un DataTable. Comme indiqué ci-dessus, il NE gère PAS la situation où l'une des valeurs de colonne contient une virgule. Nous l'utilisons principalement pour lire des fichiers de configuration personnalisés - l'avantage de l'utilisation des fichiers CSV est que nous pouvons les modifier dans 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);}
c'est le code que je l'utilise mais vos applications doivent fonctionner avec la version 3.5 nette
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();}
Je suis tombé sur ce morceau de code qui utilise Linq et regex pour analyser un fichier CSV. L'article de référence a maintenant plus d'un an et demi, mais n'a pas trouvé de moyen plus propre d'analyser un CSV en utilisant Linq (et regex) que celui-ci. La mise en garde est que le regex appliqué ici est pour les fichiers délimités par des virgules (détectera les virgules entre guillemets!) Et qu'il peut ne pas convenir aux en-têtes, mais il existe un moyen de les surmonter). Prenez un pic:
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
La meilleure option que j'ai trouvée, et elle résout les problèmes où vous pouvez avoir différentes versions d'Office installées, ainsi que les problèmes 32/64 bits comme Chuck Bevitt mentionné , est FileHelpers .
Il peut être ajouté à vos références de projet à l'aide de NuGet et fournit une solution à une ligne:
pouvez-vous dire ce qu'est CommonEngine? NuGet est-il identique à NuGet.Core. Je n'ai trouvé que NuGet.Core dans les références
sindhu jampani
Ce sont FileHelpers dont vous avez besoin. Si vous avez NuGet, ajoutez-le avec NuGet. Sinon, ajoutez-le simplement en tant qu'assemblage dans votre projet. CommonEngine fait partie de FileHelpers.
Neo
3
Pour ceux d'entre vous qui souhaitent ne pas utiliser de bibliothèque externe et préfèrent ne pas utiliser OleDB, consultez l'exemple ci-dessous. Tout ce que j'ai trouvé était soit OleDB, une bibliothèque externe, soit simplement un fractionnement basé sur une virgule! Pour mon cas, OleDB ne fonctionnait pas donc je voulais quelque chose de différent.
J'ai trouvé un article de MarkJ qui faisait référence à la méthode Microsoft.VisualBasic.FileIO.TextFieldParser comme on le voit ici . L'article est écrit en VB et ne renvoie pas de datatable, alors voyez mon exemple ci-dessous.
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;}
Réponse très basique: si vous n'avez pas de csv complexe pouvant utiliser une fonction de fractionnement simple, cela fonctionnera bien pour l'importation (notez que cela importe sous forme de chaînes, je fais des conversions de type de données plus tard si nécessaire)
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;}
Ma méthode si j'importe une table avec un séparateur de chaîne [] et gère le problème où la ligne actuelle que je lis peut être passée à la ligne suivante dans le fichier csv ou texte <- auquel cas je veux faire une boucle jusqu'à ce que j'obtienne au nombre total de lignes de la première ligne (colonnes)
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;}
Bien que vous n'ayez pas encore déclaré les lignes comme chaîne [].
Animal Style
@AnimalStyle vous avez raison - mis à jour avec une méthode plus robuste et des lignes déclarées
Matt Farguson
3
Modifié de M. ChuckBevitt
Solution de travail:
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);}
Donc, cela résout un problème de mémoire, non? Il s'agit d'un traitement ligne par ligne et qui ne persiste pas en mémoire, il ne devrait donc y avoir aucune exception? J'aime la façon dont cela est traité mais File.ReadAllLines () ne sauvegarde-t-il pas tout en mémoire? Je pense que vous êtes censé utiliser File.ReadLines () pour éviter une énorme mémoire tampon? C'est une bonne réponse à la question que je veux juste savoir sur les problèmes de mémoire.
DtechNet
2
Voici une solution qui utilise le pilote de texte ODBC d'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
Une fois rempli, vous pouvez valoriser les propriétés de la table de données, comme ColumnName, pour utiliser toutes les puissances des objets de données ADO.Net.
Dans VS2008, vous pouvez utiliser Linq pour obtenir le même effet.
REMARQUE: cela peut être un double de cette question SO.
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;}
Notez que dans la version 13 aConfiguration été renommé CsvConfigurationpour éviter les conflits d'espace de noms. Démo de cette réponse fonctionnant: dotnetfiddle.net/sdwc6i
dbc
2
J'utilise une bibliothèque appelée ExcelDataReader, vous pouvez la trouver sur NuGet. Assurez-vous d'installer à la fois ExcelDataReader et l'extension ExcelDataReader.DataSet (cette dernière fournit la méthode AsDataSet requise référencée ci-dessous).
J'ai tout encapsulé dans une seule fonction, vous pouvez le copier directement dans votre code. Donnez-lui un chemin vers le fichier CSV, il vous obtient un ensemble de données avec une table.
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();}}
Nous sommes en 2020 et c'est une excellente solution par rapport à certaines des réponses les plus anciennes ici. Il est joliment emballé et utilise une bibliothèque populaire et légère de NuGet. Et c'est flexible - si votre CSV est en mémoire, transmettez-le simplement en tant que MemoryStreamchemin d'accès au fichier. Le DataTable demandé par OP est facilement extrait du DataSet comme ceci:result.Tables[0]
Tawab Wakil
1
En partageant simplement ces méthodes d'extension, j'espère que cela pourra aider quelqu'un.
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;}
Utiliser cette bibliothèque pour charger un DataTableest extrêmement simple.
using var tr =File.OpenText("data.csv");
using var dr =CsvDataReader.Create(tr);var dt =newDataTable();
dt.Load(dr);
En supposant que votre fichier soit un fichier standard séparé par des virgules avec des en-têtes, c'est tout ce dont vous avez besoin. Il existe également des options permettant de lire des fichiers sans en-têtes, d'utiliser des délimiteurs alternatifs, etc.
Il est également possible de fournir un schéma personnalisé pour le fichier CSV afin que les colonnes puissent être traitées comme autre chose que des stringvaleurs. Cela permettra aux DataTablecolonnes d'être chargées avec des valeurs qui peuvent être plus faciles à utiliser, car vous n'aurez pas à les contraindre lorsque vous y accédez.
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);
TypedCsvSchemaest une implémentation ICsvSchemaProviderqui fournit un moyen simple de définir les types des colonnes. Cependant, il est également possible de fournir une personnalisation ICsvSchemaProviderlorsque vous souhaitez fournir plus de métadonnées, telles que l'unicité ou la taille de colonne contrainte, etc.
Réponses:
Voici une excellente classe qui copiera les données CSV dans une table de données en utilisant la structure des données pour créer le DataTable:
Un analyseur générique portable et efficace pour les fichiers plats
Il est facile à configurer et à utiliser. Je vous conseille vivement de jeter un œil.
la source
J'utilise le
OleDb
fournisseur. Cependant, cela pose des problèmes si vous lisez des lignes contenant des valeurs numériques mais que vous souhaitez qu'elles soient traitées comme du texte. Cependant, vous pouvez contourner ce problème en créant unschema.ini
fichier. Voici ma méthode que j'ai utilisée:la source
J'ai décidé d'utiliser le lecteur Csv de Sébastien Lorion .
La suggestion de Jay Riggs est également une excellente solution, mais je n'avais tout simplement pas besoin de toutes les fonctionnalités fournies par Generic Parser d'Andrew Rissing .
MISE À JOUR 25/10/2010
Après avoir utilisé le lecteur Csv de Sébastien Lorion dans mon projet pendant près d'un an et demi, j'ai constaté qu'il lançait des exceptions lors de l'analyse de certains fichiers csv que je pense être bien formés.
Donc, je suis passé à l' analyseur générique d'Andrew Rissing et il semble aller beaucoup mieux.
MISE À JOUR 22/09/2014
Ces jours-ci, j'utilise principalement cette méthode d'extension pour lire du texte délimité:
https://github.com/Core-Techs/Common/blob/master/CoreTechs.Common/Text/DelimitedTextExtensions.cs#L22
https://www.nuget.org/packages/CoreTechs.Common/
MISE À JOUR 20/02/2015
Exemple:
la source
Hey ça marche à 100%
Image CSV
Table de données importée
la source
Nous avons toujours utilisé le pilote Jet.OLEDB, jusqu'à ce que nous commencions à passer aux applications 64 bits. Microsoft n'a pas et ne publiera pas de pilote Jet 64 bits. Voici une solution simple que nous avons proposée qui utilise File.ReadAllLines et String.Split pour lire et analyser le fichier CSV et charger manuellement un DataTable. Comme indiqué ci-dessus, il NE gère PAS la situation où l'une des valeurs de colonne contient une virgule. Nous l'utilisons principalement pour lire des fichiers de configuration personnalisés - l'avantage de l'utilisation des fichiers CSV est que nous pouvons les modifier dans Excel.
la source
c'est le code que je l'utilise mais vos applications doivent fonctionner avec la version 3.5 nette
la source
Vous pouvez y parvenir en utilisant Microsoft.VisualBasic.FileIO.TextFieldParser dll en C #
la source
la source
Je suis tombé sur ce morceau de code qui utilise Linq et regex pour analyser un fichier CSV. L'article de référence a maintenant plus d'un an et demi, mais n'a pas trouvé de moyen plus propre d'analyser un CSV en utilisant Linq (et regex) que celui-ci. La mise en garde est que le regex appliqué ici est pour les fichiers délimités par des virgules (détectera les virgules entre guillemets!) Et qu'il peut ne pas convenir aux en-têtes, mais il existe un moyen de les surmonter). Prenez un pic:
la source
La meilleure option que j'ai trouvée, et elle résout les problèmes où vous pouvez avoir différentes versions d'Office installées, ainsi que les problèmes 32/64 bits comme Chuck Bevitt mentionné , est FileHelpers .
Il peut être ajouté à vos références de projet à l'aide de NuGet et fournit une solution à une ligne:
la source
Pour ceux d'entre vous qui souhaitent ne pas utiliser de bibliothèque externe et préfèrent ne pas utiliser OleDB, consultez l'exemple ci-dessous. Tout ce que j'ai trouvé était soit OleDB, une bibliothèque externe, soit simplement un fractionnement basé sur une virgule! Pour mon cas, OleDB ne fonctionnait pas donc je voulais quelque chose de différent.
J'ai trouvé un article de MarkJ qui faisait référence à la méthode Microsoft.VisualBasic.FileIO.TextFieldParser comme on le voit ici . L'article est écrit en VB et ne renvoie pas de datatable, alors voyez mon exemple ci-dessous.
la source
Réponse très basique: si vous n'avez pas de csv complexe pouvant utiliser une fonction de fractionnement simple, cela fonctionnera bien pour l'importation (notez que cela importe sous forme de chaînes, je fais des conversions de type de données plus tard si nécessaire)
Ma méthode si j'importe une table avec un séparateur de chaîne [] et gère le problème où la ligne actuelle que je lis peut être passée à la ligne suivante dans le fichier csv ou texte <- auquel cas je veux faire une boucle jusqu'à ce que j'obtienne au nombre total de lignes de la première ligne (colonnes)
la source
Modifié de M. ChuckBevitt
Solution de travail:
la source
Voici une solution qui utilise le pilote de texte ODBC d'ADO.Net:
Une fois rempli, vous pouvez valoriser les propriétés de la table de données, comme ColumnName, pour utiliser toutes les puissances des objets de données ADO.Net.
Dans VS2008, vous pouvez utiliser Linq pour obtenir le même effet.
REMARQUE: cela peut être un double de cette question SO.
la source
Je ne peux pas résister à ajouter mon propre spin à cela. C'est tellement mieux et plus compact que ce que j'ai utilisé dans le passé.
Cette solution:
Voici ce que j'ai trouvé:
Cela dépend d'une méthode d'extension (
Unique
) pour gérer les noms de colonnes en double à trouver comme réponse dans Comment ajouter des numéros uniques à une liste de chaînesEt voici la
BlankToNothing
fonction d'assistance:la source
Avec Cinchoo ETL - une bibliothèque open source, vous pouvez facilement convertir un fichier CSV en DataTable avec quelques lignes de code.
Pour plus d'informations, veuillez consulter l' article codeproject .
J'espère que ça aide.
la source
en utilisant: https://joshclose.github.io/CsvHelper/
la source
Configuration
été renomméCsvConfiguration
pour éviter les conflits d'espace de noms. Démo de cette réponse fonctionnant: dotnetfiddle.net/sdwc6iJ'utilise une bibliothèque appelée ExcelDataReader, vous pouvez la trouver sur NuGet. Assurez-vous d'installer à la fois ExcelDataReader et l'extension ExcelDataReader.DataSet (cette dernière fournit la méthode AsDataSet requise référencée ci-dessous).
J'ai tout encapsulé dans une seule fonction, vous pouvez le copier directement dans votre code. Donnez-lui un chemin vers le fichier CSV, il vous obtient un ensemble de données avec une table.
la source
MemoryStream
chemin d'accès au fichier. Le DataTable demandé par OP est facilement extrait du DataSet comme ceci:result.Tables[0]
En partageant simplement ces méthodes d'extension, j'espère que cela pourra aider quelqu'un.
la source
Utilisez ceci, une fonction résout tous les problèmes de virgule et de citation:
la source
la source
J'ai récemment écrit un analyseur CSV pour .NET qui, selon moi, est actuellement le plus rapide disponible en tant que package nuget : Sylvan.Data.Csv .
Utiliser cette bibliothèque pour charger un
DataTable
est extrêmement simple.En supposant que votre fichier soit un fichier standard séparé par des virgules avec des en-têtes, c'est tout ce dont vous avez besoin. Il existe également des options permettant de lire des fichiers sans en-têtes, d'utiliser des délimiteurs alternatifs, etc.
Il est également possible de fournir un schéma personnalisé pour le fichier CSV afin que les colonnes puissent être traitées comme autre chose que des
string
valeurs. Cela permettra auxDataTable
colonnes d'être chargées avec des valeurs qui peuvent être plus faciles à utiliser, car vous n'aurez pas à les contraindre lorsque vous y accédez.TypedCsvSchema
est une implémentationICsvSchemaProvider
qui fournit un moyen simple de définir les types des colonnes. Cependant, il est également possible de fournir une personnalisationICsvSchemaProvider
lorsque vous souhaitez fournir plus de métadonnées, telles que l'unicité ou la taille de colonne contrainte, etc.la source