PDF Maker เป็นไลบรารีสำหรับสร้างเอกสาร PDF ใน JavaScript
โปรเจ็กต์นี้ได้รับแรงบันดาลใจจาก pdfmake และสร้างบน pdf-lib และ fontkit มันจะดำรงอยู่ไม่ได้หากปราศจากผลงานอันยิ่งใหญ่และความรู้อันลึกซึ้งที่ผู้เขียนโครงการเหล่านั้นมอบให้
ฟังก์ชัน makePdf()
สร้างข้อมูล PDF จาก คำจำกัดความของเอกสาร ที่กำหนด คำจำกัดความนี้เป็นวัตถุธรรมดา
คุณสมบัติที่สำคัญที่สุดในคำจำกัดความคือชื่อ content
คุณสมบัตินี้ยอมรับรายการ บล็อก มีบล็อกหลายประเภท เช่น บล็อกข้อความ บล็อกรูปภาพ บล็อกเค้าโครงคอลัมน์และแถว
const fontData = await readFile ( 'Roboto-Regular.ttf' ) ;
const fontDataItalic = await readFile ( 'Roboto-Italic.ttf' ) ;
const pdfData = await makePdf ( {
// Fonts must be registered (see below)
fonts : {
Roboto : [ { data : fontData } , { data : fontDataItalic , italic : true } ] ,
} ,
// Content as an array of blocks
content : [
// Blocks can contain text and text properties
{ text : 'Lorem ipsum' , fontStyle : 'italic' , textAlign : 'center' , fontSize : 24 } ,
// Text can also be an array of text spans with different properties
{
text : [
'dolor sit amet, consectetur adipiscing elit ' ,
{ text : 'sed do eiusmod' , fontStyle : 'italic' } ,
' tempor, incididunt ut labore et dolore magna aliqua.' ,
] ,
} ,
] ,
} ) ;
await writeFile ( `hello.pdf` , pdfData ) ;
มีตัวอย่างเพิ่มเติมใน example/ โฟลเดอร์
แบบอักษรทั้งหมดถูกฝังอยู่ใน PDF และต้องลงทะเบียนกับคุณสมบัติ fonts
ข้อมูลแบบอักษรได้รับการยอมรับในรูปแบบ .ttf
หรือ .otf
เช่น ArrayBuffer หรือ Uint8Array ตระกูลแบบอักษรแต่ละตระกูลสามารถมีรูปแบบที่แตกต่างกันซึ่งเลือกตามคุณสมบัติ bold
และ italic
ตระกูลแบบอักษรที่ลงทะเบียนก่อนจะกลายเป็นค่าเริ่มต้น
const documentDefinition = {
fonts : {
'DejaVu-Sans' : [
// Different font versions for fontFamily "DejaVu-Sans"
// TTF / OTF font data as ArrayBuffer or Uin8Array
{ data : fontDataDejaVuSansNormal } ,
{ data : fontDataDejaVuSansBold , bold : true } ,
{ data : fontDataDejaVuSansItalic , italic : true } ,
{ data : fontDataDejaVuSansBoldItalic , bold : true , italic : true } ,
] ,
Roboto : [
// Different font versions for fontFamily "Roboto"
{ data : fontDataRobotoNormal } ,
{ data : fontDataRobotoMedium , bold : true } ,
] ,
} ,
content : [
{ text : 'lorem ipsum' , fontFamily : 'Roboto' , fontWeight : 'bold' } , // will use Roboto Medium
{ text : 'dolor sit amet' } , // will use DejaVu-Sans (the font registered first), normal
] ,
} ;
รองรับรูปภาพ JPG และ PNG เมื่อใช้รูปภาพเดียวกันมากกว่าหนึ่งครั้ง ข้อมูลรูปภาพจะถูกรวมไว้ใน PDF เพียงครั้งเดียว ขนาดของรูปภาพสามารถจำกัดได้โดยใช้คุณสมบัติ width
และ height
// An image block
{ image : 'images/logo.png' , width : 200 , height : 100 } ,
หากต้องการจัดเรียงบล็อกในแนวนอน สามารถรวมไว้ในบล็อกที่มีคุณสมบัติ columns
ได้ เมื่อคอลัมน์มีคุณสมบัติ width
ก็จะถูกเคารพ รหัสช่องว่างที่เหลือกระจายเท่าๆ กันในทุกคอลัมน์
{
columns : [
{ text : 'Column 1' , width : 100 } , // 100 pt wide
{ text : 'Column 2' } , // gets half of the remaining width
{ text : 'Column 3' } , // gets half of the remaining width
] ,
}
โครงร่างแถวสามารถใช้เพื่อจัดกลุ่มแถวหลายแถวให้เป็นบล็อกเดียว เช่น เพื่อใช้คุณสมบัติทั่วไป หรือเพื่อล้อมแถวไว้ในโครงร่างคอลัมน์โดยรอบ
{
rows : [
{ text : 'Row 1' } ,
{ text : 'Row 2' } ,
{ text : 'Row 3' } ,
] ,
textAlign : 'right' ,
}
แต่ละบล็อกสามารถมีคุณสมบัติ graphics
ที่ยอมรับรายการรูปร่างเพื่อวาดลงในบล็อกนั้นหรือฟังก์ชันที่ส่งคืนรายการรูปร่าง ฟังก์ชั่นจะถูกเรียกพร้อมกับความกว้างและความสูงของบล็อก สามารถใช้ในการวาดรูปร่างที่ขึ้นอยู่กับขนาดของบล็อก
รูปร่างอาจเป็นเส้น สี่เหลี่ยม วงกลม หรือเส้นทาง SVG ในตัวอย่างต่อไปนี้ คุณสมบัติกราฟิกใช้ในการวาดพื้นหลังสีเหลืองด้านหลังข้อความและมีเส้นขอบสีน้ำเงินที่ขอบด้านซ้าย
{
text : 'Lorem ipsum' ,
graphics : ( { width , height } ) => [
{ type : 'rect' , x : 0 , y : 0 , width , height , fillColor : 'yellow' } ,
{ type : 'line' , x1 : 0 , y1 : 0 , x2 : 0 , y2 : height , lineColor : 'blue' , lineWidth : 2 } ,
] ,
padding : { left : 5 } ,
}
ดูตัวอย่างกราฟิกด้วย
คุณสมบัติ margin
สามารถใช้เพื่อเพิ่มช่องว่างรอบบล็อกได้ โดยยอมรับค่าเดียว (ใช้กับทั้งสี่ขอบ) วัตถุที่มีคุณสมบัติใดๆ top
, right
, bottom
, left
, x
และ y
คุณสมบัติ x
และ y
สามารถใช้เป็นชวเลขเพื่อตั้งค่าทั้ง left
และ right
หรือ top
และ bottom
พร้อมกันได้ สามารถกำหนดค่าเป็นตัวเลข (เป็น pt) หรือเป็นสตริงที่มีหน่วยได้ หากกำหนดสตริง จะต้องมีหนึ่งในหน่วย pt
, in
, mm
หรือ cm
;
{
margin : { x : 5 , top : 10 } ,
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'dolor sit amet' } ,
] ,
}
ขอบ top
และ bottom
ของบล็อกที่อยู่ติดกันจะถูกยุบให้อยู่ในระยะขอบเดียวซึ่งมีขนาดสูงสุดจากระยะขอบทั้งสอง ระยะขอบคอลัมน์ไม่ยุบ
คุณสมบัติ padding
สามารถใช้เพื่อเพิ่มช่องว่างระหว่างเนื้อหาและขอบของบล็อก
คุณสมบัติ pageSize
ระดับบนสุดสามารถใช้เพื่อกำหนดขนาดหน้าได้ รองรับขนาดมาตรฐานต่างๆ เช่น A4
, Letter
และ Legal
ค่าเริ่มต้นคือ A4 ขนาดหน้าแบบกำหนดเองสามารถระบุเป็นออบเจ็กต์ที่มีคุณสมบัติ width
และ height
สามารถกำหนดค่าเป็นตัวเลข (เป็น pt) หรือเป็นสตริงที่มีหน่วยได้
{
pageSize : { width : '20cm' , height : '20cm' }
}
คุณสมบัติ pageOrientation
สามารถใช้เพื่อตั้งค่าการวางแนวหน้าได้ ค่าอาจเป็น portrait
หรือ landscape
ก็ได้ ค่าเริ่มต้นคือแนวตั้ง
{
pageSize : 'A5' ,
pageOrientation : 'landscape' ,
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'dolor sit amet' } ,
] ,
}
ส่วนหัวและส่วนท้ายที่ซ้ำกันในแต่ละหน้าสามารถกำหนดได้โดยใช้คุณสมบัติ header
และ footer
ที่เป็นทางเลือก ทั้งสองยอมรับบล็อกเดียวหรือฟังก์ชันที่ส่งคืนบล็อก ฟังก์ชั่นจะถูกเรียกพร้อมหมายเลขหน้าและจำนวนหน้าทั้งหมด หมายเลขหน้าเริ่มต้นที่ 1
{
footer : ( { pageNumber , pageCount } ) => ( {
text : `Page ${ pageNumber } of ${ pageCount } ` ,
textAlign : 'right' ,
margin : { x : '20mm' , bottom : '1cm' } ,
} ) ,
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'dolor sit amet' } ,
] ,
}
ตัวแบ่งหน้าจะถูกรวมไว้โดยอัตโนมัติ เมื่อบล็อกไม่พอดีกับหน้าปัจจุบัน หน้าใหม่จะถูกเพิ่มลงในเอกสาร หากต้องการแทรกตัวแบ่งหน้าก่อนหรือหลังบล็อก ให้ตั้งค่าคุณสมบัติ breakBefore
หรือ breakAfter
ของบล็อกเป็น always
เพื่อป้องกันการแตกหน้า ให้ตั้งค่าคุณสมบัตินี้เพื่อ avoid
ตัวแบ่งหน้าจะถูกแทรกระหว่างบรรทัดของบล็อกข้อความโดยอัตโนมัติ หากต้องการป้องกันการแตกหน้าภายในบล็อกข้อความ ให้ตั้งค่าคุณสมบัติ breakInside
เพื่อ avoid
{
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'This text will go on a new page' , breakBefore : 'always' } ,
] ,
}
แม้ว่าจะไม่มีเอกสารประกอบที่สร้างขึ้น แต่คุณสามารถดูโฟลเดอร์ API เพื่อดูข้อกำหนดคุณสมบัติที่รองรับทั้งหมดในคำจำกัดความของเอกสารได้
ตรวจสอบตัวอย่างใน examples/ โฟลเดอร์ด้วย
เอ็มไอที