1
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
"""Pembuat laporan PDF sederhana (reportlab) untuk ketiga lab."""
|
||||
import textwrap
|
||||
from xml.sax.saxutils import escape
|
||||
|
||||
from reportlab.lib import colors
|
||||
from reportlab.lib.pagesizes import A4
|
||||
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
|
||||
from reportlab.lib.units import cm
|
||||
from reportlab.platypus import (Image, PageBreak, Paragraph, Preformatted,
|
||||
SimpleDocTemplate, Spacer, Table, TableStyle)
|
||||
|
||||
|
||||
class Laporan:
|
||||
def __init__(self, path, judul, subjudul=""):
|
||||
st = getSampleStyleSheet()
|
||||
self.s = {
|
||||
"judul": ParagraphStyle("j", parent=st["Title"], fontSize=19, spaceAfter=4),
|
||||
"sub": ParagraphStyle("sj", parent=st["BodyText"], alignment=1, textColor=colors.grey, spaceAfter=14),
|
||||
"h1": ParagraphStyle("h1", parent=st["Heading1"], fontSize=14, spaceBefore=12, spaceAfter=6),
|
||||
"h2": ParagraphStyle("h2", parent=st["Heading2"], fontSize=11.5, spaceBefore=9, spaceAfter=4),
|
||||
"p": ParagraphStyle("p", parent=st["BodyText"], fontSize=10, leading=14, spaceAfter=5),
|
||||
"sel": ParagraphStyle("sel", parent=st["BodyText"], fontSize=8.5, leading=10.5),
|
||||
"selb": ParagraphStyle("selb", parent=st["BodyText"], fontSize=8.5, leading=10.5, fontName="Helvetica-Bold"),
|
||||
"kode": ParagraphStyle("k", fontName="Courier", fontSize=7.2, leading=8.6,
|
||||
backColor=colors.whitesmoke, borderPadding=4),
|
||||
"cap": ParagraphStyle("cap", parent=st["BodyText"], fontSize=8.5, textColor=colors.grey, spaceAfter=8),
|
||||
}
|
||||
self.doc = SimpleDocTemplate(path, pagesize=A4, leftMargin=2 * cm, rightMargin=2 * cm,
|
||||
topMargin=2 * cm, bottomMargin=2 * cm, title=judul)
|
||||
self.c = [Paragraph(escape(judul), self.s["judul"])]
|
||||
if subjudul:
|
||||
self.c.append(Paragraph(escape(subjudul), self.s["sub"]))
|
||||
|
||||
def h1(self, t): self.c.append(Paragraph(escape(t), self.s["h1"]))
|
||||
def h2(self, t): self.c.append(Paragraph(escape(t), self.s["h2"]))
|
||||
def p(self, t): self.c.append(Paragraph(escape(t), self.s["p"]))
|
||||
def spasi(self, h=6): self.c.append(Spacer(1, h))
|
||||
def halaman_baru(self): self.c.append(PageBreak())
|
||||
|
||||
def cap(self, t): self.c.append(Paragraph(escape(t), self.s["cap"]))
|
||||
|
||||
def kode(self, teks, lebar=105):
|
||||
baris = []
|
||||
for b in teks.expandtabs(4).split("\n"):
|
||||
baris += textwrap.wrap(b, lebar, subsequent_indent=" ", drop_whitespace=False) or [""]
|
||||
self.c.append(Preformatted("\n".join(baris), self.s["kode"]))
|
||||
|
||||
def teks_chunk(self, teks, maks=700):
|
||||
t = teks if len(teks) <= maks else teks[:maks] + " ..."
|
||||
self.c.append(Preformatted(t, self.s["kode"], maxLineLength=100, newLineChars="↵"))
|
||||
self.c.append(Spacer(1, 4))
|
||||
|
||||
def tabel(self, data, lebar=None, header=True):
|
||||
d = [[Paragraph(escape(str(x)), self.s["selb"] if (header and i == 0) else self.s["sel"])
|
||||
for x in baris] for i, baris in enumerate(data)]
|
||||
tb = Table(d, colWidths=lebar, repeatRows=1 if header else 0, hAlign="LEFT")
|
||||
gaya = [("GRID", (0, 0), (-1, -1), 0.4, colors.grey), ("VALIGN", (0, 0), (-1, -1), "TOP")]
|
||||
if header:
|
||||
gaya.append(("BACKGROUND", (0, 0), (-1, 0), colors.HexColor("#e6e6e6")))
|
||||
tb.setStyle(TableStyle(gaya))
|
||||
self.c.append(tb)
|
||||
self.c.append(Spacer(1, 6))
|
||||
|
||||
def gambar(self, path, lebar_cm=15):
|
||||
from PIL import Image as PI
|
||||
w, h = PI.open(path).size
|
||||
self.c.append(Image(path, width=lebar_cm * cm, height=lebar_cm * cm * h / w))
|
||||
|
||||
def simpan(self):
|
||||
def kaki(canvas, doc):
|
||||
canvas.saveState()
|
||||
canvas.setFont("Helvetica", 8)
|
||||
canvas.setFillColor(colors.grey)
|
||||
canvas.drawCentredString(A4[0] / 2, 1.1 * cm, f"Halaman {doc.page}")
|
||||
canvas.restoreState()
|
||||
self.doc.build(self.c, onFirstPage=kaki, onLaterPages=kaki)
|
||||
Reference in New Issue
Block a user