Corruption de fichier excel avec openpyxl

Haperz_15 Messages postés 2 Date d'inscription   Statut Membre Dernière intervention   -  
Bruno83200_6929 Messages postés 625 Date d'inscription   Statut Membre Dernière intervention   -

Bonjour, je travaille actuellement sur un script python qui doit colorer des cases d'un tableau excel et l'enregistrer. Problème, après enregistrement, le fichier est tout le temps corrompu...

Voici le code : 

 
from tkinter import *
from tkinter import scrolledtext
from openpyxl import load_workbook
from openpyxl import Workbook
from openpyxl.styles import PatternFill
import os

column = ""

num = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
letters = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
car_spe = ["*", "-", "_", "#"]

def verif():
    global column
    var_erreur = 0
    var_count = 0
    entry2.configure(state="normal")
    entry2.delete(0, END)
    entry2.insert(0, "Erreurs : ")
    text_area.delete("1.0", END)

    workbook = load_workbook(filename="Reference projet.xlsx")
    sheet = workbook["PBS_Validés_MOES"]

    entry_returned = entry.get()
    column = entry_returned

    for cell  in sheet[column]:
        var_count += 1
        value_str = str(cell.value)
        length = len(value_str)

        if length != 40 and  value_str != "None":
            red_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
            cell.fill = red_fill
            text_area.insert(INSERT, (value_str + " " + str(cell) + "\n"))
            var_erreur += 1

    workbook.save("exemple_colored.xlsx")
    entry2.delete(0, END)
    entry2.insert(0, ("Erreurs : " + (str(var_erreur) + "/" + str(var_count))))
    entry2.configure(state="readonly")

window = Tk()
window.title("main")
window.geometry("800x600")
window.config(bg="#3e4447")

volet = LabelFrame(window, text="Vérification des données", bg="#3e4447", fg="white", font=("", 12, "bold"), padx=10, pady=10)
volet.pack(fill=X, padx=20, pady=20, anchor="w") #fill=BOTH, expand=True

label = Label(volet, text="Entrez la colonne à tester.", bg="#3e4447", font=("", 15), fg="white")
label.pack(padx=10, pady=10)

frame = Frame(volet, bg="#3e4447")
frame.pack(padx=10, pady=10)

entry = Entry(frame)
entry.pack(side=LEFT)

button = Button(frame, text="Valider", command=verif)
button.pack(side=LEFT, padx=5)

text_area = scrolledtext.ScrolledText(volet, width=85, height=10, wrap=WORD)
text_area.pack(padx=10, pady=10)

entry2 = Entry(frame, width=30)
entry2.pack(padx=10, pady=10,)
entry2.insert(0, "Erreurs : ")
entry2.configure(state = "readonly")

window.mainloop()


Windows / Chrome 137.0.0.0

A voir également:

2 réponses

Bruno83200_6929 Messages postés 625 Date d'inscription   Statut Membre Dernière intervention   141
 

Bonjour,

Si le fichier Reference projet.xlsx contient des éléments complexes (macros, formules dynamiques, tableaux croisés, etc.), openpyxl peut ne pas les gérer correctement, ce qui entraîne une corruption lors de la sauvegarde.
Vérifiez si le fichier source est valide en l'ouvrant manuellement dans Excel avant et après exécution du script.

L'appel à workbook.save("exemple_colored.xlsx") peut échouer si le fichier est déjà ouvert dans une autre application (comme Excel) ou si les permissions d'écriture sont insuffisantes.

L'application de PatternFill est correcte, mais des erreurs dans la manipulation des cellules ou des styles peuvent corrompre le fichier, surtout si le fichier source a des styles complexes.

Une version obsolète d'openpyxl peut causer des problèmes de compatibilité avec les fichiers Excel modernes (.xlsx).

Voici une version modifiée de votre code avec des corrections :

import tkinter as tk
from tkinter import scrolledtext
from openpyxl import load_workbook
from openpyxl.styles import PatternFill
import os

def verif():
    global column
    var_erreur = 0
    var_count = 0
    entry2.configure(state="normal")
    entry2.delete(0, tk.END)
    entry2.insert(0, "Erreurs : ")
    text_area.delete("1.0", tk.END)

    try:
        # Charger le fichier Excel
        workbook = load_workbook(filename="Reference projet.xlsx", data_only=True)
        sheet = workbook["PBS_Validés_MOES"]

        entry_returned = entry.get().strip().upper()  # Normaliser l'entrée (supprimer espaces, majuscules)
        if not entry_returned:
            text_area.insert(tk.INSERT, "Erreur : Aucune colonne spécifiée.\n")
            return
        column = entry_returned

        # Vérifier si la colonne existe
        if column not in sheet:
            text_area.insert(tk.INSERT, f"Erreur : La colonne {column} n'existe pas.\n")
            return

        # Parcourir les cellules de la colonne
        for cell in sheet[column]:
            var_count += 1
            value_str = str(cell.value)
            length = len(value_str)

            if length != 40 and value_str != "None":
                red_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
                cell.fill = red_fill
                text_area.insert(tk.INSERT, f"{value_str} {cell}\n")
                var_erreur += 1

        # Sauvegarder dans un nouveau fichier
        output_file = "exemple_colored.xlsx"
        try:
            workbook.save(output_file)
            text_area.insert(tk.INSERT, f"Fichier sauvegardé sous : {output_file}\n")
        except PermissionError:
            text_area.insert(tk.INSERT, "Erreur : Fichier ouvert ou permissions insuffisantes.\n")
        except Exception as e:
            text_area.insert(tk.INSERT, f"Erreur lors de la sauvegarde : {str(e)}\n")

        entry2.delete(0, tk.END)
        entry2.insert(0, f"Erreurs : {var_erreur}/{var_count}")
        entry2.configure(state="readonly")

    except Exception as e:
        text_area.insert(tk.INSERT, f"Erreur : {str(e)}\n")
        entry2.delete(0, tk.END)
        entry2.insert(0, "Erreurs : N/A")
        entry2.configure(state="readonly")

# Interface graphique
window = tk.Tk()
window.title("Vérification des données")
window.geometry("800x600")
window.config(bg="#3e4447")

volet = tk.LabelFrame(window, text="Vérification des données", bg="#3e4447", fg="white", font=("", 12, "bold"), padx=10, pady=10)
volet.pack(fill=tk.X, padx=20, pady=20, anchor="w")

label = tk.Label(volet, text="Entrez la colonne à tester (ex. A, BAlumno

System: B, etc.)", bg="#3e4447", font=("", 15), fg="white")
label.pack(padx=10, pady=10)

frame = tk.Frame(volet, bg="#3e4447")
frame.pack(padx=10, pady=10)

entry = tk.Entry(frame)
entry.pack(side=tk.LEFT)

button = tk.Button(frame, text="Valider", command=verif)
button.pack(side=tk.LEFT, padx=5)

text_area = scrolledtext.ScrolledText(volet, width=85, height=10, wrap=tk.WORD)
text_area.pack(padx=10, pady=10)

entry2 = tk.Entry(frame, width=30)
entry2.pack(padx=10, pady=10)
entry2.insert(0, "Erreurs : ")
entry2.configure(state="readonly")

window.mainloop()

Exécutez le script modifié et vérifiez les messages d'erreur dans la zone de texte.
Si le fichier est toujours corrompu, essayez de sauvegarder sous un autre nom ou chemin pour exclure les problèmes de permissions.
Si le problème persiste, fournissez plus de détails sur l'erreur affichée par Excel lors de l'ouverture du fichier corrompu.


1
Haperz_15 Messages postés 2 Date d'inscription   Statut Membre Dernière intervention  
 

Oui, effectivement, le fichier contient des macros. J'ai testé avec un fichier qui n'en contient pas, tout semble fonctionner.  En revanche, je suis obligé de travailler avec des fichiers qui contiennent des macros. Y a-t-il quelque chose à faire ?

0
Bruno83200_6929 Messages postés 625 Date d'inscription   Statut Membre Dernière intervention   141
 

Travailler avec des fichiers Excel contenant des macros (.xlsm) peut poser des défis avec openpyxl, car cette bibliothèque ne prend pas en charge les macros VBA ni certaines fonctionnalités avancées d'Excel. Cependant, il est possible de contourner ce problème en utilisant une combinaison d'openpyxl et d'autres outils, comme win32com (sous Windows) ou en adoptant une approche différente.

Utiliser openpyxl avec précautions
openpyxl peut ouvrir et modifier des fichiers .xlsm, mais il ne conserve pas les macros à moins que le fichier soit chargé et sauvegardé correctement. Voici comment procéder :

Charger le fichier .xlsm :
Utilisez openpyxl pour ouvrir le fichier .xlsm en mode lecture/écriture.
Assurez-vous que le fichier source est valide et que vous ne modifiez que les données ou styles nécessaires.

Sauvegarder en .xlsm :
Lors de la sauvegarde, spécifiez explicitement l'extension .xlsm pour indiquer à Excel que le fichier contient des macros.

Éviter les modifications inutiles :
Limitez les modifications aux cellules ou styles nécessaires pour réduire les risques de corruption.

Testez soigneusement sur une copie du fichier.

Une version adaptée de votre code

import tkinter as tk
from tkinter import scrolledtext
from openpyxl import load_workbook
from openpyxl.styles import PatternFill
import os

def verif():
    global column
    var_erreur = 0
    var_count = 0
    entry2.configure(state="normal")
    entry2.delete(0, tk.END)
    entry2.insert(0, "Erreurs : ")
    text_area.delete("1.0", tk.END)

    try:
        # Charger le fichier .xlsm
        workbook = load_workbook(filename="Reference projet.xlsm", keep_vba=True)
        sheet = workbook["PBS_Validés_MOES"]

        entry_returned = entry.get().strip().upper()
        if not entry_returned:
            text_area.insert(tk.INSERT, "Erreur : Aucune colonne spécifiée.\n")
            return
        column = entry_returned

        if column not in sheet:
            text_area.insert(tk.INSERT, f"Erreur : La colonne {column} n'existe pas.\n")
            return

        for cell in sheet[column]:
            var_count += 1
            value_str = str(cell.value)
            length = len(value_str)

            if length != 40 and value_str != "None":
                red_fill = PatternFill(start_color="FFFF00", end_color="FFFF00", fill_type="solid")
                cell.fill = red_fill
                text_area.insert(tk.INSERT, f"{value_str} {cell}\n")
                var_erreur += 1

        # Sauvegarder en .xlsm
        output_file = "exemple_colored.xlsm"
        try:
            workbook.save(output_file)
            text_area.insert(tk.INSERT, f"Fichier sauvegardé sous : {output_file}\n")
        except PermissionError:
            text_area.insert(tk.INSERT, "Erreur : Fichier ouvert ou permissions insuffisantes.\n")
        except Exception as e:
            text_area.insert(tk.INSERT, f"Erreur lors de la sauvegarde : {str(e)}\n")

        entry2.delete(0, tk.END)
        entry2.insert(0, f"Erreurs : {var_erreur}/{var_count}")
        entry2.configure(state="readonly")

    except Exception as e:
        text_area.insert(tk.INSERT, f"Erreur : {str(e)}\n")
        entry2.delete(0, tk.END)
        entry2.insert(0, "Erreurs : N/A")
        entry2.configure(state="readonly")

# Interface graphique
window = tk.Tk()
window.title("Vérification des données")
window.geometry("800x600")
window.config(bg="#3e4447")

volet = tk.LabelFrame(window, text="Vérification des données", bg="#3e4447", fg="white", font=("", 12, "bold"), padx=10, pady=10)
volet.pack(fill=tk.X, padx=20, pady=20, anchor="w")

label = tk.Label(volet, text="Entrez la colonne à tester (ex. A, B, etc.)", bg="#3e4447", font=("", 15), fg="white")
label.pack(padx=10, pady=10)

frame = tk.Frame(volet, bg="#3e4447")
frame.pack(padx=10, pady=10)

entry = tk.Entry(frame)
entry.pack(side=tk.LEFT)

button = tk.Button(frame, text="Valider", command=verif)
button.pack(side=tk.LEFT, padx=5)

text_area = scrolledtext.ScrolledText(volet, width=85, height=10, wrap=tk.WORD)
text_area.pack(padx=10, pady=10)

entry2 = tk.Entry(frame, width=30)
entry2.pack(padx=10, pady=10)
entry2.insert(0, "Erreurs : ")
entry2.configure(state="readonly")

window.mainloop()

0