import mammoth from io import BytesIO from docx import Document from docx.shared import Pt from app.services.file_storage import get_file_content async def docx_to_html(file_content: bytes) -> str: result = mammoth.convert_to_html(BytesIO(file_content)) return result.value def html_to_docx_bytes(html_content: str) -> bytes: doc = Document() style = doc.styles["Normal"] font = style.font font.name = "Arial" font.size = Pt(11) from html.parser import HTMLParser class DocxHTMLParser(HTMLParser): def __init__(self): super().__init__() self.in_p = False self.current_text = "" self.paragraphs: list[str] = [] def handle_starttag(self, tag, attrs): if tag in ("p", "h1", "h2", "h3", "h4", "h5", "h6", "div", "li"): self.in_p = True self.current_text = "" def handle_endtag(self, tag): if tag in ("p", "h1", "h2", "h3", "h4", "h5", "h6", "div", "li"): if self.current_text.strip(): self.paragraphs.append(self.current_text.strip()) self.current_text = "" self.in_p = False def handle_data(self, data): self.current_text += data parser = DocxHTMLParser() parser.feed(html_content) for text in parser.paragraphs: doc.add_paragraph(text) output = BytesIO() doc.save(output) return output.getvalue() def docx_to_pdf_bytes(file_content: bytes) -> bytes: doc = Document(BytesIO(file_content)) from io import BytesIO as Bio from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer from reportlab.lib.enums import TA_LEFT buffer = Bio() pdf_doc = SimpleDocTemplate(buffer, pagesize=A4) styles = getSampleStyleSheet() story = [] for para in doc.paragraphs: if para.text.strip(): p = Paragraph(para.text, styles["Normal"]) story.append(p) story.append(Spacer(1, 6)) pdf_doc.build(story) return buffer.getvalue()