nepile/kertas
0
1import io2 3from docx import Document as DocxDocument4from docx.shared import Pt5from reportlab.lib.pagesizes import A46from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle7from reportlab.lib.units import cm8from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer9from reportlab.lib.enums import TA_JUSTIFY10 11 12def _split_paragraphs(text: str) -> list:13 raw_parts = [p.strip() for p in text.split("\n\n")]14 return [p for p in raw_parts if p]15 16 17def text_to_docx_bytes(title: str, text: str) -> bytes:18 doc = DocxDocument()19 20 style = doc.styles["Normal"]21 style.font.name = "Arial"22 style.font.size = Pt(11)23 24 heading = doc.add_heading(title, level=1)25 26 for paragraph in _split_paragraphs(text):27 lines = paragraph.split("\n")28 p = doc.add_paragraph(lines[0])29 for line in lines[1:]:30 p.add_run("\n" + line)31 32 buffer = io.BytesIO()33 doc.save(buffer)34 buffer.seek(0)35 return buffer.read()36 37 38def text_to_pdf_bytes(title: str, text: str) -> bytes:39 buffer = io.BytesIO()40 doc = SimpleDocTemplate(41 buffer, pagesize=A4,42 leftMargin=2.5 * cm, rightMargin=2.5 * cm,43 topMargin=2.5 * cm, bottomMargin=2.5 * cm,44 )45 46 styles = getSampleStyleSheet()47 title_style = ParagraphStyle(48 "TitleStyle", parent=styles["Heading1"], fontSize=16, spaceAfter=18,49 )50 body_style = ParagraphStyle(51 "BodyStyle", parent=styles["Normal"], fontSize=11, leading=16,52 alignment=TA_JUSTIFY, spaceAfter=12,53 )54 55 elements = [Paragraph(title, title_style), Spacer(1, 6)]56 57 for paragraph in _split_paragraphs(text):58 # reportlab Paragraph butuh <br/> untuk line break, bukan \n59 html_safe = (60 paragraph.replace("&", "&").replace("<", "<").replace(">", ">")61 )62 html_safe = html_safe.replace("\n", "<br/>")63 elements.append(Paragraph(html_safe, body_style))64 65 doc.build(elements)66 buffer.seek(0)67 return buffer.read()68 