doc-forge-reds/backend/app/services/document_processor.py

79 lines
2.2 KiB
Python

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()