jsPDF เหมาะมากกับการ export เบา ๆ ในเบราว์เซอร์
jsPDF ได้รับความนิยมเพราะแก้ปัญหาผลิตภัณฑ์จริงได้ตรงจุด: สร้าง PDF ในเบราว์เซอร์โดยไม่ต้องมี backend service นักพัฒนาสามารถวาดข้อความ เส้น รูปภาพ และตารางง่าย ๆ แล้วให้ผู้ใช้ดาวน์โหลดจากหน้าเดิมได้ทันที สำหรับ prototype, หน้าจอ admin เล็ก ๆ, ใบเสร็จที่เก็บในเครื่อง และ PWA ที่ต้องออฟไลน์ได้ นี่เป็นตัวเลือกที่แข็งแรงมาก
คำถามเชิงผลิตภัณฑ์คือขอบเขตของเบราว์เซอร์เริ่มไม่พอเมื่อไร เมื่อ PDF กลายเป็นเอกสารธุรกิจที่ลูกค้าต้องสแกน เก็บถาวร ส่งอีเมล หรือส่งต่อเข้าระบบอื่น งานนี้ไม่ใช่แค่ “วาดไฟล์” อีกต่อไป แต่กลายเป็นการจัดการฟอนต์ ความแม่นยำของบาร์โค้ด ความเสถียรบนมือถือ output ที่ทำซ้ำได้ และบางกรณีคือ PDF/A หรือแพ็กเกจ e-invoice
ได้ PDF เหมือนกัน แต่ขอบเขตความรับผิดชอบต่างกัน
เมื่อใช้ jsPDF แอปหน้าเว็บของคุณคือตัวเรนเดอร์ ทุกแท็บเบราว์เซอร์ต้องถือไลบรารี ฟอนต์ที่เตรียมเอง รูปภาพระหว่างทาง output ของบาร์โค้ด และ bytes ของ PDF สุดท้ายไว้เอง ค่าไลบรารีจึงเป็นศูนย์ แต่ความรับผิดชอบของระบบจริงย้ายไปอยู่บนอุปกรณ์ของผู้ใช้แต่ละคน
เมื่อใช้ gPdf เบราว์เซอร์หรือ backend ส่งคำขอแบบ DocumentRequest หรือ template_id + data ให้ gPdf ฝั่ง gPdf ดูแลสภาพแวดล้อมการเรนเดอร์ ฟอนต์ที่มาพร้อมบริการ รูปทรงบาร์โค้ด และการสร้าง binary PDF บน Edge แอปของคุณยังรับผิดชอบข้อมูลและตรรกะของเทมเพลต แต่ไม่ต้องเป็นเอนจิน PDF เอง
ความเหมาะของผลิตภัณฑ์: export ออฟไลน์หรือเอกสารปฏิบัติการ
เลือก jsPDF เมื่อ PDF เป็นฟีเจอร์อำนวยความสะดวกในเครื่อง เช่น ปุ่มส่งออกเล็ก ๆ, ใบเสร็จภาษา Latin แบบง่าย, snapshot ของแดชบอร์ด หรือ PWA ที่ต้องใช้งานได้แม้ไม่มีเครือข่าย
เลือก gPdf เมื่อ PDF เป็นส่วนหนึ่งของกระบวนการปฏิบัติการ เช่น ป้ายจัดส่ง, ป้ายคลังสินค้า, ใบแจ้งหนี้, ตั๋ว, ใบแจ้งยอด, customs form และใบเสร็จข้ามประเทศ เอกสารเหล่านี้ต้องได้ output เดียวกันทุกอุปกรณ์ ไม่ใช่ขึ้นกับสิ่งที่แท็บเบราว์เซอร์ตอนนั้นประกอบได้อย่างปลอดภัย
โมเดลต้นทุน: ไลบรารีฟรีกับภาระ production ที่คุณต้องดูแลเอง
ข้อได้เปรียบด้านราคาของ jsPDF ชัดเจน: ตัวไลบรารีเป็น open source และ CPU ของเบราว์เซอร์ไม่ได้ปรากฏเป็นบรรทัดหนึ่งในบิล cloud สำหรับฟีเจอร์ภายในขนาดเล็ก นี่อาจเป็นทางที่ถูกที่สุด
ต้นทุนระบบจริงมักไปอยู่รอบ ๆ ไลบรารี:
- ไฟล์ฟอนต์ที่รองรับ CJK หรือโมดูลฟอนต์ base64 ที่สร้างไว้
- ไลบรารีสำหรับ encode และแปลงบาร์โค้ด
- bug ด้านหน่วยความจำและการดาวน์โหลดที่ต่างกันตามเบราว์เซอร์
- print QA สำหรับเครื่องสแกนและ thermal printer
- regression test บน desktop, iOS Safari, Android WebView และ embedded browser
gPdf เปลี่ยนสิ่งนี้เป็นบิลตามการใช้งาน แผน Basic สาธารณะเริ่มที่ 5 USD/เดือนสำหรับ 100,000 หน้า และส่วนเกินมาตรฐานเริ่มที่ 0.00005 USD ต่อหน้า นี่เป็นต้นทุนผู้ขาย แต่ลดความจำเป็นที่ bundle ฝั่งหน้าเว็บทุกตัวและอุปกรณ์ผู้ใช้ทุกเครื่องต้องทำตัวเหมือนบริการ PDF สำหรับระบบจริง
ต้นทุน CJK ไม่ใช่แค่ขนาดไฟล์
จุดแข็งที่ชนก่อนคือข้อความ CJK: จีน ญี่ปุ่น และเกาหลี
ฟอนต์ PDF มาตรฐานที่มากับ jsPDF ใช้ได้ดีกับ output ภาษา Latin แบบง่าย แต่ไม่ได้ครอบคลุม Unicode glyph ทุกตัว เมื่อเอกสารมีข้อความ CJK แอปต้องมีฟอนต์ที่มี glyph เหล่านั้นจริง ๆ ในการใช้งานจริง งานฝั่งเบราว์เซอร์มักต้อง package ไฟล์ TTF, แปลงเป็นโมดูล JavaScript แบบ base64 หรือดึงข้อมูลฟอนต์ก่อนสร้าง PDF
ต้นทุนนี้จ่ายสองรอบ: รอบแรกคือข้อมูลฝั่งหน้าเว็บที่ใหญ่ขึ้น รอบที่สองคือหน่วยความจำของเบราว์เซอร์ระหว่างสร้าง PDF บนมือถือ แท็บเดียวอาจต้องถือเว็บแอป ฟอนต์ buffer ของบาร์โค้ด รูปภาพ และ bytes ของ PDF สุดท้ายพร้อมกัน
gPdf เก็บงานนี้ไว้ฝั่งบริการ เบราว์เซอร์ส่ง JSON ที่มีโครงสร้าง แล้วตัวเรนเดอร์เลือกใช้ฟอนต์ที่มาพร้อมบริการ ซึ่งครอบคลุม Latin, Greek, Cyrillic, CJK, Arabic, Devanagari, Bengali, Thai และ monospace ข้อมูลคำสั่งซื้อขนาดประมาณ 2 KB จึงไม่ต้องกลายเป็นเส้นทางส่งฟอนต์ 12 MB
บาร์โค้ด: encode ง่าย แต่พิมพ์ให้สแกนติดยากกว่า
ในโลจิสติกส์ อีคอมเมิร์ซ การผลิต healthcare, ticketing และ retail บาร์โค้ดอาจสำคัญกว่าข้อความที่มองเห็น คนอ่านหมายเลข order แต่ระบบปฏิบัติการอ่าน Code 128, GS1-128, QR, DataMatrix หรือ PDF417
เมื่อใช้ jsPDF การสร้างบาร์โค้ดมักเป็นการตัดสินใจเพิ่มอีกชั้น ทีมจะจับ jsPDF คู่กับ encoder อีกตัว เรนเดอร์บาร์โค้ดเป็น SVG, canvas หรือรูปภาพ แล้ววางผลลัพธ์นั้นลงใน PDF วิธีนี้ใช้ได้กับ QR coupon หรือ proof of concept
แต่จะเปราะเมื่อบาร์โค้ดที่พิมพ์ออกมาต้องใช้จริงในงาน:
- บาร์โค้ดบน canvas อาจถูก rasterize ด้วย resolution ที่ผิด
- รูปภาพที่ถูกย่อขยายอาจทำให้แท่ง โมดูล หรือ quiet zone เบลอ
- เบราว์เซอร์, CSS transform หรือเส้นทาง export อาจเปลี่ยนขนาดจริงสุดท้าย
- รูปแบบบาร์โค้ดต่างกันอาจต้องใช้ไลบรารีหรือเส้นทางแปลงต่างกัน
- เครื่องพิมพ์ thermal 203 DPI เผยข้อผิดพลาดเรื่องขนาดเล็ก ๆ ได้เร็วมาก
gPdf มองบาร์โค้ดเป็นองค์ประกอบของเอกสาร คำขอระบุ type: "barcode", format, ข้อมูลที่เข้ารหัส และขนาดจริงเป็นมิลลิเมตร ตัวเรนเดอร์จะสร้างรูปทรงเวกเตอร์ใน PDF สำหรับรูปแบบ 1D และ 2D ที่รองรับ ดังนั้นข้อความ shape ตาราง รูปภาพ และบาร์โค้ดจะอยู่ในระบบพิกัดเดียวกัน
Studio และการปรับเทมเพลต
jsPDF เป็นแนว code-first การเปลี่ยนเลย์เอาต์มักหมายถึงแก้คำสั่งวาด ตำแหน่ง การลงทะเบียนฟอนต์ การแปลงรูปภาพ และตำแหน่งบาร์โค้ดใน JavaScript
gPdf รองรับแนว API-first เช่นกัน แต่เพิ่ม gPdf Studio เป็นตัวออกแบบแบบเห็นภาพฟรีสำหรับเลย์เอาต์ PDF ทีมสามารถเพิ่มและลากข้อความ รูปภาพ ตาราง รูปร่าง หัวกระดาษ ท้ายกระดาษ และบาร์โค้ด แล้วเชื่อม design เข้ากับการสร้างแบบ template_id + data ได้ สิ่งนี้สำคัญเมื่อรูปแบบป้าย ใบแจ้งหนี้ หรือใบเสร็จเปลี่ยนบ่อย และคนที่ไม่ใช่ผู้เชี่ยวชาญ PDF ต้องมีส่วนร่วมกับเลย์เอาต์
เบราว์เซอร์มือถือไม่ใช่ที่ที่เหมาะกับงาน PDF หนัก ๆ
การสร้าง PDF ฝั่ง client ดูเหมือนถูก เพราะค่า server เป็นศูนย์ แต่ต้นทุนถูกย้ายไปอยู่ที่อุปกรณ์ผู้ใช้
บน desktop อาจยังพอรับได้ บนเบราว์เซอร์มือถือ เอกสาร production หนึ่งชุดอาจกดแท็บหนักมาก: ข้อมูลฟอนต์ CJK, รูปภาพ base64, canvas buffer, รูปบาร์โค้ด, bytes ของ PDF ที่สร้างแล้ว และแอปที่กำลังทำงานอยู่ แย่งหน่วยความจำในเวลาเดียวกัน iOS Safari และ Android เครื่องหน่วยความจำต่ำไม่ผ่อนปรนเท่า laptop ของนักพัฒนา
การย้ายงานสร้างไป gPdf เปลี่ยนรูปของปัญหา เบราว์เซอร์สร้างคำขอ JSON ขนาดเล็ก รอ response แบบ binary แล้วดาวน์โหลด PDF ที่เสร็จแล้ว แท็บของผู้ใช้ไม่ต้องเป็นทั้งตัวจัดการฟอนต์ ตัวเรนเดอร์บาร์โค้ด เอนจินเลย์เอาต์ และตัวเขียน binary PDF ในที่เดียว
เมื่อ jsPDF ยังเป็นตัวเลือกที่ถูกกว่าในเชิงสถาปัตยกรรม
ยังมีเหตุผลที่ชัดเจนมากในการใช้ jsPDF ต่อ
ถ้าผู้ใช้ต้อง export ขณะออฟไลน์ jsPDF เหมาะกว่า ถ้าข้อมูลห้ามออกจากอุปกรณ์เลย การสร้าง PDF ฝั่งเบราว์เซอร์คือขอบเขตความเป็นส่วนตัวที่สะอาดกว่า ถ้าเอกสารเล็ก ใช้เฉพาะ Latin และสร้างเป็นครั้งคราว การเพิ่ม API อาจไม่คุ้ม สำหรับ prototype และเครื่องมือภายใน jsPDF มักเป็นทางที่เร็วที่สุดจริง ๆ
การตัดสินใจเปลี่ยนเมื่อ output เป็นส่วนหนึ่งของกระบวนการปฏิบัติการ: ป้ายจัดส่งที่ต้องสแกนติด, ใบแจ้งหนี้ที่ต้องเก็บถาวร, ตั๋วที่ต้องตรวจสอบได้ หรือเอกสาร order ข้ามประเทศที่ต้องเรนเดอร์ชื่อ CJK ให้ถูก ณ จุดนั้น “สร้าง PDF ในเบราว์เซอร์” สำคัญน้อยกว่า “สร้าง PDF production แบบเดียวกันได้อย่างน่าเชื่อถือ”
รูปแบบการย้าย
การย้ายไม่ใช่แค่เปลี่ยน function call หนึ่งตัว แต่เป็นการย้ายจาก imperative drawing ในเบราว์เซอร์ ไปเป็นคำขอเอกสารที่มีโครงสร้าง
- // Before: browser-side drawing with jsPDF plus extra font/barcode setup.
- import { jsPDF } from "jspdf";
- import JsBarcode from "jsbarcode";
-
- const doc = new jsPDF({ unit: "mm", format: [100, 150] });
- // Load a CJK-capable TTF and register it before drawing CJK text.
- doc.addFileToVFS("NotoSansCJK-Regular.ttf", base64Font);
- doc.addFont("NotoSansCJK-Regular.ttf", "NotoSansCJK", "normal");
- doc.setFont("NotoSansCJK");
- doc.text("跨境订单 / Cross-border order", 6, 10);
-
- // Generate a barcode separately, then place it into the PDF.
- JsBarcode(canvas, "PDN0003507278", { format: "CODE128" });
- doc.addImage(canvas.toDataURL("image/png"), "PNG", 6, 72, 72, 20);
- doc.save("label.pdf");
+
+ // After: send one structured DocumentRequest to gPdf.
+ const res = await fetch("https://api.gpdf.com/api/v1/pdf/render", {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${KEY}`,
+ "Content-Type": "application/json"
+ },
+ body: JSON.stringify({
+ settings: {
+ defaults: {
+ text: {
+ font_family: "NotoSans-Regular",
+ font_mode: "prefer",
+ font_size: 9,
+ color: "#111827"
+ }
+ }
+ },
+ pages: [{
+ width: 100,
+ height: 150,
+ elements: [
+ {
+ type: "text",
+ x: 6,
+ y: 8,
+ content: "跨境订单 / Cross-border order",
+ style: { width: 88, font_size: 12, font_weight: "bold" }
+ },
+ {
+ type: "barcode",
+ x: 6,
+ y: 70,
+ width: 72,
+ height: 18,
+ format: "code128",
+ content: "PDN0003507278",
+ barcode_text: { enabled: true, position: "bottom", offset: 1 }
+ },
+ {
+ type: "barcode",
+ x: 80,
+ y: 8,
+ width: 14,
+ height: 14,
+ format: "qrcode",
+ content: "https://track.example/PDN0003507278",
+ barcode_text: { enabled: false, position: "bottom" }
+ }
+ ]
+ }]
+ })
+ });
+ const pdf = await res.arrayBuffer();
จุดเปลี่ยนสำคัญคือความเป็นเจ้าของ เมื่อใช้ jsPDF เว็บแอปของคุณต้องดูแลเส้นทางฟอนต์ CJK, การสร้างบาร์โค้ด, โปรไฟล์หน่วยความจำของเบราว์เซอร์ และพฤติกรรม export เมื่อใช้ gPdf แอปของคุณดูแลข้อมูลและเทมเพลต ส่วนตัวเรนเดอร์บน Edge ดูแลกลไกเอกสาร
สถานการณ์ PDF ที่เกี่ยวข้อง
ทีมที่กำลังเทียบ jsPDF กับ gPdf มักดูเรื่องเดียวกันหลายมุม: ถ้าต้องการสร้าง PDF จากข้อมูลธุรกิจแบบมีโครงสร้าง ให้ดู API แปลง JSON เป็น PDF และ API PDF ใบแจ้งหนี้; ถ้าเอกสารต้องพิมพ์และสแกนจริง ให้ดู API ป้ายจัดส่ง กับ API บาร์โค้ด GS1; ถ้าอยากให้ทีมแก้เลย์เอาต์โดยไม่แตะโค้ดทุกครั้ง ให้ดู API เทมเพลต PDF และถ้ามีงานเก็บถาวรให้ตรวจ API PDF/A
FAQ
jsPDF ฟรีไหม?
ตัวไลบรารีเป็น open source ต้นทุน production คือสิ่งรอบตัว: ฟอนต์ CJK, ไลบรารีบาร์โค้ด, browser QA, print QA และการรองรับอุปกรณ์ที่หน่วยความจำไม่พอ
gPdf แทน jsPDF ได้ทุกกรณีไหม?
ไม่ การ export ในเบราว์เซอร์แบบออฟไลน์และเอกสารที่อยู่ในเครื่องเท่านั้นยังเป็นพื้นที่ธรรมชาติของ jsPDF gPdf เหมาะกับเอกสาร production ที่ตัวเรนเดอร์ซึ่งควบคุมได้คุ้มกับการเรียก API
ทำไมต้องแยกต้นทุนบาร์โค้ดออกมา?
เพราะบาร์โค้ดที่ดูดีบนหน้าจออาจสแกนไม่ติดหลังการย่อขยาย การ rasterize หรือการพิมพ์ด้วยเครื่องพิมพ์ thermal เอกสารปฏิบัติการต้องการความน่าเชื่อถือของเครื่องสแกน ไม่ใช่แค่ pattern ที่มองเห็นได้
อ่านต่อ
- เอกสารอ้างอิง gPdf API -
DocumentRequest, องค์ประกอบบาร์โค้ด, ฟอนต์สำรอง และ endpoint สำหรับเรนเดอร์ - บาร์โค้ดเวกเตอร์เทียบกับ raster ใน PDF - ทำไมรูปทรงบาร์โค้ดยังสำคัญหลังพิมพ์
- บาร์โค้ด GS1-128 ที่ความละเอียด 0.1 mm ใน JSON - รายละเอียดขนาดบาร์โค้ดสำหรับงานป้าย
- PDF/A และ Factur-X สำหรับวิศวกร - เมื่อข้อกำหนดการเก็บถาวรและ e-invoice เข้ามาใน pipeline ของ PDF