สร้างด้วย 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>