Téléverser les fichiers vers "/"

This commit is contained in:
antoinewg 2026-03-18 15:31:47 -04:00
parent c5209635a2
commit d79999c56b
4 changed files with 860 additions and 0 deletions

59
UDS.html Normal file
View File

@ -0,0 +1,59 @@
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Générer UDS/RSA</title>
<style>
body { font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; padding: 20px; max-width: 900px; margin: auto; }
input, select, button, textarea { font-size: 14px; padding: 8px; margin: 6px 0; width: 100%; box-sizing: border-box; }
label { font-weight: 600; margin-top: 12px; display:block; }
.row { display:flex; gap:12px; }
.col { flex:1; }
pre { background:#f6f6f6; padding:12px; overflow:auto; }
.downloads a { display:block; margin:6px 0; }
.status { color: #444; margin:8px 0; }
</style>
</head>
<body>
<h1>Générer UDS/RSA</h1>
<p>Télécharge le <strong>template Excel</strong> (UDS.xlsx or RSA.xlsx) et le <strong>fichier texte</strong> (.txt). Entrer le nom du releveur et la hauteur de l'appareil de mesure.</p>
<label>Type de document</label>
<select id="typedoc">
<option value="uds">uds</option>
<option value="rsa">rsa</option>
</select>
<div class="row">
<div class="col">
<label>Template Excel (ex: UDS.xlsx or RSA.xlsx)</label>
<input type="file" id="template_excel" accept=".xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
</div>
<div class="col">
<label>Fichier texte (input)</label>
<input type="file" id="txt_input" accept=".txt,text/plain" />
</div>
</div>
<label>Nom du releveur</label>
<input id="nom_releveur" placeholder="Antoine / Nom" />
<label>Hauteur Bosch (ex: 1.5)</label>
<input id="hauteur_bosch" placeholder="1.5" />
<button id="runBtn">Run & Generate Excel files</button>
<div class="status" id="status">Pyodide non chargé.</div>
<h3>Downloads</h3>
<div class="downloads" id="downloads"></div>
<h3>Log / Output</h3>
<pre id="log"></pre>
<script src="uds.js"></script>

658
UDS.py Normal file
View File

@ -0,0 +1,658 @@
import sys
from openpyxl import load_workbook
import shutil
import random
import re
from datetime import date
# =================================================================
#CODE POUR CRÉER L'EXCEL DE L'UDS ET RSA AVEC UN FICHIER TXT QUI SERT A NE PAS RECOPIER LES DONNÉE POUR SAUVER DU TEMPS
# le but du code est de linker deux dictionaire, le dictionnaire cell qui contient la valeur les cellule des variables et
# dictionaire valeurs qui contient les valeurs des variables, le dictionaire valeur sera créer au fure et a mesure dans la lecture du fichier txt
# pour déterminer que la fiche du poteau est finie on met --- a la fin ce qui va arreter la lecture et commencer le processus de la création de l'excel
# deux variable vont etre créer champs et val qui seront le link entre les deux dictionaire ce qui va faire en sorte de link la valeur avec les cellule car les deux dictionaires ont les mee variable
# il y a quelques regles pour certaine variable les ''if'' dans la section ou on lie le fichier txt et quelques autre dictionnaire pas besoin de les comprendre pour comprendre le code
# on déclenche le code avec deux arguments si c'est un uds rsa et ou le fichier text se trouve par exemple rsa C:\Users\Antoine\PycharmProjects\UDS\PDF.py rsa C:\Users\Antoine\PycharmProjects\UDS\test.txt
# donc (ou se trouve le script)+(argument 1:rsa ou uds?) +(argument 2:ou se trouve le fichier texte), il faut faire la commande dans cmd.
# =====================================================================
if len(sys.argv) < 2:
print("manque de parametres: argument 1 = type de fichier,argument 2 = fichier path") #python C:\Users\Antoine\PycharmProjects\UDS\UDS.py rsa C:\Users\Antoine\PycharmProjects\UDS\RSA_UDS.txt
sys.exit()
typeDoc = sys.argv[1]
docTxt = sys.argv[2]
nom_du_releveur = input('Nom du releveur: ')
hauteur_bosch = input("rentrer la hauteur de l'appareil par rapport au sol lors des mesures: ")
cells = {}
if typeDoc == "uds":
cells = {
"poteau": "B4",
"projet": "K3",
"révision": "O3",
"travaux": "B3",
"diametre": "H3",
"adresse": "K4",
"plan": "H4",
"code_barre": "N6",
"pro_poteau": "K7",
"annee_inspection": "H5",
"parc": "K5",
"option_HQ":"N5",
"longueur": "C6",
"classe": "D6",
"annee": "H6",
"circonference": "K6",
"p/r":"D7",
"usage_commun:": "O7",
"angle": "K13",
"lclc": "K14",
"nbe_transfo": "L15",
"type_transfo": "K15",
"equip": "K16",
"gradation": "K17",
"lampadaire":"K18",
"las":"K19",
"montage_HQ":"K20",
"portee_lache":"K21",
"portee_pre:": "K22",
"portee_sui:": "N22",
"malt":"N21",
"reseau":"N20",
"cabinet":"O19",
"luminaire":"N18",
"traverse":"O17",
"las":"N16",
"fosse": "O14",
"hauteur_transfo": "O15",
"hauteur_top": "A11",
"portee_pre:": "B14",
"portee_sui:": "C14",
"hauteur_mt1": "A14",
"conducteur_mt1": "C14",
"phase_mt1": "B14",
"deri_mt1": "D14",
"hauteur_mt2": "A15",
"conducteur_mt2": "C15",
"phase_mt2": "B15",
"deri_mt2": "D15",
"hauteur_mt3:": "A16",
"conducteur_mt3": "C16",
"phase_mt3": "B16",
"deri_mt3": "D16",
"hauteur_bt1": "A23",
"conducteur_bt1": "B23",
"visee_bt1": "C23",
"deri_bt1": "D23",
"hauteur_bt2": "A22",
"conducteur_bt2": "B22",
"visee_bt2": "C22",
"deri_bt2": "D22",
"hauteur_bt3": "A21",
"conducteur_mbt3": "B21",
"visee_bt3": "C21",
"deri_bt3": "D21",
"hauteur_bt4": "A20",
"conducteur_bt4": "B20",
"visee_bt4": "C20",
"deri_bt4": "D20",
"hauteur_bt5": "A19",
"conducteur_bt5": "B19",
"visee_bt5": "C19",
"deri_bt5": "D19",
"hauteur_bt6": "A18",
"conducteur_bt6:": "B18",
"visee_bt6": "C18",
"deri_bt6": "D18",
"hauteur_toron1": "A27",
"proprio_toron1": "B27",
"toron1_existant": "C27",
"deri":"D27",
"type_toron1": "J27",
"nbe_de_cable_toron1": "L27",
"diametre_toron1": "K27",
"rupture_toron1": "M27",
"deg_sol_toron1": "N27",
"ancre_toron1": "O27",
"hauteur_toron2": "A28",
"proprio_toron2": "B28",
"existant_toron2": "C28",
"deri_toron2": "D28",
"type_toron2": "J28",
"nbe_de_cable_toron2": "L28",
"diametre_toron2": "K28",
"rupture_toron2": "M28",
"deg_sol_toron2": "N28",
"ancre_toron2": "O28",
"hauteur_toron3": "A29",
"proprio_toron3": "B29",
"existant_toron3": "C29",
"deri_toron3": "D29",
"type_toron3": "J29",
"nbe_de_cable_toron3": "L29",
"diametre_toron3": "K29",
"rupture_toron3": "M29",
"deg_sol_toron3": "N29",
"ancre_toron3": "O29",
"hauteur_toron4": "A30",
"proprio_toron4": "B30",
"existant_toron4": "C30",
"deri_toron4": "D30",
"type_toron4": "J30",
"nbe_de_cable_toron4": "L30",
"diametre_toron4": "K30",
"rupture_toron4": "M30",
"deg_sol_toron4": "N30",
"ancre_toron4": "O30",
"hauteur_toron5": "A31",
"proprio_toron5": "B31",
"existant_toron5": "C31",
"deri_toron5": "D31",
"type_toron5": "J31",
"nbe_de_cable_toron5": "L31",
"diametre_toron5": "K31",
"rupture_toron5": "M31",
"deg_sol_toron5": "N31",
"ancre_toron5": "O31",
"hauteur_toron6": "A32",
"proprio_toron6": "B32",
"existant_toron6": "C32",
"deri_toron6": "D32",
"type_toron6": "J32",
"nbe_de_cable_toron6": "L32",
"diametre_toron6": "K32",
"rupture_toron6": "M32",
"deg_sol_toron6": "N32",
"ancre_toron6": "O32",
"type_de_sol_ancre1": "K36",
"capacite_ancre1": "K37",
"angle_ancre1":"K38",
"hauban1_ancre1": "K39",
"hauban2_ancre1": "K40",
"hauban3_ancre1": "K41",
"hauban4_ancre1": "K42",
"tige_ancre1":"K43",
"cosse_ancre1": "K44",
"ecart_ancre1": "K45",
"type_ancre1": "K46",
"devi_ancre1": "K47",
"espace_dispo_ancre1": "K48",
"etat_ancre1": "K49",
"type_de_sol_ancre2": "M36",
"capacite_ancre2": "M37",
"angle_ancre2":"M38",
"hauban1_ancre2": "M39",
"hauban2_ancre2": "M40",
"hauban3_ancre2": "M41",
"hauban4_ancre2": "M42",
"tige_ancre2":"M43",
"cosse_ancre2": "M44",
"ecart_ancre2": "M45",
"type_ancre2": "M46",
"devi_ancre2": "M47",
"espace_dispo_ancre2": "M48",
"etat_ancre2": "M49",
"type_de_sol_ancre3": "N36",
"capacite_ancre3": "N37",
"angle_ancre3": "N38",
"hauban1_ancre3": "N39",
"hauban2_ancre3": "N40",
"hauban3_ancre3": "N41",
"hauban4_ancre3": "N42",
"tige_ancre3": "N43",
"cosse_ancre3": "N44",
"ecart_ancre3": "N45",
"type_ancre3": "N46",
"devi_ancre3": "N47",
"espace_dispo_ancre3": "N48",
"etat_ancre3": "N49",
"type_de_sol_ancre4": "O36",
"capacite_ancre4": "O37",
"angle_ancre4": "O38",
"hauban1_ancre4": "O39",
"hauban2_ancre4": "O40",
"hauban3_ancre4": "O41",
"hauban4_ancre4": "O42",
"tige_ancre4": "O43",
"cosse_ancre4": "O44",
"ecart_ancre4": "O45",
"type_ancre4": "O46",
"devi_ancre4": "O47",
"espace_dispo_ancre4": "O48",
"etat_ancre4": "O49",
"ligne_haute_tension": "K51",
"element_sensible": "O51",
"note": "A56",
"date": "K62",
}
elif typeDoc == "rsa":
cells = {
"poteau": "B1",
"projet": "F1",
"révision": "I1",
"travaux": "B2",
"diametre": "D2",
"classification_travaux":'F2',
"anomalie_1": "B3",
"anomalie_2": "B4",
"anomalie_3": "B5",
"probleme_1": "E3",
"probleme_2": "E4",
"probleme_3": "E5",
"nom_poteau": "B6",
"adresse": "D6",
"plan": "G6",
"code_barre": "I6",
"pro_poteau": "B7",
"usage_commun:": "D7",
"parc": "F7",
"lclc": "I7",
"longueur": "B8",
"classe": "D8",
"annee": "F8",
"nbe_transfo": "H8",
"type_transfo": "I8",
"annee_inspection": "B9",
"modele_bell": "D9",
"modele_HQ": "F9",
"equip": "H9",
"fosse": "B9",
"hauteur_lampadaire": "D10",
"cabinet": "F10",
"hauteur_transfo": "H10",
"hauteur_top": "A14",
"portee_pre:": "B14",
"portee_sui:": "C14",
"portee_dero": "D14",
"toron_ins": "E14",
"milieu": "G13",
"hauteur_mt1": "A16",
"conducteur_mt1": "B16",
"phase_mt1": "C16",
"deri_mt1": "D16",
"hauteur_mt2": "A17",
"conducteur_mt2": "B17",
"phase_mt2": "C17",
"deri_mt2": "D17",
"hauteur_mt3:": "A18",
"conducteur_mt3": "B18",
"phase_mt3": "C18",
"deri_mt3": "D18",
"hauteur_mt4": "A19",
"conducteur_mt4": "B19",
"phase_mt4": "C19",
"deri_mt4": "D19",
"hauteur_mt5": "A20",
"conducteur_mt5:": "B20",
"phase_mt5": "C20",
"deri_mt5": "D20",
"hauteur_bt1": "A27",
"conducteur_bt1": "B27",
"visee_bt1": "C27",
"deri_bt1": "D27",
"hauteur_bt2": "A26",
"conducteur_bt2": "B26",
"visee_bt2": "C26",
"deri_bt2": "D26",
"hauteur_bt3": "A25",
"conducteur_mbt3": "B25",
"visee_bt3": "C25",
"deri_bt3": "D25",
"hauteur_bt4": "A24",
"conducteur_bt4": "B24",
"visee_bt4": "C24",
"deri_bt4": "D24",
"hauteur_bt5": "A23",
"conducteur_bt5": "B23",
"visee_bt5": "C23",
"deri_bt5": "D23",
"hauteur_bt6": "A22",
"conducteur_bt6:": "B22",
"visee_bt6": "C22",
"deri_bt6": "D22",
"hauteur_toron1": "A29",
"proprio_toron1": "B29",
"type_toron1": "C29",
"nbe_de_cable_toron1": "D29",
"diametre_toron1": "E29",
"rupture_toron1": "F29",
"deg_sol_toron1": "G29",
"croisement_toron1": "H29",
"ancre_toron1": "I29",
"hauteur_toron2": "A30",
"proprio_toron2": "B30",
"type_toron2": "C30",
"nbe_de_cable_toron2": "D30",
"diametre_toron2": "E30",
"rupture_toron2": "F30",
"deg_sol_toron2": "G30",
"croisement_toron2": "H30",
"ancre_toron2": "I30",
"hauteur_toron3": "A31",
"proprio_toron3": "B31",
"type_toron3": "C31",
"nbe_de_cable_toron3": "D31",
"diametre_toron3": "E31",
"rupture_toron3": "F31",
"deg_sol_toron3": "G31",
"croisement_toron3": "H31",
"ancre_toron3": "I31",
"hauteur_toron4": "A32",
"proprio_toron4": "B32",
"type_toron4": "C32",
"nbe_de_cable_toron4": "D32",
"diametre_toron4": "E32",
"rupture_toron4": "F32",
"deg_sol_toron4": "G32",
"croisement_toron4": "H32",
"ancre_toron4": "I32",
"hauteur_toron5": "A33",
"proprio_toron5": "B33",
"type_toron5": "C33",
"nbe_de_cable_toron5": "D33",
"diametre_toron5": "E33",
"rupture_toron5": "F33",
"deg_sol_toron5": "G33",
"croisement_toron5": "H33",
"ancre_toron5": "I33",
"hauteur_toron6": "A34",
"proprio_toron6": "B34",
"type_toron6": "C34",
"nbe_de_cable_toron6": "D34",
"diametre_toron6": "E34",
"rupture_toron6": "F34",
"deg_sol_toron6": "G34",
"croisement_toron6": "H34",
"ancre_toron6": "I34" ,
"type_de_sol_ancre1": "F17",
"tige_ancre1": "F18",
"cosse_ancre1": "F19",
"type_ancre1": "F20",
"ecart_ancre1": "F21",
"hauban1_ancre1": "F22",
"hauban2_ancre1": "F23",
"hauban3_ancre1": "F24",
"hauban4_ancre1": "F25",
"etat_ancre1": "f26",
"espace_dispo_ancre1": "F27",
"type_de_sol_ancre2": "G17",
"tige_ancre2": "G18",
"cosse_ancre2": "G19",
"type_ancre2": "G20",
"ecart_ancre2": "G21",
"hauban1_ancre2": "G22",
"hauban2_ancre2": "G23",
"hauban3_ancre2": "G24",
"hauban4_ancre2": "G25",
"etat_ancre2": "G26",
"espace_dispo_ancre2": "G27",
"type_de_sol_ancre3": "H17",
"tige_ancre3": "H18",
"cosse_ancre3": "H19",
"type_ancre3": "H20",
"ecart_ancre3": "H21",
"hauban1_ancre3": "H22",
"hauban2_ancre3": "H23",
"hauban3_ancre3": "H24",
"hauban4_ancre3": "H25",
"etat_ancre3": "H26",
"espace_dispo_ancre3": "H27",
"type_de_sol_ancre4": "I17",
"tige_ancre4": "I18",
"cosse_ancre4": "I19",
"type_ancre4": "I20",
"ecart_ancre4": "I21",
"hauban1_ancre4": "I22",
"hauban2_ancre4": "I23",
"hauban3_ancre4": "I24",
"hauban4_ancre4": "I25",
"etat_ancre4": "I26",
"espace_dispo_ancre4": "I27" ,
"ligne_haute_tension": "A36",
"dis_appro": "C36",
"element_sensible": "D36",
"coord": "G36",
"note": "A38",
"date": "F49",
}
else:
print("Erreur: veuiller fournir parametre 1 = (uds ou rsa)")
sys.exit()
type_poteaux = {
74:(35, 5),
79:{'JP': (35, 5), 'SYP': (40, 5), 'LPP': (35, 5)},
80:(35, 4),
81:(35, 5),
82:(45, 5),
83:{'LPP': (40, 5), 'WRC': (35, 5)},
84:(40, 5),
86:{'RP': (40, 5), 'JP': (35, 4)},
87:(45, 5),
88:{'RP': (35, 4), 'JP': (45, 5), 'WRC': (40, 5)},
89:(45, 4),
90:{'RP': (45, 5), 'LPP': (40, 4), 'WRC': (35, 4)},
91:(40, 4),
92:(45, 5),
93:{'RP': (40, 4), 'SYP': (35, 2)},
94:(45, 4),
95:{'JP': (45, 4), 'WRC': (40, 4)},
97:(45, 4),
98: {'SYP': (40, 2), 'LPP': (35, 2)},
99:(35, 2),
100:(45, 4),
101:(35, 2),
103:{'SYP': (45, 2), 'WRC': (35, 2)},
104:(40, 2),
105:(40, 2),
107:(40, 2),
109:(45, 2),
110:{'JP': (45, 2), 'WRC': (40, 2)},
112:(45, 2),
115:(45, 2),
}
parc = {
"304":("saint-remi","saint-michel","sherrington"),
"339":("sainte-clotilde","saint-chrysostome","hemmingford","havelock"),
"303":("franklin","ormstown","saint-antoine","hinchinbrooke","godmanchester","huntingdon","saint-anicet","dundee","elgin"),
"306":("lacolle","napierville","saint-bernard-de-lacolle"),
"363":("saint-barbe","saint-stanislas-de-kostka","saint-etienne-de-beauharnois","saint-louis-de-gonzague"),
}
valeurs = {} # on crée le dictionnaire valeur qui va nous serir a linker le dictionnaire cell
def create_excel(valeurs): #fonction créant l'excel on envoit la blibliotheque qu'on a créer en lisant le fichier txt
nom_du_poteau = valeurs['poteau'].strip() + '.xlsx' #permet de donner le nom à l'excel par le nom du poteau
if typeDoc == "rsa":
shutil.copyfile('C:\\Users\\Antoine\\PycharmProjects\\UDS\\RSA.xlsx',
f'C:\\Users\\Antoine\\PycharmProjects\\UDS\\{nom_du_poteau}') #copie le template et donne un nom au fichier correspondant au nom du poteuu
wb = load_workbook(f'C:\\Users\\Antoine\\PycharmProjects\\UDS\\{nom_du_poteau}') #load la copie pour écrire dedans
ws = wb['Grille'] # Sélectionner la feuille active (ou une feuille spécifique)
elif typeDoc == "uds":
shutil.copyfile('C:\\Users\\Antoine\\PycharmProjects\\UDS\\UDS.xlsx',
f'C:\\Users\\Antoine\\PycharmProjects\\UDS\\{nom_du_poteau}') # copie le template et donne un nom au fichier
wb = load_workbook(f'C:\\Users\\Antoine\\PycharmProjects\\UDS\\{nom_du_poteau}')
ws = wb['Grille'] # Sélectionner la feuille active (ou une feuille spécifique)
for key in valeurs:
try:
champs=cells[key] #champs contient la valeur de la cellule
val=valeurs[key] # crée deux valeurs à partir du même key(variable) qui est la variable ce qui lie les deux blibliotheques cells et valeurs, donc la valeur a maintenant une cellule ttribué
ws[champs] = val # Écriture
except:
continue
wb.save(f'C:\\Users\\Antoine\\PycharmProjects\\UDS\\{nom_du_poteau}') # Sauvegarder les modifications dans le même fichier
with open(docTxt, 'r') as file: #on lie le document txt pour créer une blibliotheque qui va lier la valeur a la variable et on va créer l'excel
for line in file:
if "---" in line: #a la fin d'une fiche qui finit par --- je créer un excel
create_excel(valeurs) #on commence à écrire l'excel
valeurs.clear() # clear les values dans le dictionaire valeurs
continue
if line.strip() == "": # si il n'y a rien sur la ligne skip permet de laisser des espaces dans le fichier lock
continue
if ':' not in line: # si il y a écrit nimporte quoi on ignore la ligne
continue
line=line.split(":", 1) # explode en deux la variable et la valeur dans un tableau
variable = line[0] #met le premier split dans la valeur variable qui va être notre variable
value=line[1] #met le deuxieme split dans la valeur variable qui va être notre variable
if 'hauteur' in variable: #donne un chiffre aléatoire en string a la fin de la valur pour les hauteurs vu que j'obtient un valeur apres la virgule avec mes mesures
if value.strip() == "":
continue
if value.strip() == 'tri':
valeurs['hauteur_mt1'] = str(float(valeurs['hauteur_top']) + 0.3)
valeurs['hauteur_mt2'] = str(float(valeurs['hauteur_top']) - 0.15)
continue
c = float(value)
a = 1
b = (c**2 - a**2)**0.5 + float(hauteur_bosch)
b = round(b,2)
value = str(b)
if 'nom_poteau' in variable: #copie le valeur poteau dans le nom du poteau pour avoir par example uniquement le PHD49 en gros enleve rl'addresse
value = valeurs["poteau"].split(" ", 1)[0] #split le nom du poteau pour n'avoir que la premiere partie apres l'espace comme phd49
if 'adresse' in variable: #copie le valeur de l'addresse dans le nom du poteau pour avoir par example uniquement le PHD49 en gros enleve rl'addresse
# =================================================================
# Utilise re.sub() pour retirer le texte non numérique au début,
# puis supprimer toute indication de type "+2" ou "-3" accolée
# au numéro principal, en conservant le reste de l'adresse.
#
# Expression utilisée : r'^\D*(\d+)(?:[+-]\d+)?(.*)'
# - ^ → début de la chaîne
# - \D* → zéro ou plusieurs caractères qui NE sont PAS des chiffres
# (supprime par exemple "PHD", "PHC", etc.)
# - (\d+) → capture le numéro principal (un ou plusieurs chiffres)
# - (?: ... ) → parenthèses non capturantes (pour regrouper sans créer un groupe séparé)
# - [+-]\d+ → un signe "+" ou "-" suivi d'un ou plusieurs chiffres
# (par ex. "+2" ou "-3")
# - ? → rend la partie [+-]\d+ optionnelle
# - (.*) → capture tout le reste de la chaîne (l'adresse après le numéro)
#
# Remplacement utilisé : r'\1\2'
# - \1 → insère le numéro principal capturé
# - \2 → insère le texte restant de l'adresse
#
# Exemple :
# "PHD248+2 chemin de l'église" devient "248 chemin de l'église"
# "PHC300-1 rue des lilas" devient "300 rue des lilas"
# =================================================================
value = re.sub(r'^\D*(\d+)(?:[+-]\d+)?(.*)', r'\1\2', valeurs["poteau"]) # oon efface la partie PHD,PHC,PHO et le + ou le - pour obtenir uniquement l'addresse
if 'date' in variable:
if typeDoc == 'uds':
value = str(nom_du_releveur + '\n') + str(date.today()) # met la date d'aujourd'hui pour la date du relevé
else:
value = date.today()
if 'longueur' in variable: #on va trouver le type de longeur dépendamment de la circonférence ou pied
value = value.strip()
try:
value_int = int(value) # convert to integer if possible sinon ca marche pas
except ValueError:
continue
if value_int not in type_poteaux: # si c anous donne une valeur hors du dictionnaire ou que l'on met la valeur de la longeueur directemen on skip le processus
continue
type_poteaux_entre = type_poteaux[value_int] #met la valeur du dictionnaire dans une variable qui nous permettra de savoir si c'est un dictio ou un tuple pour differencie les deux type de modele dans le dictionaire
if isinstance(type_poteaux_entre,dict): # si on a un dictionnaire donc si on est obligé d'indiquer le type de bois
bois= valeurs['bois'].strip() # on prend la valeur du bois dans le fichier texte met le dnas une nouvelle variable
if bois == '': #si on ne connait pas le bois ca skip tout
continue
valeurs['classe'] = type_poteaux_entre[bois][1] #on va sélectionner le dictionnaire du bois correspondant et la classe du poteau
value = type_poteaux_entre[bois][0] #on va sélectionner le dictionnaire du bois correspondant et la longueur du poteau
else: #else si la valuer n'est qu'un tupple
valeurs['classe'] = type_poteaux_entre[1] #on va sélectionner la classe du poteau et on le stock dans la variable classe du dictio valeur
value = type_poteaux_entre[0] #on va sélectionner la longueur du poteau et on le stock dans le value de ce cycle qui sera longueur.
if "ville" in variable:
# This line tries to find the first key in the 'parc' dictionary
# where the target value (e.g., a town name) exists in the tuple of values.
valeurs['parc']= next((k for k, v in parc.items() if value.strip() in v), None) #k for k va me donner laclé de la valeur de la ville
valeurs[variable]=value #crée le dictionnaire valeur qui lie variable et sa valeur

95
uds.js Normal file
View File

@ -0,0 +1,95 @@
const statusEl = document.getElementById("status");
const logEl = document.getElementById("log");
const downloadsEl = document.getElementById("downloads");
const runBtn = document.getElementById("runBtn");
let pyodide = null;
async function initPyodide() {
statusEl.textContent = "Chargement de Pyodide ... (cela peut prendre 10-20s la première fois)";
pyodide = await loadPyodide();
statusEl.textContent = "Pyodide chargé. Installation de dépendances (openpyxl)...";
await pyodide.loadPackage("micropip");
const micropip = pyodide.pyimport("micropip");
await micropip.install("openpyxl");
statusEl.textContent = "Prêt — openpyxl installé."; //load micropip qui permet d'accéder a openpyxl qui sert a écrire dans les excels.
}
// load Pyodide script tag dynamically
(async () => {
const s = document.createElement("script");
s.src = "https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js";
s.onload = async () => { await initPyodide(); };
document.head.appendChild(s);
})();
function log(msg) {
logEl.textContent += msg + "\n";
logEl.scrollTop = logEl.scrollHeight;
}
function createDownloadLink(filename, bytes) {
// bytes is Uint8Array or ArrayBuffer-like
const blob = new Blob([bytes], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
a.textContent = `Download ${filename}`;
downloadsEl.appendChild(a);
}
runBtn.addEventListener("click", async () => {
downloadsEl.innerHTML = "";
logEl.textContent = "";
if (!pyodide) { alert("Pyodide n'est pas encore prêt."); return; }
const templateFile = document.getElementById("template_excel").files[0];
const txtFile = document.getElementById("txt_input").files[0];
const typeDoc = document.getElementById("typedoc").value;
const nom_releveur = document.getElementById("nom_releveur").value || "";
const hauteur_bosch = document.getElementById("hauteur_bosch").value || "0";
if (!templateFile) { alert("Veuillez uploader le template Excel."); return; }
if (!txtFile) { alert("Veuillez uploader le fichier texte."); return; }
statusEl.textContent = "Lecture des fichiers (navigateur)...";
// read files on JS side
const [tmplBuf, txtStr] = await Promise.all([
templateFile.arrayBuffer(),
txtFile.text()
]);
// pass into pyodide globals:
// set template bytes as a Uint8Array in globals so Python can get bytes via to_py()
pyodide.globals.set("template_uint8", new Uint8Array(tmplBuf));
pyodide.globals.set("txt_content", txtStr);
pyodide.globals.set("typeDoc", typeDoc);
pyodide.globals.set("nom_du_releveur", nom_releveur);
pyodide.globals.set("hauteur_bosch", hauteur_bosch);
statusEl.textContent = "Exécution du script Python (Pyodide)...";
log("Lancement du traitement...");
try {
const response = await fetch('UDS - Copie.py');
const python_core_code = await response.text();
await pyodide.runPythonAsync(python_core_code);
statusEl.textContent = "Terminé — fichiers générés.";
log("Terminé.");
} catch (err) {
console.error(err);
statusEl.textContent = "Erreur pendant l'exécution (voir log).";
log("ERREUR: " + err);
} finally {
try {
pyodide.globals.delete("template_uint8");
pyodide.globals.delete("txt_content");
pyodide.globals.delete("typeDoc");
pyodide.globals.delete("nom_du_releveur");
pyodide.globals.delete("hauteur_bosch");
} catch(e) {}
}
});

48
visualisation Normal file
View File

@ -0,0 +1,48 @@
Premiere étape est de pouvoir lire les lignes du fichier PDF et d epouvor copier ces lignes la dans des cellules spécifique, je me demande si je peux faire
en sorte de rendre le programme plus flexible en étant capable de lire les cellule spécifiques avec des espace overts et pouvoir changer l'un a l'autre
comme ca je peux analyser le ficher avec les cellules ouverts et ensuite passer à l'autre cellule ouvert. aussi pour le pdf je pense qu'au lieu de faire ligne 1 à ligne 2 pour le lire
il faudrait que la lecture se fasse par le nom dans le fichier pdf par example ligne 1 sera écrit nom du poteau: PBD351 rue roy il faudrait que la lecture trigger ''au nom du poteau'' est qu ça correspond
à la cellule spécifique qui sera lut est écrit donc ''nom du poteau'' correspondera toujours à la même cellule peu importe. le création et l'écrite du fichier excel devrait être indépendant du fichier pdf qui appelera l
fichier excel.
Dans le fichier PDF il y aura deux forme de modèle RSA et UDS,deux fonction different qui sera appelé en lisant la premiere ligne qui sera le titre:RSA ou UDS. je ne sais pas si le programme se rémémore les ligne
mais sinon ils seront mit dans un tableau avant de tomber dans la fonction. dans la fonction le but se sera de ordonner les données pour l'écriture en order dans la cellule qui va créer l'excel. Le nom de l'excel
sera donnée par la valeur du nom du poteau. Les duex fonctions seront RSA ou excel en entrant avec le tableau. Je dois aussi spécifier le nombre de fichier pdf que je dois analyser ou le nombre de page, je ne sais
si il peut lire le nombre de page spécifiquement ou il y a moyen de créer un fichier par page avec le pdf.je dois rentrer le nombre de pdf à lire.
Dans le PY de l'excel, je vais devoir créer un excel qui est une copie de l'excel(toujours copier l'excel qui est vide) (je ne sais pas si je peux copier l'excel pour l'uds sans chier les macros), ensuite le gros truc est que je ne sais pas
si je peux repérer les cellules qui sont vides et ensuite détecter ca et pouvoir écrire et ensuite passer à la prochaine cellule vide si je peux faire ca donc ça devrait être facile. Je dois rentrer avec le nombre de fichier que je vuex faire.
-----------------------------------------
✅ Objectif global
Lire un ou plusieurs fichiers PDF, en extraire les données selon un format RSA ou UDS, détecter des mots-clés (comme "Nom du poteau"),
organiser les données dans un tableau structuré, et remplir un fichier Excel modèle dans les bonnes cellules. Tu veux :
Lire un PDF page par page (ou fichier par fichier).
Identifier automatiquement si cest un modèle RSA ou UDS.
Extraire des champs (ex : "Nom du poteau", "Adresse", etc.) avec leurs valeurs.
Copier les valeurs extraites dans un modèle Excel existant, en remplissant les cellules vides spécifiques.
Générer un nouveau fichier Excel par entrée, avec le nom basé sur la valeur du champ "Nom du poteau".
🧩 Étapes proposées
Étape 1 : Lecture du PDF
Utiliser PyMuPDF (alias fitz) ou pdfplumber pour lire le contenu texte ligne par ligne.
Détecter le type de modèle ("RSA" ou "UDS") sur la première ligne.
Récupérer les lignes avec des mots-clés connus : par ex. "Nom du poteau: PBD351 rue Roy".
Flexibilité et extensions possibles
✅ Tu peux détecter les cellules vides avec if ws[cellule].value is None:
✅ Tu peux adapter les correspondances avec un dictionnaire par type de modèle (RSA, UDS)
✅ Le code est indépendant du contenu PDF il extrait et transforme en dictionnaire générique
✅ Tu peux entrer le nombre de fichiers à traiter, ou le nombre de pages à lire