2016-07-19 2 views
1

J'ai un script qui importe un fichier csv et lit chaque ligne pour mettre à jour l'élément correspondant dans Sitecore. Cela fonctionne pour beaucoup de produits mais le problème est pour certains produits où certaines cellules de la rangée ont des virgules (comme la description du produit).Comment puis-je obtenir des valeurs d'un fichier csv où certaines cellules contiennent des virgules?

protected void SubmitButton_Click(object sender, EventArgs e) 
{ 
    if (UpdateFile.PostedFile != null) 
    { 
     var file = UpdateFile.PostedFile; 

     // check if valid csv file 

     message.InnerText = "Updating..."; 

     Sitecore.Context.SetActiveSite("backedbybayer"); 
     _database = Database.GetDatabase("master"); 
     SitecoreContext context = new SitecoreContext(_database); 
     Item homeNode = context.GetHomeItem<Item>(); 


     var productsItems = 
      homeNode.Axes.GetDescendants() 
       .Where(
        child => 
         child.TemplateID == new ID(TemplateFactory.FindTemplateId<IProductDetailPageItem>())); 

     try 
     { 
      using (StreamReader sr = new StreamReader(file.InputStream)) 
      { 
       var firstLine = true; 
       string currentLine; 
       var productIdIndex = 0; 
       var industryIdIndex = 0; 
       var categoryIdIndex = 0; 
       var pestIdIndex = 0; 
       var titleIndex = 0; 
       string title; 
       string productId; 
       string categoryIds; 
       string industryIds; 
       while ((currentLine = sr.ReadLine()) != null) 
       { 
        var data = currentLine.Split(',').ToList(); 
        if (firstLine) 
        { 
         // find index of the important columns 
         productIdIndex = data.IndexOf("ProductId"); 
         industryIdIndex = data.IndexOf("PrimaryIndustryId"); 
         categoryIdIndex = data.IndexOf("PrimaryCategoryId"); 
         titleIndex = data.IndexOf("Title"); 
         firstLine = false; 
         continue; 
        } 

        title = data[titleIndex]; 
        productId = data[productIdIndex]; 
        categoryIds = data[categoryIdIndex]; 
        industryIds = data[industryIdIndex]; 

        var products = productsItems.Where(x => x.DisplayName == title); 
        foreach (var product in products) 
        { 
         product.Editing.BeginEdit(); 
         try 
         { 
          product.Fields["Product Id"].Value = productId; 
          product.Fields["Product Industry Ids"].Value = industryIds; 
          product.Fields["Category Ids"].Value = categoryIds; 
         } 
         finally 
         { 
          product.Editing.EndEdit(); 
         } 
        } 
       } 
      } 

      // when done 
      message.InnerText = "Complete"; 
     } 
     catch (Exception ex) 
     { 
      message.InnerText = "Error reading file"; 
     }    
    } 
} 

Le problème est que lorsqu'un champ de description a des virgules, comme « Le produit est un moyen efficace biofongicide préventif, » il se diviser aussi bien et jette l'index, categoryIds = data[8] obtient la valeur erronée.

La feuille de calcul est une donnée fournie par notre client, donc je préfère ne pas demander au client de modifier le fichier sauf si nécessaire. Est-ce que je peux gérer cela dans mon code? Existe-t-il une façon différente de lire le fichier qui ne divisera pas tout par virgule?

+1

Vous dites " importe un fichier xls ". Voulez-vous dire "importe un fichier csv"? Si vous essayez de lire des fichiers CSV, utilisez un vrai analyseur CSV. Google devrait apparaître plusieurs. Analyser CSV correctement n'est pas aussi simple que vous pourriez le supposer. – adv12

+0

Solution la plus simple: basculez votre délimiteur sur Semikolon **; **. Puisque votre feuille de csv contient du texte complexe, la virgule n'est pas le meilleur séparateur. – lokusking

+0

Désolé, oui, c'est un fichier csv mais je pourrais essayer d'importer un fichier xls à la place. –

Répondre

0

Je suggère l'utilisation Ado.Net Si les données de terrain sont des citations à l'intérieur et il va l'analyser comme un champ et ignorer les virgules dans ce ..

Exemple de code:

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; 
    } 
}