from xml.dom.minidom import Element import docx import zipfile from src.tools.doc_tools import get_difference_with_template, get_positions, convert_to_png from PIL import Image from docxcompose.composer import Composer from docx import Document as Document_compose from docx.enum.table import WD_TABLE_ALIGNMENT from src.domain.container import Container from src.domain.paragraph import Paragraph from src.domain.styles import Styles import shutil import os class Doc: def __init__(self, path='', id_=None): self.xdoc = docx.Document(path) self.title = path.split('/')[-1] self.name = self.title.split('.')[0] self.id_ = id(self) self.path = path paragraphs = [Paragraph(xp, self.id_, i) for (i, xp) in enumerate(self.xdoc.paragraphs)] self.container = Container(paragraphs, father=self) self.styles = Styles(self.xdoc.styles) self.tasks = [c.get_fulltask(self.container.one_liner) for c in self.container.containers if c.task] def copy(self, new_doc_path): shutil.copyfile(self.path, new_doc_path) new_doc = Doc(new_doc_path) new_doc.save_as_docx(new_doc_path) return new_doc def clear(self): os.remove(self.path) def apply_template(self, template, options_list): center_tables = False center_images = False add_template_before = False justify_content = False log = [] i = 0 j = 0 if("Recentrer les tableaux" in options_list): center_tables = True if("Recentrer les images (sauf les flottantes)" in options_list): center_images = True if("Ajouter le template avant" in options_list): add_template_before = True if("Justifier le texte" in options_list): justify_content = True if (justify_content): log.append("Le contenu du document a été justifié") self.justify_content() if(center_images): self.center_images() i = self.number_images_in_doc() log.append(f"{i} image{'s' if i>1 else ''} centrée{'s' if i>1 else ''}") if(center_tables): j = self.center_tables() log.append(f"{j} table{'s' if j>1 else ''} centrée{'s' if j>1 else ''}") if(add_template_before): self.save_as_docx() log.append(f"Le template {template.name} a été ajouté avant le document") log = self.styles.apply_from(template.styles, log) master = Document_compose(template.path) composer = Composer(master) doc = Document_compose(self.path) composer.append(doc) composer.save(self.path) else: log = self.styles.apply_from(template.styles, log) self.save_as_docx() return log def copy_one_style(self, src_style_name: str, dest_style_name: str, template): style_dest = template.styles.get_style_from_name(dest_style_name) src_style = self.styles.get_style_from_name(src_style_name) log = self.styles.copy_one_style(src_style, style_dest) return log def get_different_styles_with_template(self, template): styles_used_in_doc = self.get_all_styles_of_doc() different_styles = get_difference_with_template(styles_used_in_doc, template) return different_styles def save_as_docx(self, path: str = ''): path = path if path else self.path self.path = path self.xdoc.save(path) # def add_back_pages_from(self, src_doc): # with open (self.path, "rb") as f: # zip = zipfile.ZipFile(f) # images = [image for image in zip.namelist() if image.startswith('word/media/')] # for image in images: # zip.extract(image) # zip.close() # images = convert_to_png(images) # #copy the entire self to the end of src_doc # for p in self.get_paragraphs(): # p.insert_paragraphs(images,src_doc) # return self def get_blocks(self): def from_list_to_str(index_list): index_str = str(index_list[0]) for el in index_list[1:]: index_str += '.' + str(el) return index_str blocks = self.container.blocks for block in blocks: block.doc = self.title if block.level == 0: blocks.remove(block) block.index = from_list_to_str(block.index) return blocks @property def structure(self): return self.container.structure def replace_tasks(self, resolutions: [str]): if len(resolutions) == len(self.tasks): # exception to be handled p_tasks = [p for p in self.get_paragraphs() if p.type == 'task'] for p, r in zip(p_tasks, resolutions): p.set_text(r) else: print(f"résolutions : {len(resolutions)} != {len(self.tasks)} tasks") return self def get_paragraphs(self): return self.container.all_paragraphs def get_text_from_paragraphs(self): return [p.text for p in self.get_paragraphs()] def check_document(self): picCount = 0 tabCount = 0 for paragraph in self.xdoc.paragraphs: if picCount < len(self.xdoc.inline_shapes): print('\033[1mPicture \033[0m') picCount += 1 elif paragraph.text: print(paragraph.text) elif tabCount < len(self.xdoc.tables): table = self.xdoc.tables[tabCount] data = [] keys = None for i, row in enumerate(table.rows): text = (cell.text for cell in row.cells) if i == 0: keys = tuple(text) continue row_data = dict(zip(keys, text)) data.append(row_data) print('\033[1mTable:\033[0m', data) tabCount += 1 else: print('\033[1mEmpty paragraph\033[0m') def center_tables(self): j = 0 for table in self.xdoc.tables: j += 1 table.alignment = WD_TABLE_ALIGNMENT.CENTER return j # def center_tables_with_template(self): # j = 0 # for i,table in enumerate(self.xdoc.tables): # if(i == 0): # continue # j += 1 # table.alignment = 1 # return j def center_images(self): for paragraph in self.get_paragraphs(): paragraph.center_paragraph() def justify_content(self): for paragraph in self.get_paragraphs(): paragraph.justify_paragraph() # def add_paragraph(self,p:Paragraph): # self.container.paragraphs.append(p) # self.xdoc.add_paragraph(p.text,p.xparagraph.style) def number_images_in_doc(self): picCount = 0 for _ in self.xdoc.paragraphs: if picCount < len(self.xdoc.inline_shapes): print('\033[1mPicture \033[0m') picCount += 1 return picCount def get_all_styles_of_doc(self): return self.container.get_all_styles_used_in_doc()