สร้างด้วย jsPDF
<!DOCTYPE html> <html lang="th"> <head> <meta charset="UTF-8"> <title>Certificate PDF (Thai)</title> <!-- jsPDF --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> <!-- QRCode.js --> <script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script> </head> <body> <div style="text-align:center; margin-top:50px; font-family:sans-serif;"> <h2>สร้าง Certificate ภาษาไทย ด้วย jsPDF</h2> <button onclick="generateCertificate()">ดาวน์โหลด Certificate</button> <p>อ่านเพิ่มเติม <a href="https://parallax.github.io/jsPDF/docs/jsPDF.html" target="_blank"> jsPDF document </a> </p> </div> <script> const { jsPDF } = window.jspdf; // ✅ Helper: โหลดฟอนต์จาก URL แล้วแปลงเป็น Base64 async function loadFont(url) { const res = await fetch(url); const buffer = await res.arrayBuffer(); let binary = ''; const bytes = new Uint8Array(buffer); const chunk = 0x8000; for (let i = 0; i < bytes.length; i += chunk) { binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunk)); } return btoa(binary); } // ✅ Helper: โหลดรูปจาก URL → Base64 async function loadImageAsBase64(url) { const res = await fetch(url); const blob = await res.blob(); return new Promise((resolve) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.readAsDataURL(blob); }); } async function generateCertificate() { const doc = new jsPDF("l", "mm", "a4"); // landscape A4 // ✅ โหลดฟอนต์ภาษาไทย (THSarabunNew Regular / Bold) const fontRegular = await loadFont("https://wichianp.github.io/fonts/THSarabunNew.ttf"); const fontBold = await loadFont("https://wichianp.github.io/fonts/THSarabunNewBold.ttf"); doc.addFileToVFS("THSarabunNew.ttf", fontRegular); doc.addFont("THSarabunNew.ttf", "THSarabunNew", "normal"); doc.addFileToVFS("THSarabunNewBold.ttf", fontBold); doc.addFont("THSarabunNewBold.ttf", "THSarabunNew", "bold"); // ✅ พื้นหลัง Certificate const bg = await loadImageAsBase64("https://semicon.github.io/img/web/bg_web_1.jpg"); // ตัวอย่างภาพ (แทน certificate background) doc.addImage(bg, "JPEG", 0, 0, 297, 210); // a4 landscape = 297x210 mm // ✅ Logo const logo = await loadImageAsBase64("https://semicon.github.io/img/web/logoxxx.png"); doc.addImage(logo, "PNG", 20, 15, 30, 30); // (ภาพ, ชนิดภาพ, x, y, imgWidth, imgHeight); // ✅ ชื่อ Certificate doc.setFont("THSarabunNew", "bold"); doc.setFontSize(28); doc.text("ประกาศนียบัตร", 148, 70, { align: "center" }); // ✅ ข้อความรายละเอียด doc.setFont("THSarabunNew", "normal"); doc.setFontSize(20); doc.text("ขอมอบให้แก่", 148, 90, { align: "center" }); doc.setFont("THSarabunNew", "bold"); doc.setFontSize(22); doc.text("นายวิทยา ใจดี", 148, 105, { align: "center" }); doc.setFont("THSarabunNew", "normal"); doc.setFontSize(18); doc.text("เพื่อแสดงว่าได้เข้าร่วมกิจกรรมอบรมการสร้างเว็บไซต์", 148, 120, { align: "center" }); doc.text("จัดขึ้นเมื่อวันที่ 21 กันยายน 2568", 148, 130, { align: "center" }); // ✅ QR Code → canvas → image const qrDiv = document.createElement("div"); const qr = new QRCode(qrDiv, { text: "https://guruchian.blogspot.com", width: 100, height: 100 }); // รอ render เสร็จ setTimeout(() => { const qrImg = qrDiv.querySelector("img").src; doc.addImage(qrImg, "PNG", 250, 140, 40, 40); // ✅ เซฟ PDF //doc.save("certificate.pdf"); // ✅ เปิด PDF บน Browser window.open(doc.output("bloburl"), "_blank"); }, 500); } </script> </body> </html>
สร้างด้วย pdfMake
<!DOCTYPE html> <html lang="th"> <head> <meta charset="UTF-8"> <title>Certificate PDF with pdfmake</title> <!-- pdfmake --> <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js"></script> </head> <body> <div style="text-align:center; margin-top:50px; font-family:sans-serif;"> <h2>สร้าง Certificate ภาษาไทย ด้วย pdfMake</h2> <button onclick="generateCertificate()">ดาวน์โหลด Certificate (pdfmake)</button> <p> อ่านเพิ่มเติม <a href="https://pdfmake.github.io/docs/0.1/" target="_blank"> pdfMake document </a> </p> </div> <script> // ✅ โหลดฟอนต์จาก URL (Prompt-Regular / Prompt-Bold) async function loadFont(url) { const res = await fetch(url); const buffer = await res.arrayBuffer(); let binary = ''; const bytes = new Uint8Array(buffer); const chunk = 0x8000; for (let i = 0; i < bytes.length; i += chunk) { binary += String.fromCharCode.apply(null, bytes.subarray(i, i + chunk)); } return btoa(binary); } // ✅ โหลดรูป (พื้นหลัง, โลโก้, QR) เป็น Base64 async function loadImageAsBase64(url) { const res = await fetch(url); const blob = await res.blob(); return new Promise((resolve) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result); reader.readAsDataURL(blob); }); } async function generateCertificate() { // โหลดฟอนต์ const promptRegular = await loadFont("https://semicon.github.io/fonts/Prompt-Regular.ttf"); const promptBold = await loadFont("https://semicon.github.io/fonts/Prompt-Bold.ttf"); // โหลดรูป const bg = await loadImageAsBase64("https://semicon.github.io/img/web/bg_web_1.jpg"); // พื้นหลัง const logo = await loadImageAsBase64("https://semicon.github.io/img/web/logoxxx.png"); const qr = await loadImageAsBase64("https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=https://guruchian.blogspot.com"); // สร้าง document definition const docDefinition = { pageSize: "A4", pageOrientation: "landscape", background: [ { image: bg, width: 842, // A4 landscape = 842 x 595 pt height: 595 } ], content: [ { image: logo, width: 80, absolutePosition: { x: 40, y: 40 }, alignment: "center" }, { text: "ประกาศนียบัตร", style: "header", alignment: "center", margin: [0, 100, 0, 20] }, { text: "ขอมอบให้แก่", style: "subheader", alignment: "center" }, { text: "นายวิทยา ใจดี", style: "name", alignment: "center", margin: [0, 10, 0, 10] }, { text: "เพื่อแสดงว่าได้เข้าร่วมกิจกรรมอบรมการสร้างเว็บไซต์", style: "normal", alignment: "center" }, { text: "จัดขึ้นเมื่อวันที่ 21 กันยายน 2568", style: "normal", alignment: "center", margin: [0, 0, 0, 40] }, { image: qr, width: 100, absolutePosition: { x: 720, y: 420 } } ], styles: { header: { font: "PromptBold", fontSize: 28, bold: true }, subheader: { font: "Prompt", fontSize: 18 }, name: { font: "PromptBold", fontSize: 24, bold: true }, normal: { font: "Prompt", fontSize: 16 } }, defaultStyle: { font: "Prompt" } }; // กำหนดฟอนต์ pdfMake.vfs["Prompt-Regular.ttf"] = promptRegular; pdfMake.vfs["Prompt-Bold.ttf"] = promptBold; pdfMake.fonts = { Prompt: { normal: "Prompt-Regular.ttf", bold: "Prompt-Bold.ttf" }, PromptBold: { normal: "Prompt-Bold.ttf", bold: "Prompt-Bold.ttf" } }; // ✅ เซฟ หรือ ดาวน์โหลด PDF
//pdfMake.createPdf(docDefinition).download("certificate.pdf"); // ✅ เปิด PDF บน Browser (แทนการบังคับโหลด)
pdfMake.createPdf(docDefinition).open(); } </script> </body> </html>