Comment charger un fichier CSV dans une table de données System.Data.DataTable, en créant la table de données sur la base du fichier CSV ?
Existe-t-il une bibliothèque de classes pour cela ou puis-je utiliser ADO.net pour me connecter au fichier ?
Comment charger un fichier CSV dans une table de données System.Data.DataTable, en créant la table de données sur la base du fichier CSV ?
Existe-t-il une bibliothèque de classes pour cela ou puis-je utiliser ADO.net pour me connecter au fichier ?
J'ai utilisé OleDb
fournisseur. Cependant, il pose des problèmes si vous lisez des lignes qui ont l'apparence de valeurs numériques mais que vous voulez qu'elles soient traitées comme du texte. Cependant, vous pouvez contourner ce problème en créant un fichier schema.ini
fichier. Voici la méthode que j'ai utilisée :
// using System.Data;
// using System.Data.OleDb;
// using System.Globalization;
// using System.IO;
static DataTable GetDataTableFromCsv(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 = new OleDbConnection(
@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly +
";Extended Properties=\"Text;HDR=" + header + "\""))
using(OleDbCommand command = new OleDbCommand(sql, connection))
using(OleDbDataAdapter adapter = new OleDbDataAdapter(command))
{
DataTable dataTable = new DataTable();
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 les valeurs de plusieurs colonnes, donc trouver une regex qui couperait la ligne était un peu difficile. Le OleDbProvider a déduit le schéma correctement.
La mise en œuvre est logique, mais comment traiter les cellules contenant des types de données mixtes. Par exemple, 40C et etc.
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 donne au fournisseur OleDb des informations sur les colonnes. Voici un lien vers un article de Microsoft qui fournit des détails sur la façon de structurer le fichier. msdn.microsoft.com/fr/us/library/
Voici une excellente classe qui copiera des données CSV dans une table de données en utilisant la structure des données pour créer la table de données :
Un analyseur générique portable et efficace pour les fichiers plats
Il est facile à configurer et à utiliser. Je vous invite à y jeter un coup d'œil.
Excellent en effet. Cela a fonctionné parfaitement pour moi, sans même lire la documentation.
Cela fonctionnera-t-il sur des 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 doivent être séparés en plusieurs tables.
@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és dans la première ligne. Ce que vous avez semble être des données discriminées, délimitées par des virgules, plus génériques, nécessitant un "ETL" plus sophistiqué pour analyser le fichier en instances d'objets de différents types (qui pourraient inclure des DataRows de différentes DataTables).
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 pas besoin de toutes les fonctionnalités que cette solution. L'analyseur générique d'Andrew Rissing fournit.
Après avoir utilisé Le lecteur Csv de Sébastien Lorion dans mon projet depuis près d'un an et demi, j'ai constaté qu'il lève 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 ça semble aller beaucoup mieux.
Je suis d'accord pour dire que le lecteur CSV de Sébastien Lorien est excellent. Je l'utilise pour les traitements CSV lourds, mais j'ai aussi utilisé celui d'Andrew Rissing pour les petits travaux et il m'a bien servi. Amusez-vous bien !
J'ai essayé cela mais la collection it.Current.Keys renvoie "System.Linq.Enumerable+WhereSelectListIterator`2[System.Int32,System.Char]" au lieu du nom de la colonne. Avez-vous une idée de la raison ?
Nous avons toujours utilisé le pilote Jet.OLEDB, jusqu'à ce que nous commencions à utiliser des applications 64 bits. Microsoft n'a pas publié et ne publiera pas de pilote Jet 64 bits. Voici une solution simple que nous avons trouvée et qui utilise File.ReadAllLines et String.Split pour lire et analyser le fichier CSV et charger manuellement une DataTable. Comme indiqué ci-dessus, cette solution ne gère PAS la situation où l'une des valeurs de la colonne contient une virgule. Nous l'utilisons principalement pour lire des fichiers de configuration personnalisés - l'avantage d'utiliser des fichiers CSV est que nous pouvons les modifier dans Excel.
string CSVFilePathName = @"C:\test.csv";
string[] Lines = File.ReadAllLines(CSVFilePathName);
string[] Fields;
Fields = Lines[0].Split(new char[] { ',' });
int Cols = Fields.GetLength(0);
DataTable dt = new DataTable();
//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));
DataRow Row;
for (int i = 1; i < Lines.GetLength(0); i++)
{
Fields = Lines[i].Split(new char[] { ',' });
Row = dt.NewRow();
for (int f = 0; f < Cols; f++)
Row[f] = Fields[f];
dt.Rows.Add(Row);
}
Voici le code que j'utilise mais vos applications doivent fonctionner avec la version 3.5 du réseau.
private void 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 = new DataTable();
//this assume the first record is filled with the column names
var 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;
}
}
}
static IEnumerable<string> ReadAsLines(string filename)
{
using (StreamReader reader = new StreamReader(filename))
while (!reader.EndOfStream)
yield return reader.ReadLine();
}
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
29 votes
Comment cela peut-il être "hors sujet" ? C'est une question spécifique et 100 personnes la trouvent utile.
12 votes
@Ryan : En vérité je vous le dis... Les modérateurs de StackOverflow sont une couvée de vipères. Restez derrière moi, modérateurs de StackOverflow !