2017-06-20 2 views
2

Je dois convertir directement un fichier xls en document JSON en utilisant python3 et xlrd.xls à JSON en utilisant python3 xlrd

La table est here.

Il est divisé en trois catégories principales (PUBLICATION, CONTENU, CONCLUSION) dont les noms sont sur la première colonne (la première colonne est zéro) et le nombre de rangées par catégorie peut varier. Chaque ligne a trois valeurs clés (INDICATEURS, EVALUATION, PROPOSITION) sur les colonnes 3, 5 et 7. Il peut y avoir des lignes vides ou des valeurs manquantes

Je dois convertir cette table aux données JSON suivantes que j'ai écrites directement une référence. C'est valide.

{ 
"EVALUATION": { 
    "PUBLICATION": [ 
     { 
      "INDICATEUR": "Page de garde", 
      "EVALUATION": "Inexistante ou non conforme", 
      "PROPOSITION D'AMELIORATION": "Consulter l'example sur CANVAS" 
     }, 
     { 
      "INDICATEUR": "Page de garde", 
      "EVALUATION": "Titre du TFE non conforme", 
      "PROPOSITION D'AMELIORATION": "Utilisez le titre avalisé par le conseil des études" 
     }, 
     { 
      "INDICATEUR": "Orthographe et grammaire", 
      "EVALUATION": "Nombreuses fautes", 
      "PROPOSITION D'AMELIORATION": "Faire relire le document" 
     }, 
     { 
      "INDICATEUR": "Nombre de page", 
      "EVALUATION": "Nombre de pages grandement différent à la norme", 
      "PROPOSITION D'AMELIORATION": "" 
     } 
    ], 
    "CONTENU": [ 
     { 
      "INDICATEUR": "Développement du sujet", 
      "EVALUATION": "Présentation de l'entreprise", 
      "PROPOSITION D'AMELIORATION": "" 
     }, 
     { 
      "INDICATEUR": "Développement du sujet", 
      "EVALUATION": "Plan de localisation inutile", 
      "PROPOSITION D'AMELIORATION": "Supprimer le plan de localisation" 
     }, 
     { 
      "INDICATEUR": "Figures et capture d'écran", 
      "EVALUATION": "Captures d'écran excessives", 
      "PROPOSITION D'AMELIORATION": "Pour chaque figure et capture d'écran se poser la question 'Qu'est-ce que cela apporte à mon sujet ?'" 
     }, 
     { 
      "INDICATEUR": "Figures et capture d'écran", 
      "EVALUATION": "Captures d'écran Inutiles", 
      "PROPOSITION D'AMELIORATION": "Pour chaque figure et capture d'écran se poser la question 'Qu'est-ce que cela apporte à mon sujet ?'" 
     }, 
     { 
      "INDICATEUR": "Figures et capture d'écran", 
      "EVALUATION": "Captures d'écran illisibles", 
      "PROPOSITION D'AMELIORATION": "Pour chaque figure et capture d'écran se poser la question 'Qu'est-ce que cela apporte à mon sujet ?'" 
     }, 
     { 
      "INDICATEUR": "Conclusion", 
      "EVALUATION": "Conclusion inexistante", 
      "PROPOSITION D'AMELIORATION": "" 
     }, 
     { 
      "INDICATEUR": "Bibliographie", 
      "EVALUATION": "Inexistante", 
      "PROPOSITION D'AMELIORATION": "" 
     }, 
     { 
      "INDICATEUR": "Bibliographie", 
      "EVALUATION": "Non normalisée", 
      "PROPOSITION D'AMELIORATION": "Ecrire la bibliographie selon la norme APA" 
     } 
    ], 
    "CONCLUSION": [ 
     { 
      "INDICATEUR": "", 
      "EVALUATION": "Grave manquement sur le plan de la présentation", 
      "PROPOSITION D'AMELIORATION": "Lire le document 'Conseil de publication' disponible sur CANVAS" 
     }, 
     { 
      "INDICATEUR": "", 
      "EVALUATION": "Risque de refus du document par le conseil des études", 
      "PROPOSITION D'AMELIORATION": "" 
     } 
    ] 
} 

}

Mon intention est de boucler à travers les lignes, vérifier les lignes [1] pour identifier la catégorie et la sous-boucle pour ajouter des données comme dictionnaire dans une liste par catégorie.

Voici mon code à ce jour:

import xlrd 
file = '/home/eh/Documents/Base de Programmation/Feedback/EvaluationEI.xls' 
wb = xlrd.open_workbook(file) 
sheet = wb.sheet_by_index(0) 
data = [[sheet.cell_value(r, c) for c in range(sheet.ncols)] for r in range(sheet.nrows)] 


def readRows(): 
    for rownum in range(2,sheet.nrows): 
     rows = sheet.row_values(rownum) 
     indicateur = rows[3] 
     evaluation = rows[5] 
     amelioration = rows[7] 
     publication = [] 
     contenu = [] 
     conclusion = [] 

     if rows[1] == "PUBLICATION": 

      if rows[3] == '' and rows[5] == '' and rows[7] == '': 
       continue 
      else: 
       publication.append("INDICATEUR : " + indicateur , "EVALUATION : " + evaluation , "PROPOSITION D'AMELIORATION : " + amelioration) 

     if rows[1] == "CONTENU": 

      if rows[3] == '' and rows[5] == '' and rows[7] == '': 
       continue 
      else: 
       contenu.append("INDICATEUR : " + indicateur , "EVALUATION : " + evaluation , "PROPOSITION D'AMELIORATION : " + amelioration) 

     if rows[1] == "CONCLUSION": 

      if rows[3] == '' and rows[5] == '' and rows[7] == '': 
       continue 
      else: 
       conclusion.append("INDICATEUR : " + indicateur , "EVALUATION : " + evaluation , "PROPOSITION D'AMELIORATION : " + amelioration) 

    print (publication) 
    print (contenu) 
    print (conclusion) 




readRows() 

J'ai du mal à comprendre comment la sous-boucle pour le bon nombre de lignes à séparer les données par catégories.

Toute aide serait la bienvenue.

Merci d'avance

+1

Il semble que si vous êtes désireux de trouver les publications par exemple après la ligne PUBLICATION se trouve, mais votre code est à la recherche qu'à la même ligne que la publication (à COLONNES 3, 5, 7) qui sont vides. La liste rows [] contient en réalité les valeurs des colonnes de la ligne. Cela entraîne le déclenchement de l'instruction "continue". Ce que vous devez faire est de faire une recherche dans les lignes au-dessous de la ligne PUBLICATION pour voir si les colonnes 3,5,7 contiennent des informations utiles. –

Répondre

0

Utilisation du package json et le OrderedDict (pour préserver l'ordre clé), je pense que cela arrive à ce que vous attendez, et J'ai légèrement modifié donc nous ne construisons pas un littéral de chaîne, mais plutôt un dict qui contient les données que nous pouvons ensuite convertir avec json.dumps. Comme Ron l'a noté plus haut, votre tentative précédente consistait à ignorer les lignes où rows[1] n'était pas égale à l'une de vos trois valeurs de clé.

Cela devrait lire toutes les lignes, annexant à la dernière clé non vide:

def readRows(file, s_index=0): 
    """ 
    file: path to xls file 
    s_index: sheet_index for the xls file 
    returns a dict of OrderedDict of list of OrderedDict which can be parsed to JSON 
    """ 
    d = {"EVALUATION" : OrderedDict()} # this will be the main dict for our JSON object 
    wb = xlrd.open_workbook(file) 
    sheet = wb.sheet_by_index(s_index) 
    # getting the data from the worksheet 
    data = [[sheet.cell_value(r, c) for c in range(sheet.ncols)] for r in range(sheet.nrows)] 
    # fill the dict with data: 
    for _,row in enumerate(data[3:]): 
     if row[1]: # if there's a value, then this is a new categorie element 
      categorie = row[1] 
      d["EVALUATION"][categorie] = [] 
     if categorie: 
      i,e,a = row[3::2][:3] 
      if i or e or a: # as long as there's any data in this row, we write the child element 
       val = OrderedDict([("INDICATEUR", i),("EVALUATION", e),("PROPOSITION D'AMELIORATION", a)]) 
       d["EVALUATION"][categorie].append(val) 
    return d 

Ceci retourne une dict qui peut être facilement analysé à JSON. Capture d'écran de l'affichage:

enter image description here

Write to file if needed:

import io # for python 2 
d = readRows(file,0) 
with io.open('c:\debug\output.json','w',encoding='utf8') as out: 
    out.write(json.dumps(d,indent=2,ensure_ascii=False)) 

Note: en Python 3, je ne pense pas que vous avez besoin io.open.

+0

Excellente solution. Il fonctionne comme un charme. Je vous remercie. – hElyot

1

Les pandas ne sont-ils pas une option? Souhaitez ajouter comme un commentaire, mais ne pas avoir le représentant.

De Documentation

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_excel.html https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_json.html

df = pandas.read_excel('path_to_file.xls') 
df.to_json(path_or_buf='output_path.json', orient='table') 
+0

Merci pour votre aide. Pandas semble intéressant mais mon problème ici est la structure de mon fichier xls, qui n'est pas une table bien orientée. Peut-être que si je peux nettoyer et réarranger le fichier xls avec des pandas, je trouverai une solution. – hElyot