2010-02-24 1 views
2

Cela m'a tué - j'ai un fichier volumineux que j'ai besoin de lire en tant que DataTable.Lecture de fichier CSV à l'aide de Jet - TabDelimited ne fonctionne pas!

Après beaucoup de vous embêter J'utilise ceci:

using (OleDbConnection connection = new OleDbConnection(connString)) 
{ 
    using (OleDbCommand command = new OleDbCommand(sql, connection)) 
    { 
     using (OleDbDataAdapter adapter = new OleDbDataAdapter(command)) 
     { 
      dataTable = new DataTable(); 
      dataTable.Locale = CultureInfo.CurrentCulture; 
      adapter.Fill(dataTable); 
     } 
    } 
} 

qui fonctionne si le fichier texte est seperated mais ne comma fonctionne pas s'il est délimité par des tabulations - Quelqu'un peut-il aider ?? s'il vous plaît

Ma chaîne de connexion ressemble à:

string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly + @";Extended Properties='text;HDR=YES'";

J'ai essayé de définir la propriété FMT sans chance ....

+1

Avez-vous essayé de créer un fichier schema.ini dans le même répertoire avec la section suivante? [MyFilename.txt] Format = TabDelimited –

Répondre

2

Voici une bonne bibliothèque l'utiliser.

http://www.codeproject.com/KB/database/CsvReader.aspx

Voici le code qui utilisent la bibliothèque.

TextReader tr = new StreamReader(HttpContext.Current.Server.MapPath(Filename)); 
string data = tr.ReadToEnd(); 
tr.Close(); 

pour délimité par des virgules;

CachedCsvReader cr = new CachedCsvReader(new StringReader(csv), true); 

pour tab délimité;

CachedCsvReader cr = new CachedCsvReader(new StringReader(csv), true, '\t'); 

Et vous pouvez le charger dans DataTable en ayant ce code

DataTable dt = new DataTable(); 
dt.Load(cr); 

espérons qu'il vous sera utile. Merci

+0

Et vous pouvez également avoir facilement les en-têtes du fichier csv en appelant cette fonction comme un tableau de chaînes. cr.GetFieldHeaders(); –

+1

J'ai utilisé cette bibliothèque avec succès, ce qui lui donne un vote positif –

+0

Oui mais cela fonctionnera-t-il avec un onglet délimité et non csv ?? –

-1

Cela devrait fonctionner: (à partir http://www.hotblue.com/article0000.aspx?a=0006)

il suffit de remplacer la partie virgule avec:

if ((postdata || !quoted) && (c == ',' || c == '\t')) 

pour le rendre délimité par des tabulations.

using System.Data; 
using System.IO; 
using System.Text.RegularExpressions; 

public DataTable ParseCSV(string inputString) { 

    DataTable dt=new DataTable(); 

    // declare the Regular Expression that will match versus the input string 
    Regex re=new Regex("((?<field>[^\",\\r\\n]+)|\"(?<field>([^\"]|\"\")+)\")(,|(?<rowbreak>\\r\\n|\\n|$))"); 

    ArrayList colArray=new ArrayList(); 
    ArrayList rowArray=new ArrayList(); 

    int colCount=0; 
    int maxColCount=0; 
    string rowbreak=""; 
    string field=""; 

    MatchCollection mc=re.Matches(inputString); 

    foreach(Match m in mc) { 

    // retrieve the field and replace two double-quotes with a single double-quote 
    field=m.Result("${field}").Replace("\"\"","\""); 

    rowbreak=m.Result("${rowbreak}"); 

    if (field.Length > 0) { 
     colArray.Add(field);     
     colCount++; 
    } 

    if (rowbreak.Length > 0) { 

     // add the column array to the row Array List 
     rowArray.Add(colArray.ToArray()); 

     // create a new Array List to hold the field values 
     colArray=new ArrayList(); 

     if (colCount > maxColCount) 
     maxColCount=colCount; 

     colCount=0; 
    } 
    } 

    if (rowbreak.Length == 0) { 
    // this is executed when the last line doesn't 
    // end with a line break 
    rowArray.Add(colArray.ToArray()); 
    if (colCount > maxColCount) 
     maxColCount=colCount; 
    } 

    // create the columns for the table 
    for(int i=0; i < maxColCount; i++) 
    dt.Columns.Add(String.Format("col{0:000}",i)); 

    // convert the row Array List into an Array object for easier access 
    Array ra=rowArray.ToArray(); 
    for(int i=0; i < ra.Length; i++) {     

    // create a new DataRow 
    DataRow dr=dt.NewRow(); 

    // convert the column Array List into an Array object for easier access 
    Array ca=(Array)(ra.GetValue(i));    

    // add each field into the new DataRow 
    for(int j=0; j < ca.Length; j++) 
     dr[j]=ca.GetValue(j); 

    // add the new DataRow to the DataTable 
    dt.Rows.Add(dr); 
    } 

    // in case no data was parsed, create a single column 
    if (dt.Columns.Count == 0) 
    dt.Columns.Add("NoData"); 

    return dt; 
} 

Maintenant que nous avons un analyseur pour convertir une chaîne en un DataTable, tout ce que nous devons maintenant est une fonction qui va lire le contenu d'un fichier CSV et le transmettre à notre fonction ParseCSV:

public DataTable ParseCSVFile(string path) { 

    string inputString=""; 

    // check that the file exists before opening it 
    if (File.Exists(path)) { 

    StreamReader sr = new StreamReader(path); 
    inputString = sr.ReadToEnd(); 
    sr.Close(); 

    } 

    return ParseCSV(inputString); 
} 

Et maintenant, vous pouvez facilement remplir une grille de données avec des données venant du fichier CSV:

protected System.Web.UI.WebControls.DataGrid DataGrid1; 

private void Page_Load(object sender, System.EventArgs e) { 

    // call the parser 
    DataTable dt=ParseCSVFile(Server.MapPath("./demo.csv"));   

    // bind the resulting DataTable to a DataGrid Web Control 
    DataGrid1.DataSource=dt; 
    DataGrid1.DataBind(); 
} 
+0

Quel est le problème avec cela. Cela fonctionne très bien. –

0

manuellement: vous pouvez utiliser la méthode String.Split() pour diviser votre fichier entier. Voici un exemple de ce que j'utilise dans mon code. Dans cet exemple, je lis la ligne de données par ligne et la divise. Je place ensuite les données directement dans les colonnes.

   //Open and read the file 
       System.IO.FileStream fs = new System.IO.FileStream("myfilename", System.IO.FileMode.Open); 
       System.IO.StreamReader sr = new System.IO.StreamReader(fs); 

       string line = ""; 
       line = sr.ReadLine(); 

       string[] colVal; 

       try 
       { 
        //clear of previous data 
        //myDataTable.Clear(); 

        //for each reccord insert it into a row 
        while (!sr.EndOfStream) 
        { 
         line = sr.ReadLine(); 

          colVal = line.Split('\t'); 

          DataRow dataRow = myDataTable.NewRow(); 

          //associate values with the columns 
          dataRow["col1"] = colVal[0];   
          dataRow["col2"] = colVal[1]; 
          dataRow["col3"] = colVal[2]; 

          //add the row to the table 
          myDataTable.Rows.Add(dataRow); 
        } 

        //close the stream 
        sr.Close(); 

        //binds the dataset tothe grid view. 
        BindingSource bs = new BindingSource(); 
        bs.DataSource = myDataSet; 
        bs.DataMember = myDataTable.TableName; 
        myGridView.DataSource = bs; 
       } 

Vous pouvez le modifier pour faire des boucles pour les colonnes si vous en avez plusieurs et qu'elles sont numérotées. Aussi, je recommande de vérifier d'abord l'intégrité, en vérifiant que le nombre de colonnes lues est correct.

Questions connexes