wolfhece 2.1.8__py3-none-any.whl → 2.1.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wolfhece/PyDraw.py +7 -5
- wolfhece/PyParams.py +3 -0
- wolfhece/apps/version.py +1 -1
- wolfhece/multiprojects.py +16 -2
- wolfhece/report/__init__.py +0 -0
- wolfhece/report/reporting.py +516 -0
- wolfhece/report/wolf_report.png +0 -0
- {wolfhece-2.1.8.dist-info → wolfhece-2.1.10.dist-info}/METADATA +1 -1
- {wolfhece-2.1.8.dist-info → wolfhece-2.1.10.dist-info}/RECORD +12 -9
- {wolfhece-2.1.8.dist-info → wolfhece-2.1.10.dist-info}/WHEEL +0 -0
- {wolfhece-2.1.8.dist-info → wolfhece-2.1.10.dist-info}/entry_points.txt +0 -0
- {wolfhece-2.1.8.dist-info → wolfhece-2.1.10.dist-info}/top_level.txt +0 -0
wolfhece/PyDraw.py
CHANGED
@@ -2055,7 +2055,8 @@ class WolfMapViewer(wx.Frame):
|
|
2055
2055
|
"""
|
2056
2056
|
Récupère un graphique matplotlib sur base de la fenêtre OpenGL et de la palette de la matrice active
|
2057
2057
|
"""
|
2058
|
-
self.zoom_on(center=center, width=width, height= height, canvas_height=self.canvasheight)
|
2058
|
+
self.zoom_on(center=center, width=width, height= height, canvas_height=self.canvasheight, forceupdate=True)
|
2059
|
+
|
2059
2060
|
|
2060
2061
|
fig,axes = plt.subplots(1,2, gridspec_kw={'width_ratios': [20, 1]})
|
2061
2062
|
self.display_canvasogl(fig=fig,ax=axes[0])
|
@@ -2188,7 +2189,7 @@ class WolfMapViewer(wx.Frame):
|
|
2188
2189
|
ax=ax[0],
|
2189
2190
|
title=_('Current time {:0>8} s'.format(el_time)))
|
2190
2191
|
|
2191
|
-
def
|
2192
|
+
def get_canvas_as_image(self) -> Image.Image:
|
2192
2193
|
"""
|
2193
2194
|
Récupère la fenêtre OpenGL sous forme d'image
|
2194
2195
|
"""
|
@@ -3326,7 +3327,7 @@ class WolfMapViewer(wx.Frame):
|
|
3326
3327
|
for cur in self.linkedList:
|
3327
3328
|
if cur is not self:
|
3328
3329
|
cur.update()
|
3329
|
-
|
3330
|
+
|
3330
3331
|
def zoom_on_active_profile(self, size:float=500., forceupdate:bool=True):
|
3331
3332
|
""" Zoom on active profile """
|
3332
3333
|
|
@@ -8515,7 +8516,8 @@ class WolfMapViewer(wx.Frame):
|
|
8515
8516
|
curarray.updatepalette(onzoom=[self.xmin, self.xmax, self.ymin, self.ymax])
|
8516
8517
|
curarray.delete_lists()
|
8517
8518
|
|
8518
|
-
self.
|
8519
|
+
self.Paint()
|
8520
|
+
# self.Refresh()
|
8519
8521
|
|
8520
8522
|
def _plotting(self, drawing_type: draw_type, checked_state: bool = True):
|
8521
8523
|
""" Drawing objets on canvas"""
|
@@ -8875,7 +8877,7 @@ class WolfMapViewer(wx.Frame):
|
|
8875
8877
|
curobj.uncheck_plot()
|
8876
8878
|
|
8877
8879
|
curitem = self.gettreeitem(curobj)
|
8878
|
-
self.treelist.
|
8880
|
+
self.treelist.UncheckItem(curitem)
|
8879
8881
|
|
8880
8882
|
def get_current_zoom(self):
|
8881
8883
|
"""
|
wolfhece/PyParams.py
CHANGED
@@ -1029,6 +1029,9 @@ class Wolf_Param(wx.Frame):
|
|
1029
1029
|
page.Append(pg.FontProperty(label = param_name, name = locname, value = locvalue))
|
1030
1030
|
|
1031
1031
|
else:
|
1032
|
+
if locvalue is None:
|
1033
|
+
locvalue = ""
|
1034
|
+
|
1032
1035
|
page.Append(pg.StringProperty(label = param_name, name = locname, value = locvalue))
|
1033
1036
|
|
1034
1037
|
def _add_elem_to_page(self, page:pg.PropertyGridPage, group:str, param:dict, param_def:dict = None, prefix:str=''):
|
wolfhece/apps/version.py
CHANGED
wolfhece/multiprojects.py
CHANGED
@@ -26,8 +26,21 @@ class Project(Wolf_Param):
|
|
26
26
|
Il s'agit d'une surcharge d'un objet Wolf_Param qui est organisé en groupes de paramètres
|
27
27
|
Chaque paramètre peut être défini par une clé, une valeur et un commentaire (+ éventuellement une chaîne JSON)
|
28
28
|
"""
|
29
|
-
def __init__(self,
|
30
|
-
|
29
|
+
def __init__(self,
|
30
|
+
wdir='',
|
31
|
+
parent=None,
|
32
|
+
title="Default Title",
|
33
|
+
w=500, h=800,
|
34
|
+
ontop=False,
|
35
|
+
to_read=True,
|
36
|
+
filename='',
|
37
|
+
withbuttons=True,
|
38
|
+
DestroyAtClosing=True,
|
39
|
+
toShow=True,
|
40
|
+
init_GUI:bool = False,
|
41
|
+
force_even_if_same_default:bool = False):
|
42
|
+
|
43
|
+
super().__init__(parent, title, w, h, ontop, to_read, filename, withbuttons, DestroyAtClosing, toShow, init_GUI, force_even_if_same_default)
|
31
44
|
self.wdir = wdir
|
32
45
|
|
33
46
|
class Wolf2D_Project(Project):
|
@@ -73,6 +86,7 @@ class Wolf2D_Project(Project):
|
|
73
86
|
super().__init__(wdir, parent, title, w, h, ontop, to_read, filename, withbuttons, DestroyAtClosing, toShow)
|
74
87
|
|
75
88
|
self.mysims:dict[str,Union[Wolfresults_2D, wolfres2DGPU]]={}
|
89
|
+
|
76
90
|
self.mycontours={}
|
77
91
|
self.mycolormaps={}
|
78
92
|
self.epsilon=5e-4
|
File without changes
|
@@ -0,0 +1,516 @@
|
|
1
|
+
|
2
|
+
from docx import Document
|
3
|
+
from docx.shared import Pt
|
4
|
+
from docx.oxml.ns import qn
|
5
|
+
from docx.shared import Inches
|
6
|
+
from docx.shared import RGBColor
|
7
|
+
from pathlib import Path
|
8
|
+
from typing import Union, List, Tuple,Literal
|
9
|
+
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
|
10
|
+
from PIL import Image
|
11
|
+
import pandas as pd
|
12
|
+
from tempfile import NamedTemporaryFile, TemporaryDirectory
|
13
|
+
import logging
|
14
|
+
import matplotlib.pyplot as plt
|
15
|
+
from matplotlib.figure import Figure
|
16
|
+
from datetime import datetime
|
17
|
+
import os
|
18
|
+
import socket
|
19
|
+
import hashlib
|
20
|
+
import re
|
21
|
+
|
22
|
+
from gettext import gettext as _
|
23
|
+
|
24
|
+
class RapidReport:
|
25
|
+
"""
|
26
|
+
Class for creating a report 'quickly'.
|
27
|
+
|
28
|
+
It can be used in Jupyter notebooks or in scripts to create a simple report in Word format.
|
29
|
+
|
30
|
+
Word document is created with the following structure:
|
31
|
+
|
32
|
+
- Main page with title, author, date and hash of the document
|
33
|
+
- Summary (automatically generated)
|
34
|
+
- Title
|
35
|
+
- Paragraph
|
36
|
+
- Figure (numbered automatically with caption)
|
37
|
+
- Bullet list
|
38
|
+
- Table
|
39
|
+
|
40
|
+
It is not a full-fledged reporting tool with advanced functionnalities but a simple way to create a report quickly 'on-the-fly'.
|
41
|
+
|
42
|
+
|
43
|
+
Example:
|
44
|
+
|
45
|
+
```
|
46
|
+
rapport = RapidReport('Rapport de Projet', 'Alice')
|
47
|
+
|
48
|
+
rapport.add_title('Titre Principal', level=0)
|
49
|
+
rapport.add_paragraph('Ceci est un **paragraphe** introductif avec des mots en *italique* et en **gras**.')
|
50
|
+
|
51
|
+
rapport += "Tentative d'ajout de figure vie un lien incorrect.\nPassage à la ligne"
|
52
|
+
rapport.add_figure('/path/to/image.png', 'Légende de la figure.')
|
53
|
+
|
54
|
+
rapport.add_bullet_list(['Premier élément', 'Deuxième élément', 'Troisième élément'])
|
55
|
+
|
56
|
+
rapport.add_table_from_listoflists([['Nom', 'Âge'], ['Alice', '25'], ['Bob', '30']])
|
57
|
+
|
58
|
+
rapport.save('rapport.docx')
|
59
|
+
```
|
60
|
+
|
61
|
+
"""
|
62
|
+
|
63
|
+
def __init__(self, main_title:str, author:str):
|
64
|
+
|
65
|
+
self._main_title = main_title
|
66
|
+
self._author = author
|
67
|
+
self._date = None
|
68
|
+
|
69
|
+
self._content = []
|
70
|
+
self._document = None
|
71
|
+
|
72
|
+
self._filename = None
|
73
|
+
|
74
|
+
self._idx_figure = 0
|
75
|
+
|
76
|
+
self._styles={}
|
77
|
+
|
78
|
+
self._has_first_page = False
|
79
|
+
|
80
|
+
def _define_default_styles(self):
|
81
|
+
|
82
|
+
# Définir le style de titre
|
83
|
+
self._title_style = self._document.styles.add_style('TitleStyle', 1)
|
84
|
+
self._title_style.font.name = 'Arial'
|
85
|
+
self._title_style.font.size = Pt(20)
|
86
|
+
self._title_style.font.bold = True
|
87
|
+
self._title_style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Arial')
|
88
|
+
|
89
|
+
# Définir le style de légende
|
90
|
+
self._caption_style = self._document.styles.add_style('CaptionStyle', 1)
|
91
|
+
self._caption_style.font.name = 'Arial'
|
92
|
+
self._caption_style.font.size = Pt(9)
|
93
|
+
self._caption_style.font.italic = True
|
94
|
+
self._caption_style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Arial')
|
95
|
+
self._caption_style.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
96
|
+
|
97
|
+
# Définir le style de corps de texte
|
98
|
+
self._body_text_style = self._document.styles.add_style('BodyTextStyle', 1)
|
99
|
+
self._body_text_style.font.name = 'Arial'
|
100
|
+
self._body_text_style.font.size = Pt(11)
|
101
|
+
self._body_text_style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Arial')
|
102
|
+
self._body_text_style.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.JUSTIFY
|
103
|
+
|
104
|
+
# Définir le style de liste à puce
|
105
|
+
self._bullet_list_style = self._document.styles.add_style('BulletListStyle', 1)
|
106
|
+
self._bullet_list_style.font.name = 'Arial'
|
107
|
+
self._bullet_list_style.font.size = Pt(9)
|
108
|
+
self._bullet_list_style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Arial')
|
109
|
+
self._bullet_list_style.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
|
110
|
+
self._bullet_list_style.paragraph_format.left_indent = Inches(0.25)
|
111
|
+
|
112
|
+
self._table_grid_style = self._document.styles.add_style('TableGrid', 3)
|
113
|
+
self._table_grid_style.font.name = 'Arial'
|
114
|
+
self._table_grid_style.font.size = Pt(9)
|
115
|
+
self._table_grid_style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Arial')
|
116
|
+
self._table_grid_style.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
117
|
+
|
118
|
+
self._figure_style = self._document.styles.add_style('FigureStyle', 1)
|
119
|
+
self._figure_style.font.name = 'Arial'
|
120
|
+
self._figure_style.font.size = Pt(9)
|
121
|
+
self._figure_style._element.rPr.rFonts.set(qn('w:eastAsia'), 'Arial')
|
122
|
+
self._figure_style.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
|
123
|
+
|
124
|
+
self._styles['TitleStyle'] = self._title_style
|
125
|
+
self._styles['CaptionStyle'] = self._caption_style
|
126
|
+
self._styles['BodyTextStyle'] = self._body_text_style
|
127
|
+
self._styles['BulletListStyle'] = self._bullet_list_style
|
128
|
+
self._styles['TableGrid'] = self._table_grid_style
|
129
|
+
self._styles['FigureStyle'] = self._figure_style
|
130
|
+
|
131
|
+
def set_font(self, fontname:str='Arial', fontsize:int=12):
|
132
|
+
""" Définir la police et la taille de la police pour les styles de texte. """
|
133
|
+
|
134
|
+
for style in self._styles.values():
|
135
|
+
style.font.name = fontname
|
136
|
+
style.font.size = Pt(fontsize)
|
137
|
+
|
138
|
+
def fill_first_page(self, main_title:str, author:str):
|
139
|
+
"""
|
140
|
+
Remplir la première page du document.
|
141
|
+
|
142
|
+
Ajouter le titre, l'auteur et la date.
|
143
|
+
|
144
|
+
"""
|
145
|
+
if self._has_first_page:
|
146
|
+
return
|
147
|
+
|
148
|
+
# Récupérer le nom de l'utilisateur
|
149
|
+
user_name = os.getlogin()
|
150
|
+
|
151
|
+
# Récupérer le nom de l'ordinateur
|
152
|
+
computer_name = socket.gethostname()
|
153
|
+
|
154
|
+
logo_path = Path(__file__).parent / 'wolf_report.png'
|
155
|
+
|
156
|
+
self._main_title = main_title
|
157
|
+
self._author = author
|
158
|
+
self._date = datetime.now().strftime('%d/%m/%Y')
|
159
|
+
|
160
|
+
self._insert_title(self._main_title, level=0, index=0)
|
161
|
+
self._insert_figure(logo_path,caption=None, width=2.0, index=1)
|
162
|
+
|
163
|
+
self._insert_paragraph('Ce document a été généré automatiquement par le paquet Python "wolfhece".', index =2)
|
164
|
+
self._insert_paragraph(' ', index=3)
|
165
|
+
self._insert_paragraph(f'Auteur : {self._author}', index=4)
|
166
|
+
self._insert_paragraph(f'Date : {self._date}', index=5)
|
167
|
+
self._insert_paragraph(' ', index=6)
|
168
|
+
self._insert_paragraph(f'Utilisateur : {user_name}', index=7)
|
169
|
+
self._insert_paragraph(f'Ordinateur : {computer_name}', index=8)
|
170
|
+
self._insert_paragraph(' ', index=9)
|
171
|
+
|
172
|
+
chain_hash = hashlib.md5(self._main_title.encode() +
|
173
|
+
self._author.encode() +
|
174
|
+
user_name.encode() +
|
175
|
+
computer_name.encode()+
|
176
|
+
self._date.encode()).hexdigest()
|
177
|
+
|
178
|
+
self._insert_paragraph('Hash du document : ' + chain_hash, index=10)
|
179
|
+
|
180
|
+
self._insert_new_page(index=11)
|
181
|
+
|
182
|
+
self._insert_paragraph('summary', index=12)
|
183
|
+
|
184
|
+
self._has_first_page = True
|
185
|
+
|
186
|
+
def _insert_title(self, title:str, level:int=1, index:int = 0):
|
187
|
+
""" Insère un titre dans le document. """
|
188
|
+
|
189
|
+
self._content.insert(index, ('title', title, level))
|
190
|
+
|
191
|
+
def _insert_paragraph(self, paragraph_text:str, style:str='BodyTextStyle', index:int = 0):
|
192
|
+
""" Insère un paragraphe dans le document. """
|
193
|
+
|
194
|
+
self._content.insert(index, ('paragraph', paragraph_text, style))
|
195
|
+
|
196
|
+
def _insert_figure(self, image_path:Union[str, Path, Image.Image, Figure], caption:str, width:float=7.0, index:int = 0):
|
197
|
+
""" Insère une figure dans le document. """
|
198
|
+
|
199
|
+
self._content.insert(index, ('figure', image_path, caption, width, self._idx_figure))
|
200
|
+
|
201
|
+
def add_title(self, title:str, level:int=1):
|
202
|
+
""" Ajoute un titre au document. """
|
203
|
+
|
204
|
+
self._content.append(('title', title, level))
|
205
|
+
|
206
|
+
def _list_titles(self, level:int=None):
|
207
|
+
""" Renvoie la liste des titres du document. """
|
208
|
+
|
209
|
+
if level is None:
|
210
|
+
return [item[1] for item in self._content if item[0] == 'title']
|
211
|
+
else:
|
212
|
+
return [item[1] for item in self._content if item[0] == 'title' and item[2] == level]
|
213
|
+
|
214
|
+
def _list_captions(self):
|
215
|
+
""" Renvoie la liste des légendes de figures du document. """
|
216
|
+
|
217
|
+
return [item[2] for item in self._content if item[0] == 'figure' if item[2]]
|
218
|
+
|
219
|
+
def _list_figures(self):
|
220
|
+
""" Renvoie la liste des figures du document. """
|
221
|
+
|
222
|
+
return [item[1] for item in self._content if item[0] == 'figure' if item[1] and item[2]]
|
223
|
+
|
224
|
+
def _list_index(self):
|
225
|
+
""" Renvoie la liste des index de figures du document. """
|
226
|
+
|
227
|
+
return [item[3] for item in self._content if item[0] == 'figure' if item[3]]
|
228
|
+
|
229
|
+
def fig_exists(self, fig_name:str):
|
230
|
+
""" Vérifie si une figure existe dans le document. """
|
231
|
+
|
232
|
+
return fig_name in self._list_figures()
|
233
|
+
|
234
|
+
def get_fig_index(self, fig_name_caption:str):
|
235
|
+
""" Renvoie la légende d'une figure. """
|
236
|
+
|
237
|
+
list_figures = self._list_figures()
|
238
|
+
list_captions = self._list_captions()
|
239
|
+
|
240
|
+
if fig_name_caption in list_figures:
|
241
|
+
idx = self._list_figures().index(fig_name_caption)+1
|
242
|
+
elif fig_name_caption in list_captions:
|
243
|
+
idx = self._list_captions().index(fig_name_caption)+1
|
244
|
+
else:
|
245
|
+
idx = None
|
246
|
+
|
247
|
+
return idx
|
248
|
+
|
249
|
+
def _add_summary(self):
|
250
|
+
""" Ajoute un sommaire au document. """
|
251
|
+
|
252
|
+
titles = self._list_titles()
|
253
|
+
|
254
|
+
self._document.add_heading(_('Summary'), level=1).style = 'TitleStyle'
|
255
|
+
|
256
|
+
for cur_title in titles:
|
257
|
+
p = self._document.add_paragraph(cur_title, style='BodyTextStyle')
|
258
|
+
run = p.add_run()
|
259
|
+
run.add_tab()
|
260
|
+
run.bold = True
|
261
|
+
p.style = 'BodyTextStyle'
|
262
|
+
|
263
|
+
self._document.add_heading(_('List of figures'), level=1).style = 'TitleStyle'
|
264
|
+
figures = self._list_captions()
|
265
|
+
for i, cur_figure in enumerate(figures):
|
266
|
+
p = self._document.add_paragraph(f'Fig. {i+1} : {cur_figure}', style='BodyTextStyle')
|
267
|
+
run = p.add_run()
|
268
|
+
run.add_tab()
|
269
|
+
run.bold = True
|
270
|
+
p.style = 'BodyTextStyle'
|
271
|
+
|
272
|
+
self._document.add_page_break()
|
273
|
+
|
274
|
+
def add_paragraph(self, paragraph_text:str, style:str='BodyTextStyle'):
|
275
|
+
""" Ajoute un paragraphe au document. """
|
276
|
+
|
277
|
+
self._content.append(('paragraph', paragraph_text, style))
|
278
|
+
|
279
|
+
def add(self, paragraph_text:str, style:str='BodyTextStyle'):
|
280
|
+
""" Ajoute un paragraphe au document. """
|
281
|
+
|
282
|
+
self.add_paragraph(paragraph_text, style=style)
|
283
|
+
|
284
|
+
def __add__(self, paragraph_text:str):
|
285
|
+
""" Surcharge de l'opérateur + pour ajouter un paragraphe. """
|
286
|
+
|
287
|
+
self.add_paragraph(paragraph_text)
|
288
|
+
|
289
|
+
return self
|
290
|
+
|
291
|
+
def add_figure(self, image_path:Union[str, Path, Image.Image, Figure], caption:str, width:float=7.0):
|
292
|
+
""" Ajoute une figure au document avec une légende. """
|
293
|
+
|
294
|
+
if caption:
|
295
|
+
self._idx_figure += 1
|
296
|
+
|
297
|
+
self._content.append(('figure', image_path, caption, width, self._idx_figure))
|
298
|
+
|
299
|
+
def add_bullet_list(self, bullet_list: List[str], style:str='BulletListStyle'):
|
300
|
+
""" Ajoute une liste à puce au document. """
|
301
|
+
|
302
|
+
for item in bullet_list:
|
303
|
+
self.add_paragraph('- ' + item, style=style)
|
304
|
+
|
305
|
+
def add_new_page(self):
|
306
|
+
""" Ajoute une nouvelle page au document. """
|
307
|
+
|
308
|
+
self._content.append(('newpage', '', None))
|
309
|
+
|
310
|
+
def _insert_new_page(self, index:int = 0):
|
311
|
+
""" Insère une nouvelle page au document. """
|
312
|
+
|
313
|
+
self._content.insert(index, ('newpage', '', None))
|
314
|
+
|
315
|
+
def add_table_from_listoflists(self, data:List[List[str]], style:str='TableGrid'):
|
316
|
+
"""
|
317
|
+
Ajoute un tableau au document.
|
318
|
+
|
319
|
+
:param data: Liste de listes contenant les données du tableau. Chaque liste est une ligne du tableau.
|
320
|
+
|
321
|
+
"""
|
322
|
+
|
323
|
+
self._content.append(('table', data, style))
|
324
|
+
|
325
|
+
def add_table_from_dict(self, data:dict, style:str='TableGrid'):
|
326
|
+
"""
|
327
|
+
Ajoute un tableau au document.
|
328
|
+
|
329
|
+
:param data: Dictionnaire contenant les données du tableau. Les clés sont les en-têtes de colonnes.
|
330
|
+
|
331
|
+
"""
|
332
|
+
|
333
|
+
table_data = [list(data.keys())]
|
334
|
+
table_data += [list(data.values())]
|
335
|
+
self.add_table_from_listoflists(table_data, style=style)
|
336
|
+
|
337
|
+
def add_table_as_picture(self, data:Union[List[List[str]], dict, pd.DataFrame, Figure], caption:str=None):
|
338
|
+
""" Ajoute un tableau au document sous forme d'image. """
|
339
|
+
|
340
|
+
def fig2img(fig):
|
341
|
+
"""Convert a Matplotlib figure to a PIL Image and return it"""
|
342
|
+
import io
|
343
|
+
buf = io.BytesIO()
|
344
|
+
|
345
|
+
fig.savefig(buf, bbox_inches='tight')
|
346
|
+
buf.seek(0)
|
347
|
+
img = Image.open(buf)
|
348
|
+
return img
|
349
|
+
|
350
|
+
if isinstance(data, Figure):
|
351
|
+
tmp_image = fig2img(data)
|
352
|
+
self.add_figure(tmp_image, caption)
|
353
|
+
return
|
354
|
+
|
355
|
+
if isinstance(data, dict):
|
356
|
+
data = pd.DataFrame(data)
|
357
|
+
elif isinstance(data, list):
|
358
|
+
data = pd.DataFrame(data)
|
359
|
+
|
360
|
+
fig, ax = plt.subplots()
|
361
|
+
|
362
|
+
ax.axis('off')
|
363
|
+
ax.table(cellText=data.values,
|
364
|
+
colLabels=data.columns,
|
365
|
+
loc='center',
|
366
|
+
cellLoc='center',
|
367
|
+
colColours=['#f3f3f3']*len(data.columns))
|
368
|
+
|
369
|
+
fig.tight_layout()
|
370
|
+
|
371
|
+
tmp_image = fig2img(fig)
|
372
|
+
|
373
|
+
self.add_figure(tmp_image, caption, width=4.0)
|
374
|
+
|
375
|
+
def _apply_text_styles(self, paragraph, text):
|
376
|
+
""" Search for bold and italic styles in the text and apply them."""
|
377
|
+
|
378
|
+
text = text.replace('\n\n', 'DOUBLE_NEWLINE')
|
379
|
+
text = text.replace('\n', ' ')
|
380
|
+
text = text.replace('DOUBLE_NEWLINE', '\n')
|
381
|
+
|
382
|
+
def split_bold(text):
|
383
|
+
return text.split('**')
|
384
|
+
|
385
|
+
def split_italic(text):
|
386
|
+
return text.split('*')
|
387
|
+
|
388
|
+
splitted_bold = split_bold(text)
|
389
|
+
|
390
|
+
bold = False
|
391
|
+
for cur_text in splitted_bold:
|
392
|
+
if cur_text != '':
|
393
|
+
italic = False
|
394
|
+
spliited_italic = split_italic(cur_text)
|
395
|
+
for cur_text2 in spliited_italic:
|
396
|
+
if cur_text2 != '':
|
397
|
+
run = paragraph.add_run(cur_text2)
|
398
|
+
run.bold = bold
|
399
|
+
run .italic = italic
|
400
|
+
|
401
|
+
italic = not italic
|
402
|
+
bold = not bold
|
403
|
+
|
404
|
+
def parse_content(self):
|
405
|
+
""" Parse le contenu du document et l'ajoute au document Word. """
|
406
|
+
|
407
|
+
# tmp_dir = TemporaryDirectory()
|
408
|
+
|
409
|
+
for item in self._content:
|
410
|
+
|
411
|
+
if item[0] == 'title':
|
412
|
+
self._document.add_heading(item[1], level=item[2]).style = 'TitleStyle'
|
413
|
+
|
414
|
+
elif item[0] == 'paragraph':
|
415
|
+
|
416
|
+
if item[1] == 'summary':
|
417
|
+
self._add_summary()
|
418
|
+
continue
|
419
|
+
else:
|
420
|
+
p = self._document.add_paragraph()
|
421
|
+
self._apply_text_styles(p, item[1])
|
422
|
+
p.style = item[2] if item[2] else 'BodyTextStyle'
|
423
|
+
|
424
|
+
elif item[0] == 'figure':
|
425
|
+
|
426
|
+
if isinstance(item[1], Image.Image):
|
427
|
+
|
428
|
+
tmp_name = NamedTemporaryFile(suffix='.png').name
|
429
|
+
item[1].save(tmp_name)
|
430
|
+
|
431
|
+
elif isinstance(item[1], str):
|
432
|
+
tmp_name = item[1]
|
433
|
+
|
434
|
+
elif isinstance(item[1], Path):
|
435
|
+
tmp_name = str(item[1])
|
436
|
+
|
437
|
+
elif isinstance(item[1], Figure):
|
438
|
+
item[1].tight_layout()
|
439
|
+
tmp_name = NamedTemporaryFile(suffix='.png').name
|
440
|
+
item[1].savefig(tmp_name)
|
441
|
+
|
442
|
+
if Path(tmp_name).exists():
|
443
|
+
self._document.add_picture(tmp_name, width=Inches(item[3]) if item[3] else Inches(7.0))
|
444
|
+
self._document.paragraphs[-1].style = 'FigureStyle'
|
445
|
+
else:
|
446
|
+
logging.error(f"File {tmp_name} not found.")
|
447
|
+
p = self._document.add_paragraph()
|
448
|
+
run = p.add_run(f'Error: Image not found. {tmp_name}')
|
449
|
+
run.font.color.rgb = RGBColor(255, 0, 0)
|
450
|
+
p.style = 'BodyTextStyle'
|
451
|
+
|
452
|
+
if item[2]:
|
453
|
+
caption = self._document.add_paragraph(f'Fig. {item[4]} :' + item[2])
|
454
|
+
caption.style = 'CaptionStyle'
|
455
|
+
|
456
|
+
elif item[0] == 'table':
|
457
|
+
|
458
|
+
data = item[1]
|
459
|
+
style = item[2]
|
460
|
+
table = self._document.add_table(rows=len(data), cols=len(data[0]))
|
461
|
+
table.style = style
|
462
|
+
|
463
|
+
for i, row in enumerate(data):
|
464
|
+
for j, cell in enumerate(row):
|
465
|
+
table.cell(i, j).text = cell
|
466
|
+
|
467
|
+
elif item[0] == 'newpage':
|
468
|
+
self._document.add_page_break()
|
469
|
+
|
470
|
+
def save(self, file_path:Union[str,Path]=None):
|
471
|
+
""" Sauvegarde le document Word. """
|
472
|
+
|
473
|
+
if file_path is None:
|
474
|
+
file_path = self._filename
|
475
|
+
|
476
|
+
if file_path is None:
|
477
|
+
raise ValueError("Le chemin du fichier n'a pas été spécifié.")
|
478
|
+
|
479
|
+
self._document = Document()
|
480
|
+
|
481
|
+
self._define_default_styles()
|
482
|
+
|
483
|
+
self.fill_first_page(self._main_title, self._author)
|
484
|
+
|
485
|
+
self.parse_content()
|
486
|
+
try:
|
487
|
+
self._document.save(str(file_path))
|
488
|
+
except Exception as e:
|
489
|
+
logging.error(f"Error saving file: {e}")
|
490
|
+
|
491
|
+
if __name__ == '__main__':
|
492
|
+
|
493
|
+
# Exemple d'utilisation
|
494
|
+
rapport = RapidReport('Rapport de Projet', 'Alice')
|
495
|
+
|
496
|
+
rapport.add_title('Titre Principal', level=0)
|
497
|
+
rapport.add_paragraph('Ceci est un **paragraphe** introductif avec des mots en *italique* et en **gras**.')
|
498
|
+
|
499
|
+
rapport += "Tentative d'ajout de figure vie un lien incorrect.\nPassage à la ligne"
|
500
|
+
rapport.add_figure('/path/to/image.png', 'Légende de la figure.')
|
501
|
+
rapport+="""
|
502
|
+
Commentraire sur la figure multilignes
|
503
|
+
ligne 2
|
504
|
+
ligne3"""
|
505
|
+
|
506
|
+
rapport.add_bullet_list(['Premier élément', 'Deuxième élément', 'Troisième élément'])
|
507
|
+
|
508
|
+
rapport.add_table_from_listoflists([['Nom', 'Âge'], ['Alice', '25'], ['Bob', '30']])
|
509
|
+
rapport.add_table_from_dict({'Nom': ['Alice', 'Bob'], 'Âge': ['25', '30']})
|
510
|
+
rapport.add_table_as_picture({'Nom': ['Alice', 'Bob'], 'Âge': ['25', '30']}, caption='Tableau de données')
|
511
|
+
|
512
|
+
rapport.save('rapport.docx')
|
513
|
+
|
514
|
+
assert rapport.get_fig_index('/path/to/image.png') == 1
|
515
|
+
assert rapport.get_fig_index('Tableau de données') == 2
|
516
|
+
|
Binary file
|
@@ -6,12 +6,12 @@ wolfhece/ManageParams.py,sha256=Wgt5Zh7QBtyiwTAltPHunSLqt4XuVuRH76GTUrXabS4,219
|
|
6
6
|
wolfhece/Model1D.py,sha256=-cMz-ePSYzrKVVDidiDOz6cojEZ3y6u9gIb7RPwT6Y8,476593
|
7
7
|
wolfhece/PyConfig.py,sha256=oGSL1WsLM9uinlNP4zGBLK3uHPmBfduUi7R-VtWuRFA,8034
|
8
8
|
wolfhece/PyCrosssections.py,sha256=f4dNYRUGZKePruaaBiTcn5vlrw8TFTj9XwTDrdiF_uU,112450
|
9
|
-
wolfhece/PyDraw.py,sha256=
|
9
|
+
wolfhece/PyDraw.py,sha256=eYv0X1NFCWlgOgiRaIjW0SPlR_uVLdZhFpztY1jX6Lo,378408
|
10
10
|
wolfhece/PyGui.py,sha256=VKE785z9XLIWNbxqpyEceLK_wtmPJyq6A_M_qX_94Lg,104772
|
11
11
|
wolfhece/PyGuiHydrology.py,sha256=wKhR-KthPRyzJ887NmsozmUpm2CIQIwO3IbYORCYjrE,7290
|
12
12
|
wolfhece/PyHydrographs.py,sha256=GKK8U0byI45H9O_e4LAOOi7Aw0Tg7Q0Lx322stPg5IQ,3453
|
13
13
|
wolfhece/PyPalette.py,sha256=_Nm2Lc4UxYlZgK8ifZDioG8a0at8oiteYC0x_4XugFc,24384
|
14
|
-
wolfhece/PyParams.py,sha256=
|
14
|
+
wolfhece/PyParams.py,sha256=xUmtwna4rhTCqa3-fpq7bG5pxMpoa4PFRi5hEjxOxPw,96868
|
15
15
|
wolfhece/PyPictures.py,sha256=-mJB0JL2YYiEK3D7_ssDkvYiMWK4ve9kXhozQXNeSx8,2216
|
16
16
|
wolfhece/PyTranslate.py,sha256=4appkmNeHHZLFmUtaA_k5_5QL-5ymxnbVN4R2OblmtE,622
|
17
17
|
wolfhece/PyVertex.py,sha256=dHTjyYYTn0F_NWerlAOBKHV79RUzEEtMJMldQtVc1Cs,40092
|
@@ -34,7 +34,7 @@ wolfhece/import_ascfiles.py,sha256=jg4urcLdSgFS1Knvh7AVGJqM44qc_uYDNrR568tMh-A,4
|
|
34
34
|
wolfhece/ins.py,sha256=0aU1mo4tYbw64Gwzrqbh-NCTH1tukmk0mpPHjRPHZXU,12661
|
35
35
|
wolfhece/irm_qdf.py,sha256=749SlAXiN1oXp5tfBJoPNJWxydQlY55K0qvIM5YexlM,15436
|
36
36
|
wolfhece/ismember.py,sha256=fkLvaH9fhx-p0QrlEzqa6ySO-ios3ysjAgXVXzLgSpY,2482
|
37
|
-
wolfhece/multiprojects.py,sha256=
|
37
|
+
wolfhece/multiprojects.py,sha256=K40kM09xNkQSjiwANTsA4CpaW7KEkawpBkpoiehk9yo,21251
|
38
38
|
wolfhece/picc.py,sha256=KKPNk1BEe7QBzo2icIsdsxUopJ1LXYTomfdfeG2gCeA,7419
|
39
39
|
wolfhece/pyGui1D.py,sha256=pzLWXQ_w3Y_yI846w1GklFO9h5lWZOqiUzg1BUPkuRI,121616
|
40
40
|
wolfhece/pybridges.py,sha256=4PRSsWngDmQnlVuN2tJj0C_HT1h47ExH9QTUPs_Wxlg,57215
|
@@ -66,7 +66,7 @@ wolfhece/apps/check_install.py,sha256=jrKR-njqnpIh6ZJqvP6KbDUPVCfwTNQj4glQhcyzs9
|
|
66
66
|
wolfhece/apps/curvedigitizer.py,sha256=avWERHuVxPnJBOD_ibczwW_XG4vAenqWS8W1zjhBox8,4898
|
67
67
|
wolfhece/apps/isocurrent.py,sha256=4XnNWPa8mYUK7V4zdDRFrHFIXNG2AN2og3TqWKKcqjY,3811
|
68
68
|
wolfhece/apps/splashscreen.py,sha256=LkEVMK0eCc84NeCWD3CGja7fuQ_k1PrZdyqD3GQk_8c,2118
|
69
|
-
wolfhece/apps/version.py,sha256=
|
69
|
+
wolfhece/apps/version.py,sha256=p7F6qFk_CdXhKrAOXaQdIRVqeFmOEFL0SsGEAojsQgo,388
|
70
70
|
wolfhece/apps/wolf.py,sha256=gqfm-ZaUJqNsfCzmdtemSeqLw-GVdSVix-evg5WArJI,293
|
71
71
|
wolfhece/apps/wolf2D.py,sha256=gWD9ee2-1pw_nUxjgRaJMuSe4kUT-RWhOeoTt_Lh1mM,267
|
72
72
|
wolfhece/apps/wolf_logo.bmp,sha256=ruJ4MA51CpGO_AYUp_dB4SWKHelvhOvd7Q8NrVOjDJk,3126
|
@@ -241,6 +241,9 @@ wolfhece/radar/wolfradar.py,sha256=ylyz8hNAGq92WXnMO8hVe6Nk-a7g--fL-xOcjfhFEtk,9
|
|
241
241
|
wolfhece/rem/REMMaker.py,sha256=kffClHHpf8P4ruZpEb9EB__HBzg9rFAkiVCh-GFtIHU,30790
|
242
242
|
wolfhece/rem/RasterViz.py,sha256=TDhWyMppcYBL71HfhpZuMgYKhz7faZg-MEOQJo_3Ivo,29128
|
243
243
|
wolfhece/rem/__init__.py,sha256=S2-J5uEGK_VaMFjRUYFIdSScJjZyuXH4RmMmnG3OG7I,19
|
244
|
+
wolfhece/report/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
245
|
+
wolfhece/report/reporting.py,sha256=LrOUI7j1vPefsGhqag1f2KpKRXR-5cH7SyGIsf6nOG0,19196
|
246
|
+
wolfhece/report/wolf_report.png,sha256=NoSV58LSwb-oxCcZScRiJno-kxDwRdm_bK-fiMsKJdA,592485
|
244
247
|
wolfhece/scenario/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
245
248
|
wolfhece/scenario/check_scenario.py,sha256=nFiCscEGHyz1YvjmZoKlYrfmW03-nLiDTDdRoeE6MUs,4619
|
246
249
|
wolfhece/scenario/config_manager.py,sha256=SValpikuNt_XaJXt8P7kAu6iN_N5YlohyL8ry3iT380,77389
|
@@ -264,8 +267,8 @@ wolfhece/sounds/sonsw2.wav,sha256=pFLVt6By0_EPQNt_3KfEZ9a1uSuYTgQSX1I_Zurv9Rc,11
|
|
264
267
|
wolfhece/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
265
268
|
wolfhece/ui/wolf_multiselection_collapsiblepane.py,sha256=yGbU_JsF56jsmms0gh7mxa7tbNQ_SxqhpAZxhm-mTy4,14860
|
266
269
|
wolfhece/ui/wolf_times_selection_comparison_models.py,sha256=wCxGRnE3kzEkWlWA6-3X8ADOFux_B0a5QWJ2GnXTgJw,4709
|
267
|
-
wolfhece-2.1.
|
268
|
-
wolfhece-2.1.
|
269
|
-
wolfhece-2.1.
|
270
|
-
wolfhece-2.1.
|
271
|
-
wolfhece-2.1.
|
270
|
+
wolfhece-2.1.10.dist-info/METADATA,sha256=Zzg2Nmd6IpZTLHVQohBtHfLxq6TwzEOzad-ue6QTJJk,2282
|
271
|
+
wolfhece-2.1.10.dist-info/WHEEL,sha256=cpQTJ5IWu9CdaPViMhC9YzF8gZuS5-vlfoFihTBC86A,91
|
272
|
+
wolfhece-2.1.10.dist-info/entry_points.txt,sha256=AIu1KMswrdsqNq_2jPtrRIU4tLjuTnj2dCY-pxIlshw,276
|
273
|
+
wolfhece-2.1.10.dist-info/top_level.txt,sha256=EfqZXMVCn7eILUzx9xsEu2oBbSo9liWPFWjIHik0iCI,9
|
274
|
+
wolfhece-2.1.10.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|