Python: Nulis nama di PDF Sertifikat

From OnnoWiki
Jump to navigation Jump to search

Bisa. Cara paling aman biasanya begini:

  • siapkan 1 file template sertifikat PDF
  • siapkan 1 file daftar nama
  • jalankan script untuk membuat 1 PDF per nama

Di bawah ini script Python yang umum dipakai. Script ini akan:

  • membaca nama dari file `nama.txt`
  • menaruh nama di posisi tertentu pada template PDF
  • menghasilkan file baru seperti `sertifikat_Andi.pdf`, `sertifikat_Budi.pdf`, dst.
import os
import re
import io
from pathlib import Path

from pypdf import PdfReader, PdfWriter
from reportlab.pdfgen import canvas
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics

# =========================
# KONFIGURASI
# =========================
TEMPLATE_PDF = "template_sertifikat.pdf"
DAFTAR_NAMA = "nama.txt"
OUTPUT_DIR = "output_sertifikat"
# Posisi nama pada halaman PDF
# Satuan: points
# Titik (0,0) ada di kiri bawah halaman
NAMA_X = 297   # contoh tengah halaman A4 landscape
NAMA_Y = 250

FONT_NAME = "Helvetica-Bold"
FONT_SIZE = 28
TEXT_COLOR = (0, 0, 0)  # RGB 0-1 akan di-set di bawah

# Jika ingin pakai font TTF sendiri, uncomment ini:
# FONT_TTF_PATH = "Montserrat-Bold.ttf"
# pdfmetrics.registerFont(TTFont("CustomFont", FONT_TTF_PATH))
# FONT_NAME = "CustomFont"

# =========================
# FUNGSI BANTUAN
# =========================
def safe_filename(text: str) -> str:
    text = text.strip()
    text = re.sub(r"[^\w\s-]", "", text, flags=re.UNICODE)
    text = re.sub(r"\s+", "_", text)
    return text

def buat_overlay(page_width, page_height, nama):
    packet = io.BytesIO()
    c = canvas.Canvas(packet, pagesize=(page_width, page_height)) 

    c.setFont(FONT_NAME, FONT_SIZE)
    c.setFillColorRGB(*TEXT_COLOR) 

    # Tulis nama dengan anchor tengah
    text_width = pdfmetrics.stringWidth(nama, FONT_NAME, FONT_SIZE)
    c.drawString(NAMA_X - (text_width / 2), NAMA_Y, nama) 

    c.save()
    packet.seek(0)
    return PdfReader(packet)

def baca_daftar_nama(path_file):
    with open(path_file, "r", encoding="utf-8") as f:
        return [line.strip() for line in f if line.strip()] 

# =========================
# PROSES UTAMA
# =========================
def main():
    os.makedirs(OUTPUT_DIR, exist_ok=True) 

    names = baca_daftar_nama(DAFTAR_NAMA)
    if not names:
        raise ValueError("File nama.txt kosong atau tidak ada nama valid.")

    template_reader = PdfReader(TEMPLATE_PDF)
    if len(template_reader.pages) == 0:
        raise ValueError("Template PDF tidak memiliki halaman.")

    template_page = template_reader.pages[0]
    page_width = float(template_page.mediabox.width)
    page_height = float(template_page.mediabox.height) 

    for nama in names:
        reader = PdfReader(TEMPLATE_PDF)
        writer = PdfWriter() 

        page = reader.pages[0]
        overlay_pdf = buat_overlay(page_width, page_height, nama)
        overlay_page = overlay_pdf.pages[0]

        page.merge_page(overlay_page)
        writer.add_page(page)

        # Jika template punya lebih dari 1 halaman, tambahkan sisanya
        for i in range(1, len(reader.pages)):
            writer.add_page(reader.pages[i])

        nama_file = safe_filename(nama)
        output_path = Path(OUTPUT_DIR) / f"sertifikat_{nama_file}.pdf" 

        with open(output_path, "wb") as out_file:
            writer.write(out_file)

        print(f"Berhasil membuat: {output_path}")

if __name__ == "__main__":
    main()

Siapkan file `nama.txt` seperti ini:

Andi Saputra
Budi Santoso
Citra Lestari
Dewi Anggraini

Install library yang dibutuhkan:

pip install pypdf reportlab

Lalu jalankan:

python buat_sertifikat.py


Hal penting:

  • `NAMA_X` dan `NAMA_Y` harus disesuaikan dengan posisi area nama di sertifikat.
  • Kalau teks nama terlalu panjang, bisa:
 * kecilkan `FONT_SIZE`
 * ganti font
 * atau pakai logika auto-fit.

Kalau Anda mau, saya bisa lanjut buatkan versi yang lebih lengkap, misalnya:

  • baca dari Excel/CSV
  • otomatis mengecilkan font jika nama kepanjangan
  • tambah nomor sertifikat, tanggal, dan judul kegiatan
  • atau saya sesuaikan langsung berdasarkan template PDF yang Anda upload.