#!/usr/bin/env python3 """ Extraction des KPIs des feuilles de route COP régionales et génération d'un fichier Excel de comparaison. Inclut les 4 régions : Grand Est, Occitanie, AURA, Normandie avec numéros de pages sources. """ from openpyxl import Workbook from openpyxl.styles import Font, PatternFill, Alignment, Border, Side from openpyxl.utils import get_column_letter wb = Workbook() # ============================================================ # Couleurs & styles gouvernementaux # ============================================================ BLEU_MARIANNE = "000091" BLEU_CLAIR = "E3E3FD" GRIS_CLAIR = "F5F5F5" BLANC = "FFFFFF" NOIR = "161616" header_font = Font(name="Marianne", bold=True, color=BLANC, size=11) header_fill = PatternFill(start_color=BLEU_MARIANNE, end_color=BLEU_MARIANNE, fill_type="solid") category_font = Font(name="Marianne", bold=True, color=BLEU_MARIANNE, size=11) category_fill = PatternFill(start_color=BLEU_CLAIR, end_color=BLEU_CLAIR, fill_type="solid") normal_font = Font(name="Marianne", size=10, color=NOIR) na_font = Font(name="Marianne", size=10, color="929292", italic=True) link_font = Font(name="Marianne", size=8, color="000091", italic=True) thin_border = Border( left=Side(style="thin", color="CCCCCC"), right=Side(style="thin", color="CCCCCC"), top=Side(style="thin", color="CCCCCC"), bottom=Side(style="thin", color="CCCCCC"), ) wrap_alignment = Alignment(wrap_text=True, vertical="top") # ============================================================ # URLs des documents sources # ============================================================ URLS = { "grand_est": "https://www.prefectures-regions.gouv.fr/grand-est/grand-est/irecontenu/telechargement/120569/895203/file/20240927_Grand_Est_Planification_ecologique_feuille_de_route.pdf", "occitanie": "https://www.prefectures-regions.gouv.fr/occitanie/irecontenu/telechargement/123908/917834/file/feuille_de_route_cop.pdf", "aura": "https://www.prefectures-regions.gouv.fr/content/download/133679/980081/version/1/file/COP-AURA_202512-feuilleroute+COP+regional.pdf", "normandie": "https://www.prefectures-regions.gouv.fr/normandie/irecontenu/telechargement/122983/912028/file/COP%20Normandie_FDR%20vf.pdf", } # ============================================================ # Données KPIs extraites des PDFs (avec pages sources) # ============================================================ kpis = [ # --- TRANSPORTS & MOBILITÉS --- { "categorie": "Transports & Mobilités", "indicateur": "Réduction émissions GES transports", "unite": "ktCO2eq", "grand_est": "25% des leviers régionaux", "grand_est_page": 16, "occitanie": "-4 967 ktCO2eq d'ici 2030 vs 2019", "occitanie_page": 21, "aura": "-30% émissions (14,3 MtCO2eq en 2022)", "aura_page": 15, "normandie": "6% de l'effort national GES, enjeux forts transport", "normandie_page": 3, }, { "categorie": "Transports & Mobilités", "indicateur": "Usage du vélo / mobilité active", "unite": "% déplacements", "grand_est": "Non chiffré spécifiquement", "grand_est_page": 17, "occitanie": "×4 usage vélo → 12% des déplacements d'ici 2030", "occitanie_page": 22, "aura": "Développer mobilité active (pas de cible vélo seul)", "aura_page": 15, "normandie": "Voiries cyclables + schéma directeur vélo + tourisme à vélo", "normandie_page": 8, }, { "categorie": "Transports & Mobilités", "indicateur": "Aménagements cyclables", "unite": "km", "grand_est": "Non chiffré", "grand_est_page": 17, "occitanie": "7 499 km sécurisés d'ici 2026", "occitanie_page": 22, "aura": "Non chiffré spécifiquement", "aura_page": 15, "normandie": "Schéma directeur vélo (non chiffré)", "normandie_page": 8, }, { "categorie": "Transports & Mobilités", "indicateur": "Véhicules électriques", "unite": "multiplicateur / %", "grand_est": "1/6 des véhicules (~460 000 VE)", "grand_est_page": 16, "occitanie": "×14 le nombre de VE (2021-2030)", "occitanie_page": 26, "aura": "15% de VE légers en 2030", "aura_page": 15, "normandie": "Décarboner flottes employeurs", "normandie_page": 8, }, { "categorie": "Transports & Mobilités", "indicateur": "Points de recharge VE", "unite": "nombre", "grand_est": "100% territoire maillé", "grand_est_page": 13, "occitanie": "17 701 points de recharge d'ici 2026", "occitanie_page": 26, "aura": "Non chiffré spécifiquement", "aura_page": 15, "normandie": "Infrastructure recharge (électrique, H2, BioGNV)", "normandie_page": 9, }, { "categorie": "Transports & Mobilités", "indicateur": "Report modal fret (rail & fleuve)", "unite": "%", "grand_est": "25% de report modal fret", "grand_est_page": 16, "occitanie": "×2 part ferroviaire ; +50% fluvial", "occitanie_page": 107, "aura": "-10% transport routier marchandises", "aura_page": 15, "normandie": "Multimodalité, ferroutage, réseau ferroviaire/fluvial", "normandie_page": 8, }, { "categorie": "Transports & Mobilités", "indicateur": "Bus et cars décarbonés", "unite": "% ou nombre", "grand_est": "~900 bus/cars décarbonés en 2030", "grand_est_page": 16, "occitanie": "15% flotte décarbonée en 2030", "occitanie_page": 107, "aura": "Non chiffré spécifiquement", "aura_page": 15, "normandie": "Décarboner flottes bus et cars (Bio GNV, H2…)", "normandie_page": 8, }, { "categorie": "Transports & Mobilités", "indicateur": "Réduction usage voiture individuelle", "unite": "%", "grand_est": "-5% conso au 100 des thermiques", "grand_est_page": 16, "occitanie": "-4% distance/voiture/an", "occitanie_page": 107, "aura": "-15% voiture ; -10% déplacements", "aura_page": 15, "normandie": "Covoiturage + télétravail + réduction dépl. domicile-travail", "normandie_page": 8, }, # --- BÂTIMENT --- { "categorie": "Bâtiment : Résidentiel & Tertiaire", "indicateur": "Réduction conso énergétique résidentiel", "unite": "% vs 2019", "grand_est": "-15%", "grand_est_page": 18, "occitanie": "-15% vs 2019", "occitanie_page": 31, "aura": "-15% vs 2019", "aura_page": 16, "normandie": "Mobilisation SPRH + rénovations performantes", "normandie_page": 10, }, { "categorie": "Bâtiment : Résidentiel & Tertiaire", "indicateur": "Réduction conso énergétique tertiaire", "unite": "% vs réf.", "grand_est": "-33%", "grand_est_page": 18, "occitanie": "-40% vs 2010", "occitanie_page": 31, "aura": "-30% vs 2019", "aura_page": 16, "normandie": "Plate-forme OPERAT + sobriété tertiaire", "normandie_page": 10, }, { "categorie": "Bâtiment : Résidentiel & Tertiaire", "indicateur": "Passoires thermiques (F et G)", "unite": "% ou logements/an", "grand_est": "Non chiffré spécifiquement", "grand_est_page": 18, "occitanie": "-60% passoires vs 2021 (178 000 RP)", "occitanie_page": 31, "aura": "80 000 logements rénovés/an", "aura_page": 16, "normandie": "SPRH ANAH + rénovations performantes", "normandie_page": 10, }, { "categorie": "Bâtiment : Résidentiel & Tertiaire", "indicateur": "Remplacement chaudières fioul", "unite": "% vs 2019", "grand_est": "÷4 résidences avec chaudière fioul", "grand_est_page": 18, "occitanie": "-75% chaudières fioul résidentiel", "occitanie_page": 108, "aura": "Non chiffré spécifiquement", "aura_page": 16, "normandie": "Incitation aux énergies décarbonées", "normandie_page": 11, }, { "categorie": "Bâtiment : Résidentiel & Tertiaire", "indicateur": "Remplacement chaudières gaz", "unite": "% vs 2019", "grand_est": "-25% résidences chaudière gaz", "grand_est_page": 18, "occitanie": "-20% chaudières gaz résidentiel", "occitanie_page": 108, "aura": "Non chiffré (gaz = 60% émissions bât.)", "aura_page": 16, "normandie": "Non chiffré", "normandie_page": None, }, # --- ÉNERGIE --- { "categorie": "Énergie & Économie circulaire", "indicateur": "Production ENR - Éolien terrestre", "unite": "TWh", "grand_est": "2ᵉ région éolienne (non chiffré)", "grand_est_page": 22, "occitanie": "×2,5 (3,2 → 7,9 TWh) d'ici 2031", "occitanie_page": 108, "aura": "+50% élec. renouvelable d'ici 2030", "aura_page": 18, "normandie": "Zones d'accélération EnR", "normandie_page": 15, }, { "categorie": "Énergie & Économie circulaire", "indicateur": "Production ENR - Photovoltaïque", "unite": "TWh / MW", "grand_est": "Non chiffré", "grand_est_page": 22, "occitanie": "×2 PV (4,1 → 9 TWh) ; 7 000 MW", "occitanie_page": 108, "aura": "Inclus dans +50% élec. renouvelable", "aura_page": 18, "normandie": "Structurer filière PV + autoconsommation", "normandie_page": 16, }, { "categorie": "Énergie & Économie circulaire", "indicateur": "Production biogaz / biométhane", "unite": "multiplicateur", "grand_est": "Non chiffré", "grand_est_page": 22, "occitanie": "×10 (0,3 → 3 TWh/an) d'ici 2031", "occitanie_page": 108, "aura": "Non chiffré", "aura_page": 18, "normandie": "Métha'Normandie + gaz verts", "normandie_page": 16, }, { "categorie": "Énergie & Économie circulaire", "indicateur": "Chaleur renouvelable", "unite": "TWh", "grand_est": "Synergies chaleur fatale", "grand_est_page": 23, "occitanie": "×2 à ×4 chaleur livrée", "occitanie_page": 108, "aura": ">30 TWh chaleur renouvelable", "aura_page": 18, "normandie": "Récupération chaleur fatale industrielle", "normandie_page": 17, }, { "categorie": "Énergie & Économie circulaire", "indicateur": "ENR citoyens / participatifs", "unite": "nombre", "grand_est": "500 GWh ; ×3 capacité EnR citoyens", "grand_est_page": 23, "occitanie": "100 000 citoyens ; 500 projets", "occitanie_page": 39, "aura": "Non chiffré", "aura_page": None, "normandie": "Financements participatifs (Kiwai Normandie)", "normandie_page": 16, }, # --- INDUSTRIE --- { "categorie": "Industrie & Emploi", "indicateur": "Réduction émissions industrielles", "unite": "% ou ktCO2eq", "grand_est": "27% effort régional ; 14/50 sites", "grand_est_page": 24, "occitanie": "-31% (3 446 → 2 390 ktCO2eq)", "occitanie_page": 108, "aura": "-40% pour 90 sites", "aura_page": 17, "normandie": "Programme ZIBAC-SOCRATE + PACTE Industrie", "normandie_page": 15, }, { "categorie": "Industrie & Emploi", "indicateur": "Décarbonation gros émetteurs", "unite": "%", "grand_est": "14 gros sites accompagnés", "grand_est_page": 25, "occitanie": "-40% GES des 70 plus gros", "occitanie_page": 43, "aura": "-40% GES des 90 sites", "aura_page": 17, "normandie": "Feuilles de route décarbonation gros émetteurs", "normandie_page": 17, }, { "categorie": "Industrie & Emploi", "indicateur": "Décarbonation PME / industrie diffuse", "unite": "%", "grand_est": "Accompagner toutes les entreprises", "grand_est_page": 25, "occitanie": "-30% GES secteur diffus", "occitanie_page": 46, "aura": "100% mobilisation TPE/PME/ETI", "aura_page": 17, "normandie": "Amplifier sensibilisation PME + dispositifs", "normandie_page": 17, }, # --- BIODIVERSITÉ --- { "categorie": "Biodiversité, Eau & Sols", "indicateur": "Réduction prélèvements eau", "unite": "% vs réf.", "grand_est": "-10%", "grand_est_page": 14, "occitanie": "-10% vs 2022", "occitanie_page": 109, "aura": "-10% d'ici 2030", "aura_page": 14, "normandie": "Études volumes prélevables + eaux non conventionnelles", "normandie_page": 12, }, { "categorie": "Biodiversité, Eau & Sols", "indicateur": "Réduction artificialisation (ZAN)", "unite": "% ou ha", "grand_est": "÷2 conso ENAF d'ici 2031", "grand_est_page": 14, "occitanie": "÷2 (max 14 000 ha sur 2021-2030)", "occitanie_page": 34, "aura": "-50% conso ENAF ; 1 000 ha désimperméabilisés", "aura_page": 14, "normandie": "Désimperméabilisation + renaturation friches", "normandie_page": 14, }, { "categorie": "Biodiversité, Eau & Sols", "indicateur": "Zones humides / tourbières", "unite": "ha / opérations", "grand_est": "10 opérations ; 1 000 ha/an", "grand_est_page": 29, "occitanie": "Non chiffré", "occitanie_page": None, "aura": "Non chiffré", "aura_page": None, "normandie": "Programme régional restauration tourbières", "normandie_page": 12, }, { "categorie": "Biodiversité, Eau & Sols", "indicateur": "Continuités écologiques - Points noirs", "unite": "% résorbés", "grand_est": "100% résorbés d'ici 2030", "grand_est_page": 30, "occitanie": "Identifier/résorber d'ici 2030", "occitanie_page": 110, "aura": "100% de résorption d'ici 2030", "aura_page": 14, "normandie": "Trajectoire écologique habitats naturels", "normandie_page": 12, }, # --- AGRICULTURE --- { "categorie": "Agriculture, Forêt & Alimentation", "indicateur": "Plantation d'arbres", "unite": "millions d'arbres", "grand_est": "89 millions d'ici 2026", "grand_est_page": 20, "occitanie": "11 millions d'ici 2026", "occitanie_page": 109, "aura": "Non chiffré", "aura_page": None, "normandie": "Renouvellement peuplements forestiers fragilisés", "normandie_page": 13, }, { "categorie": "Agriculture, Forêt & Alimentation", "indicateur": "Linéaire de haies / bocage", "unite": "km", "grand_est": "+4 000 km de haies vs 2019", "grand_est_page": 20, "occitanie": "Non chiffré", "occitanie_page": None, "aura": "Non chiffré", "aura_page": None, "normandie": "Plans d'actions plantation + maintien bocage", "normandie_page": 12, }, { "categorie": "Agriculture, Forêt & Alimentation", "indicateur": "Surfaces en légumineuses", "unite": "ha", "grand_est": "×2 les surfaces", "grand_est_page": 20, "occitanie": "+100 000 ha d'ici 2030", "occitanie_page": 109, "aura": "Non traité", "aura_page": None, "normandie": "Progresser en légumineuses (alimentation animale et humaine)", "normandie_page": 18, }, # --- DÉCHETS --- { "categorie": "Déchets", "indicateur": "Réduction déchets ménagers (DMA)", "unite": "kg/hab/an ou %", "grand_est": "-85 kg/hab/an vs 2019", "grand_est_page": 22, "occitanie": "-108 kg/hab vs 2010", "occitanie_page": 108, "aura": "Zéro enfouissement d'ici 2030", "aura_page": 19, "normandie": "Prévention + consommation responsable + arrêt collecte déchets verts PAP", "normandie_page": 20, }, { "categorie": "Déchets", "indicateur": "Valorisation des déchets", "unite": "kg/hab/an ou %", "grand_est": "+68 kg/hab/an valorisés vs 2019", "grand_est_page": 22, "occitanie": "57% valorisation matière ; 90% bouteilles plastiques", "occitanie_page": 108, "aura": "Développer recyclage et réemploi", "aura_page": 19, "normandie": "Valorisation BTP + textiles >60% + déchets organiques", "normandie_page": 20, }, { "categorie": "Déchets", "indicateur": "Tarification incitative", "unite": "habitants ou %", "grand_est": "Non chiffré", "grand_est_page": None, "occitanie": "2,1M hab. en tarif. incitative d'ici 2031", "occitanie_page": 108, "aura": "Non chiffré", "aura_page": None, "normandie": "Généraliser la redevance incitative", "normandie_page": 20, }, # --- EMPLOI --- { "categorie": "Emploi & Formation", "indicateur": "Professionnels rénovation / BTP", "unite": "nombre", "grand_est": "Augmenter nombre RGE", "grand_est_page": 25, "occitanie": "Non chiffré", "occitanie_page": None, "aura": "Former +2,8M personnes (national)", "aura_page": 21, "normandie": "Montée en compétences BTP + rénovateurs BBC + RGE", "normandie_page": 10, }, { "categorie": "Emploi & Formation", "indicateur": "Accompagnement entreprises transition", "unite": "nombre", "grand_est": "Non chiffré", "grand_est_page": None, "occitanie": "2 000 entreprises (2025-2027)", "occitanie_page": 87, "aura": "100% mobilisation TPE/PME/ETI", "aura_page": 17, "normandie": "Identification évolutions métiers + formation continue", "normandie_page": 24, }, ] # ============================================================ # Création de la feuille Excel # ============================================================ ws = wb.active ws.title = "KPIs COP Régionales" # En-têtes headers = ["Catégorie", "Indicateur / KPI", "Unité", "Grand Est", "Page GE", "Occitanie", "Page Occ.", "Auvergne-Rhône-Alpes", "Page AURA", "Normandie", "Page Norm."] col_widths = [30, 40, 18, 45, 8, 45, 8, 45, 8, 45, 8] for col_idx, (header, width) in enumerate(zip(headers, col_widths), 1): cell = ws.cell(row=1, column=col_idx, value=header) cell.font = header_font cell.fill = header_fill cell.alignment = Alignment(wrap_text=True, vertical="center", horizontal="center") cell.border = thin_border ws.column_dimensions[get_column_letter(col_idx)].width = width ws.row_dimensions[1].height = 30 # Données current_category = "" row = 2 for kpi in kpis: cat = kpi["categorie"] # Ligne catégorie si nouvelle if cat != current_category: if current_category != "": row += 1 # ligne vide entre catégories for col_idx in range(1, len(headers) + 1): cell = ws.cell(row=row, column=col_idx) cell.fill = category_fill cell.border = thin_border if col_idx == 1: cell.value = cat cell.font = category_font cell.alignment = wrap_alignment ws.row_dimensions[row].height = 25 row += 1 current_category = cat values = [ cat, kpi["indicateur"], kpi["unite"], kpi["grand_est"], kpi.get("grand_est_page", ""), kpi["occitanie"], kpi.get("occitanie_page", ""), kpi["aura"], kpi.get("aura_page", ""), kpi["normandie"], kpi.get("normandie_page", ""), ] for col_idx, val in enumerate(values, 1): cell = ws.cell(row=row, column=col_idx, value=val if val is not None else "") cell.border = thin_border cell.alignment = wrap_alignment # Page columns if col_idx in (5, 7, 9, 11) and val: cell.font = link_font elif val and ("Non" in str(val) or str(val) == ""): cell.font = na_font else: cell.font = normal_font # Alternance couleurs if row % 2 == 0: cell.fill = PatternFill(start_color=GRIS_CLAIR, end_color=GRIS_CLAIR, fill_type="solid") ws.row_dimensions[row].height = 50 row += 1 # Freeze panes ws.freeze_panes = "A2" ws.auto_filter.ref = f"A1:K{row-1}" # ============================================================ # Feuille de métadonnées # ============================================================ ws2 = wb.create_sheet("Sources & Métadonnées") meta = [ ["Région", "URL du document", "Pages"], ["Grand Est", URLS["grand_est"], "71 pages"], ["Occitanie", URLS["occitanie"], "116 pages"], ["Auvergne-Rhône-Alpes", URLS["aura"], "198 pages"], ["Normandie", URLS["normandie"], "31 pages — OCR Mistral (document basé sur images)"], [], ["Note", "Les objectifs et KPIs sont extraits des documents officiels des COP régionales."], ["Note", "Les horizons temporels varient selon les régions (2030 ou 2031 principalement)."], ["Note", "Les unités et périmètres ne sont pas toujours strictement identiques entre régions."], ["Note", "Le PDF Normandie était basé sur des images : extraction via OCR Mistral (mistral-ocr-latest)."], ["Date", "Extraction réalisée en février 2025"], ] for r, row_data in enumerate(meta, 1): for c, val in enumerate(row_data, 1): cell = ws2.cell(row=r, column=c, value=val) if r == 1: cell.font = header_font cell.fill = header_fill elif c == 1: cell.font = Font(bold=True, name="Marianne", size=10) else: cell.font = Font(name="Marianne", size=10) ws2.column_dimensions["A"].width = 25 ws2.column_dimensions["B"].width = 100 ws2.column_dimensions["C"].width = 50 output_path = "/home/qdonnars/projects/chat_perso/COP/KPIs_COP_Regionales.xlsx" wb.save(output_path) print(f"Excel sauvegardé : {output_path}")