เรียนรู้เพิ่มเติมที่ pdf-lib.js.org
pdf-lib
ถูกสร้างขึ้นเพื่อจัดการกับระบบนิเวศของ JavaScript ที่ขาดการสนับสนุนที่มีประสิทธิภาพสำหรับการจัดการ PDF (โดยเฉพาะอย่างยิ่งสำหรับ การแก้ไข PDF)
คุณสมบัติที่แตกต่างสองประการของ pdf-lib
คือ:
มีไลบรารี PDF JavaScript โอเพ่นซอร์สที่ดีอื่น ๆ ให้เลือก อย่างไรก็ตาม ส่วนใหญ่สามารถ สร้าง ได้เฉพาะเอกสารเท่านั้น ไม่สามารถ แก้ไข เอกสารที่มีอยู่ได้ และส่วนใหญ่ใช้งานได้ในสภาพแวดล้อมเฉพาะเท่านั้น
ตัวอย่างนี้สร้าง PDF นี้
ลองสาธิต JSFiddle
import { PDFDocument , StandardFonts , rgb } from 'pdf-lib'
// Create a new PDFDocument
const pdfDoc = await PDFDocument . create ( )
// Embed the Times Roman font
const timesRomanFont = await pdfDoc . embedFont ( StandardFonts . TimesRoman )
// Add a blank page to the document
const page = pdfDoc . addPage ( )
// Get the width and height of the page
const { width , height } = page . getSize ( )
// Draw a string of text toward the top of the page
const fontSize = 30
page . drawText ( 'Creating PDFs in JavaScript is awesome!' , {
x : 50 ,
y : height - 4 * fontSize ,
size : fontSize ,
font : timesRomanFont ,
color : rgb ( 0 , 0.53 , 0.71 ) ,
} )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
ตัวอย่างนี้สร้าง PDF นี้ (เมื่อ PDF นี้ใช้สำหรับตัวแปร existingPdfBytes
)
ลองสาธิต JSFiddle
import { degrees , PDFDocument , rgb , StandardFonts } from 'pdf-lib' ;
// This should be a Uint8Array or ArrayBuffer
// This data can be obtained in a number of different ways
// If your running in a Node environment, you could use fs.readFile()
// In the browser, you could make a fetch() call and use res.arrayBuffer()
const existingPdfBytes = ...
// Load a PDFDocument from the existing PDF bytes
const pdfDoc = await PDFDocument . load ( existingPdfBytes )
// Embed the Helvetica font
const helveticaFont = await pdfDoc . embedFont ( StandardFonts . Helvetica )
// Get the first page of the document
const pages = pdfDoc . getPages ( )
const firstPage = pages [ 0 ]
// Get the width and height of the first page
const { width , height } = firstPage . getSize ( )
// Draw a string of text diagonally across the first page
firstPage . drawText ( 'This text was added with JavaScript!' , {
x : 5 ,
y : height / 2 + 300 ,
size : 50 ,
font : helveticaFont ,
color : rgb ( 0.95 , 0.1 , 0.1 ) ,
rotate : degrees ( - 45 ) ,
} )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
ตัวอย่างนี้สร้าง PDF นี้
ลองสาธิต JSFiddle
ดูเพิ่มเติมที่การสร้างและการกรอกแบบฟอร์ม
import { PDFDocument } from 'pdf-lib'
// Create a new PDFDocument
const pdfDoc = await PDFDocument . create ( )
// Add a blank page to the document
const page = pdfDoc . addPage ( [ 550 , 750 ] )
// Get the form so we can add fields to it
const form = pdfDoc . getForm ( )
// Add the superhero text field and description
page . drawText ( 'Enter your favorite superhero:' , { x : 50 , y : 700 , size : 20 } )
const superheroField = form . createTextField ( 'favorite.superhero' )
superheroField . setText ( 'One Punch Man' )
superheroField . addToPage ( page , { x : 55 , y : 640 } )
// Add the rocket radio group, labels, and description
page . drawText ( 'Select your favorite rocket:' , { x : 50 , y : 600 , size : 20 } )
page . drawText ( 'Falcon Heavy' , { x : 120 , y : 560 , size : 18 } )
page . drawText ( 'Saturn IV' , { x : 120 , y : 500 , size : 18 } )
page . drawText ( 'Delta IV Heavy' , { x : 340 , y : 560 , size : 18 } )
page . drawText ( 'Space Launch System' , { x : 340 , y : 500 , size : 18 } )
const rocketField = form . createRadioGroup ( 'favorite.rocket' )
rocketField . addOptionToPage ( 'Falcon Heavy' , page , { x : 55 , y : 540 } )
rocketField . addOptionToPage ( 'Saturn IV' , page , { x : 55 , y : 480 } )
rocketField . addOptionToPage ( 'Delta IV Heavy' , page , { x : 275 , y : 540 } )
rocketField . addOptionToPage ( 'Space Launch System' , page , { x : 275 , y : 480 } )
rocketField . select ( 'Saturn IV' )
// Add the gundam check boxes, labels, and description
page . drawText ( 'Select your favorite gundams:' , { x : 50 , y : 440 , size : 20 } )
page . drawText ( 'Exia' , { x : 120 , y : 400 , size : 18 } )
page . drawText ( 'Kyrios' , { x : 120 , y : 340 , size : 18 } )
page . drawText ( 'Virtue' , { x : 340 , y : 400 , size : 18 } )
page . drawText ( 'Dynames' , { x : 340 , y : 340 , size : 18 } )
const exiaField = form . createCheckBox ( 'gundam.exia' )
const kyriosField = form . createCheckBox ( 'gundam.kyrios' )
const virtueField = form . createCheckBox ( 'gundam.virtue' )
const dynamesField = form . createCheckBox ( 'gundam.dynames' )
exiaField . addToPage ( page , { x : 55 , y : 380 } )
kyriosField . addToPage ( page , { x : 55 , y : 320 } )
virtueField . addToPage ( page , { x : 275 , y : 380 } )
dynamesField . addToPage ( page , { x : 275 , y : 320 } )
exiaField . check ( )
dynamesField . check ( )
// Add the planet dropdown and description
page . drawText ( 'Select your favorite planet*:' , { x : 50 , y : 280 , size : 20 } )
const planetsField = form . createDropdown ( 'favorite.planet' )
planetsField . addOptions ( [ 'Venus' , 'Earth' , 'Mars' , 'Pluto' ] )
planetsField . select ( 'Pluto' )
planetsField . addToPage ( page , { x : 55 , y : 220 } )
// Add the person option list and description
page . drawText ( 'Select your favorite person:' , { x : 50 , y : 180 , size : 18 } )
const personField = form . createOptionList ( 'favorite.person' )
personField . addOptions ( [
'Julius Caesar' ,
'Ada Lovelace' ,
'Cleopatra' ,
'Aaron Burr' ,
'Mark Antony' ,
] )
personField . select ( 'Ada Lovelace' )
personField . addToPage ( page , { x : 55 , y : 70 } )
// Just saying...
page . drawText ( `* Pluto should be a planet too!` , { x : 15 , y : 15 , size : 15 } )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
ตัวอย่างนี้สร้าง PDF นี้ (เมื่อ PDF นี้ใช้สำหรับตัวแปร formPdfBytes
รูปภาพนี้จะใช้สำหรับตัวแปร marioImageBytes
และรูปภาพนี้จะใช้สำหรับตัวแปร emblemImageBytes
)
ลองสาธิต JSFiddle
ดูเพิ่มเติมที่การสร้างและการกรอกแบบฟอร์ม
import { PDFDocument } from 'pdf-lib'
// These should be Uint8Arrays or ArrayBuffers
// This data can be obtained in a number of different ways
// If your running in a Node environment, you could use fs.readFile()
// In the browser, you could make a fetch() call and use res.arrayBuffer()
const formPdfBytes = ...
const marioImageBytes = ...
const emblemImageBytes = ...
// Load a PDF with form fields
const pdfDoc = await PDFDocument . load ( formPdfBytes )
// Embed the Mario and emblem images
const marioImage = await pdfDoc . embedPng ( marioImageBytes )
const emblemImage = await pdfDoc . embedPng ( emblemImageBytes )
// Get the form containing all the fields
const form = pdfDoc . getForm ( )
// Get all fields in the PDF by their names
const nameField = form . getTextField ( 'CharacterName 2' )
const ageField = form . getTextField ( 'Age' )
const heightField = form . getTextField ( 'Height' )
const weightField = form . getTextField ( 'Weight' )
const eyesField = form . getTextField ( 'Eyes' )
const skinField = form . getTextField ( 'Skin' )
const hairField = form . getTextField ( 'Hair' )
const alliesField = form . getTextField ( 'Allies' )
const factionField = form . getTextField ( 'FactionName' )
const backstoryField = form . getTextField ( 'Backstory' )
const traitsField = form . getTextField ( 'Feat+Traits' )
const treasureField = form . getTextField ( 'Treasure' )
const characterImageField = form . getButton ( 'CHARACTER IMAGE' )
const factionImageField = form . getTextField ( 'Faction Symbol Image' )
// Fill in the basic info fields
nameField . setText ( 'Mario' )
ageField . setText ( '24 years' )
heightField . setText ( `5' 1"` )
weightField . setText ( '196 lbs' )
eyesField . setText ( 'blue' )
skinField . setText ( 'white' )
hairField . setText ( 'brown' )
// Fill the character image field with our Mario image
characterImageField . setImage ( marioImage )
// Fill in the allies field
alliesField . setText (
[
`Allies:` ,
` • Princess Daisy` ,
` • Princess Peach` ,
` • Rosalina` ,
` • Geno` ,
` • Luigi` ,
` • Donkey Kong` ,
` • Yoshi` ,
` • Diddy Kong` ,
`` ,
`Organizations:` ,
` • Italian Plumbers Association` ,
] . join ( 'n' ) ,
)
// Fill in the faction name field
factionField . setText ( `Mario's Emblem` )
// Fill the faction image field with our emblem image
factionImageField . setImage ( emblemImage )
// Fill in the backstory field
backstoryField . setText (
`Mario is a fictional character in the Mario video game franchise, owned by Nintendo and created by Japanese video game designer Shigeru Miyamoto. Serving as the company's mascot and the eponymous protagonist of the series, Mario has appeared in over 200 video games since his creation. Depicted as a short, pudgy, Italian plumber who resides in the Mushroom Kingdom, his adventures generally center upon rescuing Princess Peach from the Koopa villain Bowser. His younger brother and sidekick is Luigi.` ,
)
// Fill in the traits field
traitsField . setText (
[
`Mario can use three basic three power-ups:` ,
` • the Super Mushroom, which causes Mario to grow larger` ,
` • the Fire Flower, which allows Mario to throw fireballs` ,
` • the Starman, which gives Mario temporary invincibility` ,
] . join ( 'n' ) ,
)
// Fill in the treasure field
treasureField . setText ( [ '• Gold coins' , '• Treasure chests' ] . join ( 'n' ) )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
ตัวอย่างนี้สร้าง PDF นี้ (เมื่อ PDF นี้ถูกใช้สำหรับตัวแปร formPdfBytes
)
ลองสาธิต JSFiddle
import { PDFDocument } from 'pdf-lib'
// This should be a Uint8Array or ArrayBuffer
// This data can be obtained in a number of different ways
// If your running in a Node environment, you could use fs.readFile()
// In the browser, you could make a fetch() call and use res.arrayBuffer()
const formPdfBytes = ...
// Load a PDF with form fields
const pdfDoc = await PDFDocument . load ( formPdfBytes )
// Get the form containing all the fields
const form = pdfDoc . getForm ( )
// Fill the form's fields
form . getTextField ( 'Text1' ) . setText ( 'Some Text' ) ;
form . getRadioGroup ( 'Group2' ) . select ( 'Choice1' ) ;
form . getRadioGroup ( 'Group3' ) . select ( 'Choice3' ) ;
form . getRadioGroup ( 'Group4' ) . select ( 'Choice1' ) ;
form . getCheckBox ( 'Check Box3' ) . check ( ) ;
form . getCheckBox ( 'Check Box4' ) . uncheck ( ) ;
form . getDropdown ( 'Dropdown7' ) . select ( 'Infinity' ) ;
form . getOptionList ( 'List Box6' ) . select ( 'Honda' ) ;
// Flatten the form's fields
form . flatten ( ) ;
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
ตัวอย่างนี้สร้าง PDF นี้ (เมื่อ PDF นี้ถูกใช้สำหรับตัวแปร firstDonorPdfBytes
และ PDF นี้ถูกใช้สำหรับตัวแปร secondDonorPdfBytes
)
ลองสาธิต JSFiddle
import { PDFDocument } from 'pdf-lib'
// Create a new PDFDocument
const pdfDoc = await PDFDocument . create ( )
// These should be Uint8Arrays or ArrayBuffers
// This data can be obtained in a number of different ways
// If your running in a Node environment, you could use fs.readFile()
// In the browser, you could make a fetch() call and use res.arrayBuffer()
const firstDonorPdfBytes = ...
const secondDonorPdfBytes = ...
// Load a PDFDocument from each of the existing PDFs
const firstDonorPdfDoc = await PDFDocument . load ( firstDonorPdfBytes )
const secondDonorPdfDoc = await PDFDocument . load ( secondDonorPdfBytes )
// Copy the 1st page from the first donor document, and
// the 743rd page from the second donor document
const [ firstDonorPage ] = await pdfDoc . copyPages ( firstDonorPdfDoc , [ 0 ] )
const [ secondDonorPage ] = await pdfDoc . copyPages ( secondDonorPdfDoc , [ 742 ] )
// Add the first copied page
pdfDoc . addPage ( firstDonorPage )
// Insert the second copied page to index 0, so it will be the
// first page in `pdfDoc`
pdfDoc . insertPage ( 0 , secondDonorPage )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
ตัวอย่างนี้สร้าง PDF นี้ (เมื่ออิมเมจนี้ใช้สำหรับตัวแปร jpgImageBytes
และอิมเมจนี้ใช้สำหรับตัวแปร pngImageBytes
)
ลองสาธิต JSFiddle
import { PDFDocument } from 'pdf-lib'
// These should be Uint8Arrays or ArrayBuffers
// This data can be obtained in a number of different ways
// If your running in a Node environment, you could use fs.readFile()
// In the browser, you could make a fetch() call and use res.arrayBuffer()
const jpgImageBytes = ...
const pngImageBytes = ...
// Create a new PDFDocument
const pdfDoc = await PDFDocument . create ( )
// Embed the JPG image bytes and PNG image bytes
const jpgImage = await pdfDoc . embedJpg ( jpgImageBytes )
const pngImage = await pdfDoc . embedPng ( pngImageBytes )
// Get the width/height of the JPG image scaled down to 25% of its original size
const jpgDims = jpgImage . scale ( 0.25 )
// Get the width/height of the PNG image scaled down to 50% of its original size
const pngDims = pngImage . scale ( 0.5 )
// Add a blank page to the document
const page = pdfDoc . addPage ( )
// Draw the JPG image in the center of the page
page . drawImage ( jpgImage , {
x : page . getWidth ( ) / 2 - jpgDims . width / 2 ,
y : page . getHeight ( ) / 2 - jpgDims . height / 2 ,
width : jpgDims . width ,
height : jpgDims . height ,
} )
// Draw the PNG image near the lower right corner of the JPG image
page . drawImage ( pngImage , {
x : page . getWidth ( ) / 2 - pngDims . width / 2 + 75 ,
y : page . getHeight ( ) / 2 - pngDims . height ,
width : pngDims . width ,
height : pngDims . height ,
} )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
ตัวอย่างนี้สร้าง PDF นี้ (เมื่อ PDF นี้ใช้สำหรับตัวแปร americanFlagPdfBytes
และ PDF นี้ใช้สำหรับตัวแปร usConstitutionPdfBytes
)
ลองสาธิต JSFiddle
import { PDFDocument } from 'pdf-lib'
// These should be Uint8Arrays or ArrayBuffers
// This data can be obtained in a number of different ways
// If your running in a Node environment, you could use fs.readFile()
// In the browser, you could make a fetch() call and use res.arrayBuffer()
const americanFlagPdfBytes = ...
const usConstitutionPdfBytes = ...
// Create a new PDFDocument
const pdfDoc = await PDFDocument . create ( )
// Embed the American flag PDF bytes
const [ americanFlag ] = await pdfDoc . embedPdf ( americanFlagPdfBytes )
// Load the U.S. constitution PDF bytes
const usConstitutionPdf = await PDFDocument . load ( usConstitutionPdfBytes )
// Embed the second page of the constitution and clip the preamble
const preamble = await pdfDoc . embedPage ( usConstitutionPdf . getPages ( ) [ 1 ] , {
left : 55 ,
bottom : 485 ,
right : 300 ,
top : 575 ,
} )
// Get the width/height of the American flag PDF scaled down to 30% of
// its original size
const americanFlagDims = americanFlag . scale ( 0.3 )
// Get the width/height of the preamble clipping scaled up to 225% of
// its original size
const preambleDims = preamble . scale ( 2.25 )
// Add a blank page to the document
const page = pdfDoc . addPage ( )
// Draw the American flag image in the center top of the page
page . drawPage ( americanFlag , {
... americanFlagDims ,
x : page . getWidth ( ) / 2 - americanFlagDims . width / 2 ,
y : page . getHeight ( ) - americanFlagDims . height - 150 ,
} )
// Draw the preamble clipping in the center bottom of the page
page . drawPage ( preamble , {
... preambleDims ,
x : page . getWidth ( ) / 2 - preambleDims . width / 2 ,
y : page . getHeight ( ) / 2 - preambleDims . height / 2 - 50 ,
} )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
pdf-lib
อาศัยโมดูลน้องสาวเพื่อรองรับการฝังแบบอักษรที่กำหนดเอง: @pdf-lib/fontkit
คุณต้องเพิ่มโมดูล @pdf-lib/fontkit
ให้กับโปรเจ็กต์ของคุณและลงทะเบียนโดยใช้ pdfDoc.registerFontkit(...)
ก่อนที่จะฝังฟอนต์แบบกำหนดเอง
ดูคำแนะนำในการติดตั้งโดยละเอียดด้านล่างเกี่ยวกับการติดตั้ง
@pdf-lib/fontkit
เป็นโมดูล UMD หรือ NPM
ตัวอย่างนี้สร้าง PDF นี้ (เมื่อใช้แบบอักษรนี้สำหรับตัวแปร fontBytes
)
ลองสาธิต JSFiddle
import { PDFDocument , rgb } from 'pdf-lib'
import fontkit from '@pdf-lib/fontkit'
// This should be a Uint8Array or ArrayBuffer
// This data can be obtained in a number of different ways
// If you're running in a Node environment, you could use fs.readFile()
// In the browser, you could make a fetch() call and use res.arrayBuffer()
const fontBytes = ...
// Create a new PDFDocument
const pdfDoc = await PDFDocument . create ( )
// Register the `fontkit` instance
pdfDoc . registerFontkit ( fontkit )
// Embed our custom font in the document
const customFont = await pdfDoc . embedFont ( fontBytes )
// Add a blank page to the document
const page = pdfDoc . addPage ( )
// Create a string of text and measure its width and height in our custom font
const text = 'This is text in an embedded font!'
const textSize = 35
const textWidth = customFont . widthOfTextAtSize ( text , textSize )
const textHeight = customFont . heightAtSize ( textSize )
// Draw the string of text on the page
page . drawText ( text , {
x : 40 ,
y : 450 ,
size : textSize ,
font : customFont ,
color : rgb ( 0 , 0.53 , 0.71 ) ,
} )
// Draw a box around the string of text
page . drawRectangle ( {
x : 40 ,
y : 450 ,
width : textWidth ,
height : textHeight ,
borderColor : rgb ( 1 , 0 , 0 ) ,
borderWidth : 1.5 ,
} )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
ตัวอย่างนี้สร้าง PDF นี้ (เมื่ออิมเมจนี้ใช้สำหรับตัวแปร jpgAttachmentBytes
และ PDF นี้ใช้สำหรับตัวแปร pdfAttachmentBytes
)
ลองสาธิต JSFiddle
import { PDFDocument } from 'pdf-lib'
// These should be Uint8Arrays or ArrayBuffers
// This data can be obtained in a number of different ways
// If your running in a Node environment, you could use fs.readFile()
// In the browser, you could make a fetch() call and use res.arrayBuffer()
const jpgAttachmentBytes = ...
const pdfAttachmentBytes = ...
// Create a new PDFDocument
const pdfDoc = await PDFDocument . create ( )
// Add the JPG attachment
await pdfDoc . attach ( jpgAttachmentBytes , 'cat_riding_unicorn.jpg' , {
mimeType : 'image/jpeg' ,
description : 'Cool cat riding a unicorn! ???️' ,
creationDate : new Date ( '2019/12/01' ) ,
modificationDate : new Date ( '2020/04/19' ) ,
} )
// Add the PDF attachment
await pdfDoc . attach ( pdfAttachmentBytes , 'us_constitution.pdf' , {
mimeType : 'application/pdf' ,
description : 'Constitution of the United States ???' ,
creationDate : new Date ( '1787/09/17' ) ,
modificationDate : new Date ( '1992/05/07' ) ,
} )
// Add a page with some text
const page = pdfDoc . addPage ( ) ;
page . drawText ( 'This PDF has two attachments' , { x : 135 , y : 415 } )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
ตัวอย่างนี้สร้าง PDF นี้
ลองสาธิต JSFiddle
import { PDFDocument , StandardFonts } from 'pdf-lib'
// Create a new PDFDocument
const pdfDoc = await PDFDocument . create ( )
// Embed the Times Roman font
const timesRomanFont = await pdfDoc . embedFont ( StandardFonts . TimesRoman )
// Add a page and draw some text on it
const page = pdfDoc . addPage ( [ 500 , 600 ] )
page . setFont ( timesRomanFont )
page . drawText ( 'The Life of an Egg' , { x : 60 , y : 500 , size : 50 } )
page . drawText ( 'An Epic Tale of Woe' , { x : 125 , y : 460 , size : 25 } )
// Set all available metadata fields on the PDFDocument. Note that these fields
// are visible in the "Document Properties" section of most PDF readers.
pdfDoc . setTitle ( '? The Life of an Egg ?' )
pdfDoc . setAuthor ( 'Humpty Dumpty' )
pdfDoc . setSubject ( ' An Epic Tale of Woe ' )
pdfDoc . setKeywords ( [ 'eggs' , 'wall' , 'fall' , 'king' , 'horses' , 'men' ] )
pdfDoc . setProducer ( 'PDF App 9000 ?' )
pdfDoc . setCreator ( 'pdf-lib (https://github.com/Hopding/pdf-lib)' )
pdfDoc . setCreationDate ( new Date ( '2018-06-24T01:58:37.228Z' ) )
pdfDoc . setModificationDate ( new Date ( '2019-12-21T07:00:11.000Z' ) )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
ลองสาธิต JSFiddle
import { PDFDocument } from 'pdf-lib'
// This should be a Uint8Array or ArrayBuffer
// This data can be obtained in a number of different ways
// If your running in a Node environment, you could use fs.readFile()
// In the browser, you could make a fetch() call and use res.arrayBuffer()
const existingPdfBytes = ...
// Load a PDFDocument without updating its existing metadata
const pdfDoc = await PDFDocument . load ( existingPdfBytes , {
updateMetadata : false
} )
// Print all available metadata fields
console . log ( 'Title:' , pdfDoc . getTitle ( ) )
console . log ( 'Author:' , pdfDoc . getAuthor ( ) )
console . log ( 'Subject:' , pdfDoc . getSubject ( ) )
console . log ( 'Creator:' , pdfDoc . getCreator ( ) )
console . log ( 'Keywords:' , pdfDoc . getKeywords ( ) )
console . log ( 'Producer:' , pdfDoc . getProducer ( ) )
console . log ( 'Creation Date:' , pdfDoc . getCreationDate ( ) )
console . log ( 'Modification Date:' , pdfDoc . getModificationDate ( ) )
สคริปต์นี้ให้ผลลัพธ์ต่อไปนี้ ( เมื่อ PDF นี้ถูกใช้สำหรับตัวแปร existingPdfBytes
):
Title: Microsoft Word - Basic Curriculum Vitae example.doc
Author: Administrator
Subject: undefined
Creator: PScript5.dll Version 5.2
Keywords: undefined
Producer: Acrobat Distiller 8.1.0 (Windows)
Creation Date: 2010-07-29T14:26:00.000Z
Modification Date: 2010-07-29T14:26:00.000Z
import {
PDFDocument ,
StandardFonts ,
NonFullScreenPageMode ,
ReadingDirection ,
PrintScaling ,
Duplex ,
PDFName ,
} from 'pdf-lib'
// Create a new PDFDocument
const pdfDoc = await PDFDocument . create ( )
// Embed the Times Roman font
const timesRomanFont = await pdfDoc . embedFont ( StandardFonts . TimesRoman )
// Add a page and draw some text on it
const page = pdfDoc . addPage ( [ 500 , 600 ] )
page . setFont ( timesRomanFont )
page . drawText ( 'The Life of an Egg' , { x : 60 , y : 500 , size : 50 } )
page . drawText ( 'An Epic Tale of Woe' , { x : 125 , y : 460 , size : 25 } )
// Set all available viewer preferences on the PDFDocument:
const viewerPrefs = pdfDoc . catalog . getOrCreateViewerPreferences ( )
viewerPrefs . setHideToolbar ( true )
viewerPrefs . setHideMenubar ( true )
viewerPrefs . setHideWindowUI ( true )
viewerPrefs . setFitWindow ( true )
viewerPrefs . setCenterWindow ( true )
viewerPrefs . setDisplayDocTitle ( true )
// Set the PageMode (otherwise setting NonFullScreenPageMode has no meaning)
pdfDoc . catalog . set ( PDFName . of ( 'PageMode' ) , PDFName . of ( 'FullScreen' ) )
// Set what happens when fullScreen is closed
viewerPrefs . setNonFullScreenPageMode ( NonFullScreenPageMode . UseOutlines )
viewerPrefs . setReadingDirection ( ReadingDirection . L2R )
viewerPrefs . setPrintScaling ( PrintScaling . None )
viewerPrefs . setDuplex ( Duplex . DuplexFlipLongEdge )
viewerPrefs . setPickTrayByPDFSize ( true )
// We can set the default print range to only the first page
viewerPrefs . setPrintPageRange ( { start : 0 , end : 0 } )
// Or we can supply noncontiguous ranges (e.g. pages 1, 3, and 5-7)
viewerPrefs . setPrintPageRange ( [
{ start : 0 , end : 0 } ,
{ start : 2 , end : 2 } ,
{ start : 4 , end : 6 } ,
] )
viewerPrefs . setNumCopies ( 2 )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
import { PDFDocument } from 'pdf-lib'
// This should be a Uint8Array or ArrayBuffer
// This data can be obtained in a number of different ways
// If your running in a Node environment, you could use fs.readFile()
// In the browser, you could make a fetch() call and use res.arrayBuffer()
const existingPdfBytes = ...
// Load a PDFDocument without updating its existing metadata
const pdfDoc = await PDFDocument . load ( existingPdfBytes )
const viewerPrefs = pdfDoc . catalog . getOrCreateViewerPreferences ( )
// Print all available viewer preference fields
console . log ( 'HideToolbar:' , viewerPrefs . getHideToolbar ( ) )
console . log ( 'HideMenubar:' , viewerPrefs . getHideMenubar ( ) )
console . log ( 'HideWindowUI:' , viewerPrefs . getHideWindowUI ( ) )
console . log ( 'FitWindow:' , viewerPrefs . getFitWindow ( ) )
console . log ( 'CenterWindow:' , viewerPrefs . getCenterWindow ( ) )
console . log ( 'DisplayDocTitle:' , viewerPrefs . getDisplayDocTitle ( ) )
console . log ( 'NonFullScreenPageMode:' , viewerPrefs . getNonFullScreenPageMode ( ) )
console . log ( 'ReadingDirection:' , viewerPrefs . getReadingDirection ( ) )
console . log ( 'PrintScaling:' , viewerPrefs . getPrintScaling ( ) )
console . log ( 'Duplex:' , viewerPrefs . getDuplex ( ) )
console . log ( 'PickTrayByPDFSize:' , viewerPrefs . getPickTrayByPDFSize ( ) )
console . log ( 'PrintPageRange:' , viewerPrefs . getPrintPageRange ( ) )
console . log ( 'NumCopies:' , viewerPrefs . getNumCopies ( ) )
สคริปต์นี้ให้ผลลัพธ์ต่อไปนี้ ( เมื่อ PDF นี้ถูกใช้สำหรับตัวแปร existingPdfBytes
):
HideToolbar: true
HideMenubar: true
HideWindowUI: false
FitWindow: true
CenterWindow: true
DisplayDocTitle: true
NonFullScreenPageMode: UseNone
ReadingDirection: R2L
PrintScaling: None
Duplex: DuplexFlipLongEdge
PickTrayByPDFSize: true
PrintPageRange: [ { start: 1, end: 1 }, { start: 3, end: 4 } ]
NumCopies: 2
ตัวอย่างนี้สร้าง PDF นี้
ลองสาธิต JSFiddle
import { PDFDocument , rgb } from 'pdf-lib'
// SVG path for a wavy line
const svgPath =
'M 0,20 L 100,160 Q 130,200 150,120 C 190,-40 200,200 300,150 L 400,90'
// Create a new PDFDocument
const pdfDoc = await PDFDocument . create ( )
// Add a blank page to the document
const page = pdfDoc . addPage ( )
page . moveTo ( 100 , page . getHeight ( ) - 5 )
// Draw the SVG path as a black line
page . moveDown ( 25 )
page . drawSvgPath ( svgPath )
// Draw the SVG path as a thick green line
page . moveDown ( 200 )
page . drawSvgPath ( svgPath , { borderColor : rgb ( 0 , 1 , 0 ) , borderWidth : 5 } )
// Draw the SVG path and fill it with red
page . moveDown ( 200 )
page . drawSvgPath ( svgPath , { color : rgb ( 1 , 0 , 0 ) } )
// Draw the SVG path at 50% of its original size
page . moveDown ( 200 )
page . drawSvgPath ( svgPath , { scale : 0.5 } )
// Serialize the PDFDocument to bytes (a Uint8Array)
const pdfBytes = await pdfDoc . save ( )
// For example, `pdfBytes` can be:
// • Written to a file in Node
// • Downloaded from the browser
// • Rendered in an <iframe>
pdf-lib
รองรับรันไทม์ Deno ใหม่ที่น่าตื่นเต้นอย่างเต็มที่! ตัวอย่างการใช้งานทั้งหมดทำงานใน Deno สิ่งเดียวที่คุณต้องทำคือเปลี่ยนการนำเข้าสำหรับ pdf-lib
และ @pdf-lib/fontkit
เพื่อใช้ Skypack CDN เนื่องจาก Deno ต้องการให้โมดูลทั้งหมดอ้างอิงผ่าน URL
ดูเพิ่มเติมวิธีการสร้างและแก้ไขไฟล์ PDF ใน Deno ด้วย pdf-lib
ด้านล่างนี้เป็นตัวอย่าง เอกสารการสร้าง ที่แก้ไขสำหรับ Deno:
import {
PDFDocument ,
StandardFonts ,
rgb ,
} from 'https://cdn.skypack.dev/pdf-lib@^1.11.1?dts' ;
const pdfDoc = await PDFDocument . create ( ) ;
const timesRomanFont = await pdfDoc . embedFont ( StandardFonts . TimesRoman ) ;
const page = pdfDoc . addPage ( ) ;
const { width , height } = page . getSize ( ) ;
const fontSize = 30 ;
page . drawText ( 'Creating PDFs in JavaScript is awesome!' , {
x : 50 ,
y : height - 4 * fontSize ,
size : fontSize ,
font : timesRomanFont ,
color : rgb ( 0 , 0.53 , 0.71 ) ,
} ) ;
const pdfBytes = await pdfDoc . save ( ) ;
await Deno . writeFile ( 'out.pdf' , pdfBytes ) ;
หากคุณบันทึกสคริปต์นี้เป็น create-document.ts
คุณสามารถดำเนินการได้โดยใช้ Deno ด้วยคำสั่งต่อไปนี้:
deno run --allow-write create-document.ts
ไฟล์ out.pdf
ที่ได้จะมีลักษณะเช่นนี้
นี่เป็นตัวอย่างที่ซับซ้อนกว่าเล็กน้อยซึ่งสาธิตวิธีฝังแบบอักษรและวัดข้อความใน Deno:
import {
degrees ,
PDFDocument ,
rgb ,
StandardFonts ,
} from 'https://cdn.skypack.dev/pdf-lib@^1.11.1?dts' ;
import fontkit from 'https://cdn.skypack.dev/@pdf-lib/fontkit@^1.0.0?dts' ;
const url = 'https://pdf-lib.js.org/assets/ubuntu/Ubuntu-R.ttf' ;
const fontBytes = await fetch ( url ) . then ( ( res ) => res . arrayBuffer ( ) ) ;
const pdfDoc = await PDFDocument . create ( ) ;
pdfDoc . registerFontkit ( fontkit ) ;
const customFont = await pdfDoc . embedFont ( fontBytes ) ;
const page = pdfDoc . addPage ( ) ;
const text = 'This is text in an embedded font!' ;
const textSize = 35 ;
const textWidth = customFont . widthOfTextAtSize ( text , textSize ) ;
const textHeight = customFont . heightAtSize ( textSize ) ;
page . drawText ( text , {
x : 40 ,
y : 450 ,
size : textSize ,
font : customFont ,
color : rgb ( 0 , 0.53 , 0.71 ) ,
} ) ;
page . drawRectangle ( {
x : 40 ,
y : 450 ,
width : textWidth ,
height : textHeight ,
borderColor : rgb ( 1 , 0 , 0 ) ,
borderWidth : 1.5 ,
} ) ;
const pdfBytes = await pdfDoc . save ( ) ;
await Deno . writeFile ( 'out.pdf' , pdfBytes ) ;
หากคุณบันทึกสคริปต์นี้เป็น custom-font.ts
คุณสามารถดำเนินการได้โดยใช้คำสั่งต่อไปนี้:
deno run --allow-write --allow-net custom-font.ts
ไฟล์ out.pdf
ที่ได้จะมีลักษณะเช่นนี้
ตัวอย่างการใช้งานมีโค้ดที่กระชับและตรงประเด็น ซึ่งแสดงให้เห็นคุณสมบัติต่างๆ ของ pdf-lib
คุณสามารถดูตัวอย่างการทำงานที่สมบูรณ์ได้ในไดเร็กทอรี apps/
แอปเหล่านี้ใช้เพื่อทำการทดสอบ pdf-lib
ด้วยตนเองก่อนการเปิดตัวทุกครั้ง (นอกเหนือจากการทดสอบอัตโนมัติ)
ขณะนี้มีสี่แอพ:
node
- มีการทดสอบสำหรับ pdf-lib
ในสภาพแวดล้อมของโหนด การทดสอบเหล่านี้เป็นข้อมูลอ้างอิงที่สะดวกเมื่อพยายามบันทึก/โหลด PDF, แบบอักษร หรือรูปภาพด้วย pdf-lib
จากระบบไฟล์ นอกจากนี้ยังช่วยให้คุณสามารถเปิด PDF ของคุณในโปรแกรมดูต่างๆ ได้อย่างรวดเร็ว (Acrobat, Preview, Foxit, Chrome, Firefox ฯลฯ...) เพื่อให้มั่นใจถึงความเข้ากันได้web
- มีการทดสอบสำหรับ pdf-lib
ในสภาพแวดล้อมของเบราว์เซอร์ การทดสอบเหล่านี้เป็นข้อมูลอ้างอิงที่สะดวกเมื่อพยายามบันทึก/โหลด PDF, แบบอักษร หรือรูปภาพด้วย pdf-lib
ในสภาพแวดล้อมของเบราว์เซอร์rn
- มีการทดสอบสำหรับ pdf-lib
ในสภาพแวดล้อม React Native การทดสอบเหล่านี้เป็นข้อมูลอ้างอิงที่สะดวกเมื่อพยายามบันทึก/โหลด PDF, แบบอักษร หรือรูปภาพด้วย pdf-lib
ในสภาพแวดล้อม React Nativedeno
- มีการทดสอบสำหรับ pdf-lib
ในสภาพแวดล้อม Deno การทดสอบเหล่านี้เป็นข้อมูลอ้างอิงที่มีประโยชน์เมื่อพยายามบันทึก/โหลด PDF, แบบอักษร หรือรูปภาพด้วย pdf-lib
จากระบบไฟล์ วิธีติดตั้งเวอร์ชันเสถียรล่าสุด:
# With npm
npm install --save pdf-lib
# With yarn
yarn add pdf-lib
สิ่งนี้ถือว่าคุณใช้ npm หรือเส้นด้ายเป็นตัวจัดการแพ็คเกจของคุณ
คุณยังสามารถดาวน์โหลด pdf-lib
เป็นโมดูล UMD ได้จาก unpkg หรือ jsDelivr บิลด์ UMD ได้รับการคอมไพล์เป็น ES5 ดังนั้นจึงควรใช้งานได้กับเบราว์เซอร์รุ่นใหม่ การสร้าง UMD มีประโยชน์หากคุณไม่ได้ใช้ตัวจัดการแพ็คเกจหรือตัวรวมโมดูล ตัวอย่างเช่น คุณสามารถใช้โดยตรงในแท็ก <script>
ของหน้า HTML
มีบิลด์ต่อไปนี้:
หมายเหตุ: หากคุณใช้สคริปต์ CDN ในการใช้งานจริง คุณควรใส่หมายเลขเวอร์ชันเฉพาะใน URL เช่น:
- https://unpkg.com/[email protected]/dist/pdf-lib.min.js
- https://cdn.jsdelivr.net/npm/[email protected]/dist/pdf-lib.min.js
เมื่อใช้บิลด์ UMD คุณจะสามารถเข้าถึงตัวแปร window.PDFLib
ส่วนกลางได้ ตัวแปรนี้มีคลาสและฟังก์ชันทั้งหมดที่ส่งออกโดย pdf-lib
ตัวอย่างเช่น:
// NPM module
import { PDFDocument , rgb } from 'pdf-lib' ;
// UMD module
var PDFDocument = PDFLib . PDFDocument ;
var rgb = PDFLib . rgb ;
pdf-lib
อาศัยโมดูลน้องสาวเพื่อรองรับการฝังแบบอักษรที่กำหนดเอง: @pdf-lib/fontkit
คุณต้องเพิ่มโมดูล @pdf-lib/fontkit
ให้กับโปรเจ็กต์ของคุณและลงทะเบียนโดยใช้ pdfDoc.registerFontkit(...)
ก่อนที่จะฝังฟอนต์แบบกำหนดเอง (ดูตัวอย่างการฝังฟอนต์) โมดูลนี้จะไม่รวมอยู่ตามค่าเริ่มต้น เนื่องจากผู้ใช้บางคนไม่ต้องการโมดูลนี้ และจะเพิ่มขนาดชุดรวม
การติดตั้งโมดูลนี้เป็นเรื่องง่าย เช่นเดียวกับ pdf-lib
เอง @pdf-lib/fontkit
สามารถติดตั้งด้วย npm
/ yarn
หรือเป็นโมดูล UMD
# With npm
npm install --save @pdf-lib/fontkit
# With yarn
yarn add @pdf-lib/fontkit
หากต้องการลงทะเบียนอินสแตนซ์ fontkit
:
import { PDFDocument } from 'pdf-lib'
import fontkit from '@pdf-lib/fontkit'
const pdfDoc = await PDFDocument . create ( )
pdfDoc . registerFontkit ( fontkit )
มีบิลด์ต่อไปนี้:
หมายเหตุ: หากคุณใช้สคริปต์ CDN ในการใช้งานจริง คุณควรใส่หมายเลขเวอร์ชันเฉพาะใน URL เช่น:
- https://unpkg.com/@pdf-lib/[email protected]/dist/fontkit.umd.min.js
- https://cdn.jsdelivr.net/npm/@pdf-lib/[email protected]/dist/fontkit.umd.min.js
เมื่อใช้บิลด์ UMD คุณจะสามารถเข้าถึงตัวแปร window.fontkit
ส่วนกลางได้ หากต้องการลงทะเบียนอินสแตนซ์ fontkit
:
var pdfDoc = await PDFLib . PDFDocument . create ( )
pdfDoc . registerFontkit ( fontkit )
เอกสาร API มีอยู่ในไซต์โครงการที่ https://pdf-lib.js.org/docs/api/
repo สำหรับไซต์โครงการ (และไฟล์เอกสารที่สร้างขึ้น) ตั้งอยู่ที่นี่: https://github.com/Hopding/pdf-lib-docs
เมื่อทำงานกับ PDF คุณมักจะเจอคำว่า "การเข้ารหัสอักขระ" และ "แบบอักษร" บ่อยครั้ง หากคุณมีประสบการณ์ในการพัฒนาเว็บไซต์ คุณอาจสงสัยว่าทำไมสิ่งเหล่านี้ถึงแพร่หลายมาก มันไม่ใช่แค่รายละเอียดที่น่ารำคาญที่คุณไม่ควรต้องกังวลใช่ไหม? ไลบรารี PDF และโปรแกรมอ่านไม่ควรสามารถจัดการทั้งหมดนี้ให้คุณได้เหมือนกับที่เว็บเบราว์เซอร์สามารถทำได้ใช่ไหม น่าเสียดายที่นี่ไม่ใช่กรณี ลักษณะของรูปแบบไฟล์ PDF ทำให้เป็นเรื่องยากมากที่จะหลีกเลี่ยงการคำนึงถึงการเข้ารหัสอักขระและแบบอักษรเมื่อทำงานกับ PDF
pdf-lib
พยายามอย่างเต็มที่เพื่อทำให้สิ่งต่าง ๆ ง่ายขึ้นสำหรับคุณ แต่ไม่สามารถแสดงเวทย์มนตร์ได้ ซึ่งหมายความว่าคุณควรตระหนักถึงสิ่งต่อไปนี้:
import { PDFDocument , StandardFonts } from 'pdf-lib'
const pdfDoc = await PDFDocument . create ( )
const courierFont = await pdfDoc . embedFont ( StandardFonts . Courier )
const page = pdfDoc . addPage ( )
page . drawText ( 'Some boring latin text in the Courier font' , {
font : courierFont ,
} )
embedFont
เมื่อคุณฝังแบบอักษรของคุณเอง คุณสามารถใช้อักขระ Unicode ใดก็ได้ที่แบบอักษรนั้นรองรับ ความสามารถนี้ช่วยให้คุณหลุดพ้นจากข้อจำกัดที่กำหนดโดยฟอนต์มาตรฐาน ไฟล์ PDF ส่วนใหญ่ใช้แบบอักษรฝังตัว คุณสามารถฝังและใช้แบบอักษรที่กำหนดเองได้ (ดูเพิ่มเติม): import { PDFDocument } from 'pdf-lib'
import fontkit from '@pdf-lib/fontkit'
const url = 'https://pdf-lib.js.org/assets/ubuntu/Ubuntu-R.ttf'
const fontBytes = await fetch ( url ) . then ( ( res ) => res . arrayBuffer ( ) )
const pdfDoc = await PDFDocument . create ( )
pdfDoc . registerFontkit ( fontkit )
const ubuntuFont = await pdfDoc . embedFont ( fontBytes )
const page = pdfDoc . addPage ( )
page . drawText ( 'Some fancy Unicode text in the ŪЬȕǹƚü font' , {
font : ubuntuFont ,
} )
โปรดทราบว่าข้อผิดพลาดในการเข้ารหัสจะเกิดขึ้นหากคุณพยายามใช้อักขระที่มีแบบอักษรที่ไม่รองรับ ตัวอย่างเช่น Ω
ไม่ได้อยู่ในชุดอักขระ WinAnsi ดังนั้นการพยายามวาดมันบนหน้าด้วยฟอนต์ Helvetica มาตรฐานจะเกิดข้อผิดพลาดต่อไปนี้:
Error: WinAnsi cannot encode "Ω" (0x03a9)
at Encoding.encodeUnicodeCodePoint
โดยทั่วไปการฝังแบบอักษรในเอกสาร PDF จะทำให้ไฟล์มีขนาดใหญ่ขึ้น คุณสามารถลดขนาดไฟล์ที่เพิ่มขึ้นได้โดยการตั้งค่าย่อยแบบอักษรเพื่อให้ฝังเฉพาะอักขระที่จำเป็นเท่านั้น คุณสามารถเซ็ตย่อยแบบอักษรได้โดยตั้งค่าตัวเลือก subset
เป็น true
ตัวอย่างเช่น:
const font = await pdfDoc . embedFont ( fontBytes , { subset : true } ) ;
โปรดทราบว่าการตั้งค่าย่อยใช้ไม่ได้กับแบบอักษรทั้งหมด ดู #207 (ความคิดเห็น) สำหรับรายละเอียดเพิ่มเติม
pdf-lib
สามารถสร้าง กรอก และอ่านฟิลด์แบบฟอร์ม PDF ได้ รองรับประเภทฟิลด์ต่อไปนี้:
ดูตัวอย่างการใช้งานการสร้างแบบฟอร์มและการกรอกแบบฟอร์มสำหรับตัวอย่างโค้ด การทดสอบ 1, 14, 15, 16 และ 17 ในตัวอย่างที่สมบูรณ์มีโค้ดตัวอย่างการทำงานสำหรับการสร้างแบบฟอร์มและการกรอกในสภาพแวดล้อม JS ต่างๆ
สิ่งสำคัญ: แบบอักษรเริ่มต้นที่ใช้แสดงข้อความในปุ่ม รายการแบบเลื่อนลง รายการตัวเลือก และช่องข้อความคือแบบอักษร Helvetica มาตรฐาน แบบอักษรนี้รองรับเฉพาะอักขระในอักษรละตินเท่านั้น (ดูรายละเอียดแบบอักษรและ Unicode) ซึ่งหมายความว่า หากมีการสร้างหรือแก้ไขประเภทฟิลด์ใด ๆ เหล่านี้เพื่อให้มีข้อความนอกตัวอักษรละติน (ตามปกติ) คุณจะต้องฝังและใช้แบบอักษรที่กำหนดเองเพื่ออัปเดตลักษณะที่ปรากฏของฟิลด์ มิฉะนั้นจะเกิดข้อผิดพลาด (อาจเกิดขึ้นเมื่อคุณบันทึก PDFDocument
)
คุณสามารถใช้แบบอักษรที่ฝังไว้เมื่อกรอกแบบฟอร์มดังต่อไปนี้:
import { PDFDocument } from 'pdf-lib' ;
import fontkit from '@pdf-lib/fontkit' ;
// Fetch the PDF with form fields
const formUrl = 'https://pdf-lib.js.org/assets/dod_character.pdf' ;
const formBytes = await fetch ( formUrl ) . then ( ( res ) => res . arrayBuffer ( ) ) ;
// Fetch the Ubuntu font
const fontUrl = 'https://pdf-lib.js.org/assets/ubuntu/Ubuntu-R.ttf' ;
const fontBytes = await fetch ( fontUrl ) . then ( ( res ) => res . arrayBuffer ( ) ) ;
// Load the PDF with form fields
const pdfDoc = await PDFDocument . load ( formBytes ) ;
// Embed the Ubuntu font
pdfDoc . registerFontkit ( fontkit ) ;
const ubuntuFont = await pdfDoc . embedFont ( fontBytes ) ;
// Get two text fields from the form
const form = pdfDoc . getForm ( ) ;
const nameField = form . getTextField ( 'CharacterName 2' ) ;
const ageField = form . getTextField ( 'Age' ) ;
// Fill the text fields with some fancy Unicode characters (outside
// the WinAnsi latin character set)
nameField . setText ( 'Ӎӑȑїõ' ) ;
ageField . setText ( '24 ŷȇȁŗš' ) ;
// **Key Step:** Update the field appearances with the Ubuntu font
form . updateFieldAppearances ( ubuntuFont ) ;
// Save the PDF with filled form fields
const pdfBytes = await pdfDoc . save ( ) ;
ฟิลด์แบบฟอร์มที่มีอยู่สามารถเข้าถึงได้ด้วยวิธี PDFForm
ต่อไปนี้:
PDFForm.getButton
PDFForm.getCheckBox
PDFForm.getDropdown
PDFForm.getOptionList
PDFForm.getRadioGroup
PDFForm.getTextField
สามารถสร้างฟิลด์แบบฟอร์มใหม่ได้ด้วยวิธีการต่อไปนี้ของ PDFForm
:
PDFForm.createButton
PDFForm.createCheckBox
PDFForm.createDropdown
PDFForm.createOptionList
PDFForm.createRadioGroup
PDFForm.createTextField
ด้านล่างนี้คือวิธีการที่ใช้กันทั่วไปบางส่วนในการอ่านและการเติมคลาสย่อยของ PDFField
ที่กล่าวมาข้างต้น :
PDFCheckBox.check
PDFCheckBox.uncheck
PDFCheckBox.isChecked
PDFDropdown.select
PDFDropdown.clear
PDFDropdown.getSelected
PDFDropdown.getOptions
PDFDropdown.addOptions
PDFOptionList.select
PDFOptionList.clear
PDFOptionList.getSelected
PDFOptionList.getOptions
PDFOptionList.addOptions
PDFRadioGroup.select
PDFRadioGroup.clear
PDFRadioGroup.getSelected
PDFRadioGroup.getOptions
PDFRadioGroup.addOptionToPage
PDFTextField.setText
PDFTextField.getText
PDFTextField.setMaxLength
PDFTextField.getMaxLength
PDFTextField.removeMaxLength
pdf-lib
สามารถ แยกเนื้อหาของช่องข้อความได้ (ดู PDFTextField.getText
) แต่ ไม่สามารถ แยกข้อความธรรมดาบนหน้านอกช่องแบบฟอร์มได้ นี่เป็นคุณสมบัติที่ยากต่อการนำไปใช้ แต่อยู่ภายในขอบเขตของไลบรารีนี้และอาจจะเพิ่มลงใน pdf-lib
ในอนาคต ดู #93, #137, #177, #329 และ #380pdf-lib
สามารถ ลบและแก้ไขเนื้อหาของฟิลด์ข้อความ (ดู PDFTextField.setText
) แต่ ไม่มี API สำหรับการลบหรือแก้ไขข้อความบนเพจนอกฟิลด์แบบฟอร์ม นี่เป็นฟีเจอร์ที่นำไปใช้ได้ยากเช่นกัน แต่อยู่ภายในขอบเขตของ pdf-lib
และอาจจะเพิ่มเข้ามาในอนาคต ดู #93, #137, #177, #329 และ #380pdf-lib
ไม่ รองรับการใช้ HTML หรือ CSS เมื่อเพิ่มเนื้อหาลงใน PDF ในทำนองเดียวกัน pdf-lib
ไม่สามารถ ฝังเนื้อหา HTML/CSS ลงใน PDF ได้ แม้ว่าคุณลักษณะดังกล่าวจะสะดวกเพียงใด แต่ก็เป็นเรื่องยากมากที่จะนำไปใช้และอยู่นอกเหนือขอบเขตของไลบรารีนี้ หากความสามารถนี้คือสิ่งที่คุณต้องการ ให้พิจารณาใช้ Puppeteer การสนทนาเป็นสถานที่ที่ดีที่สุดในการพูดคุยกับเรา ถามคำถาม และเรียนรู้เพิ่มเติมเกี่ยวกับ pdf-lib!
ดูเพิ่มเติมที่ MAINTAINERSHIP.md#communication และ MAINTAINERSHIP.md#discord
ขณะนี้ pdf-lib
ไม่รองรับเอกสารที่เข้ารหัส คุณไม่ควรใช้ pdf-lib
กับเอกสารที่เข้ารหัส อย่างไรก็ตาม นี่เป็นคุณสมบัติที่สามารถเพิ่มลงใน pdf-lib
ได้ โปรดสร้างปัญหาหากคุณพบว่าคุณลักษณะนี้มีประโยชน์!
เมื่อเอกสารที่เข้ารหัสถูกส่งผ่านไปยัง PDFDocument.load(...)
ข้อผิดพลาดจะเกิดขึ้น:
import { PDFDocument , EncryptedPDFError } from 'pdf-lib'
const encryptedPdfBytes = ...
// Assignment fails. Throws an `EncryptedPDFError`.
const pdfDoc = PDFDocument . load ( encryptedPdfBytes )
พฤติกรรมเริ่มต้นนี้มักเป็นสิ่งที่คุณต้องการ ช่วยให้คุณตรวจสอบได้ง่ายว่าเอกสารที่กำหนดได้รับการเข้ารหัสหรือไม่ และป้องกันไม่ให้คุณพยายามแก้ไขเอกสารนั้น อย่างไรก็ตาม หากคุณต้องการโหลดเอกสารจริงๆ คุณสามารถใช้ตัวเลือก { ignoreEncryption: true }
:
import { PDFDocument } from 'pdf-lib'
const encryptedPdfBytes = ...
// Assignment succeeds. Does not throw an error.
const pdfDoc = PDFDocument . load ( encryptedPdfBytes , { ignoreEncryption : true } )
โปรดทราบว่า การใช้ตัวเลือกนี้ไม่ได้ถอดรหัสเอกสาร ซึ่งหมายความว่าการแก้ไขใด ๆ ที่คุณพยายามทำกับ PDFDocument
ที่ส่งคืนอาจล้มเหลวหรือมีผลลัพธ์ที่ไม่คาดคิด
คุณไม่ควรใช้ตัวเลือกนี้ มีไว้เพื่อเหตุผลด้านความเข้ากันได้แบบย้อนหลังเท่านั้น
เรายินดีรับการสนับสนุนจากชุมชนโอเพ่นซอร์ส! หากคุณสนใจที่จะมีส่วนร่วมใน pdf-lib
โปรดดูที่ไฟล์ CONTRIBUTING.md ประกอบด้วยข้อมูลที่จะช่วยคุณในการตั้งค่า pdf-lib
และทำงานบนเครื่องของคุณ (เราพยายามทำให้สิ่งนี้ง่ายและรวดเร็วที่สุด!)
ตรวจสอบ MAINTAINERSHIP.md เพื่อดูรายละเอียดเกี่ยวกับวิธีการดูแลรักษา repo นี้ และวิธีที่เราใช้ปัญหา การประชาสัมพันธ์ และการสนทนา
pdfkit
เป็นไลบรารีการสร้าง PDF สำหรับ Node และ Browser ไลบรารีนี้มีประโยชน์อย่างมากในการอ้างอิงและการพิสูจน์การมีอยู่เมื่อสร้าง pdf-lib
โค้ดของ pdfkit
สำหรับการฝังแบบอักษร การฝัง PNG และการฝัง JPG มีประโยชน์อย่างยิ่งpdf.js
เป็นไลบรารีการเรนเดอร์ PDF สำหรับเบราว์เซอร์ ไลบรารีนี้มีประโยชน์ในการอ้างอิงเมื่อเขียน parser ของ pdf-lib
รหัสบางส่วนสำหรับการถอดรหัสสตรีมถูกย้ายไปยัง TypeScript โดยตรงเพื่อใช้ใน pdf-lib
pdfbox
เป็นไลบรารีการสร้างและแก้ไข PDF ที่เขียนด้วยภาษา Java ไลบรารีนี้เป็นข้อมูลอ้างอิงอันล้ำค่าเมื่อใช้การสร้างแบบฟอร์มและการกรอก API สำหรับ pdf-lib
jspdf
เป็นไลบรารีการสร้าง PDF สำหรับเบราว์เซอร์pdfmake
เป็นไลบรารีการสร้าง PDF สำหรับเบราว์เซอร์hummus
เป็นไลบรารีการสร้างและแก้ไข PDF สำหรับสภาพแวดล้อมโหนด hummus
เป็น Node wrapper รอบๆ ไลบรารี C++ ดังนั้นจึงใช้ไม่ได้ในสภาพแวดล้อม JavaScript หลายอย่าง เช่น Browser หรือ React Nativereact-native-pdf-lib
เป็นไลบรารีการสร้างและแก้ไข PDF สำหรับสภาพแวดล้อม React Native react-native-pdf-lib
เป็น wrapper ของไลบรารี C++ และ Javapdfassembler
เป็นไลบรารีการสร้างและแก้ไข PDF สำหรับ Node และเบราว์เซอร์ ต้องใช้ความรู้บางอย่างเกี่ยวกับโครงสร้างเชิงตรรกะของเอกสาร PDF เพื่อใช้งาน repo นี้เคยมีไฟล์ชื่อ pdf_specification.pdf
อยู่ในไดเร็กทอรีราก นี่เป็นสำเนาของข้อกำหนด PDF 1.7 ซึ่ง Adobe เปิดให้ใช้งานอย่างเสรี ในวันที่ 30/8/2021 เราได้รับการร้องเรียน DMCA ที่กำหนดให้เราต้องลบไฟล์ออกจากที่เก็บนี้ การลบไฟล์ออกโดยอาศัยการคอมมิตใหม่เป็น master
นั้นไม่เพียงพอต่อการตอบสนองต่อการร้องเรียน ไฟล์จำเป็นต้องถูกลบออกจากประวัติคอมไพล์ของ repo โดยสมบูรณ์ น่าเสียดายที่ไฟล์ถูกเพิ่มเข้ามาเมื่อสองปีที่แล้ว ซึ่งหมายความว่าเราต้องเขียนประวัติ git ของ repo ใหม่และบังคับ push ไปที่ master
?
เราลบไฟล์และเขียนประวัติของ repo ใหม่โดยใช้ BFG Repo-Cleaner ตามที่อธิบายไว้ที่นี่ เพื่อความโปร่งใสทั้งหมด นี่คือคำสั่งที่เราเรียกใช้:
$ git clone [email protected]:Hopding/pdf-lib.git
$ cd pdf-lib
$ rm pdf_specification.pdf
$ git commit -am 'Remove pdf_specification.pdf'
$ bfg --delete-files pdf_specification.pdf
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
$ git push --force
หากคุณเป็นผู้ใช้ pdf-lib
คุณไม่ควรสนใจ! เพียงใช้ pdf-lib
ต่อไปเหมือนปกติ? -
หากคุณเป็นนักพัฒนา pdf-lib
(หมายความว่าคุณได้แยก pdf-lib
และ/หรือมี PR แบบเปิด) สิ่งนี้จะส่งผลต่อคุณ หากคุณแยกหรือโคลน Repo ก่อนวันที่ 30/08/2021 ประวัติ Git ของ Fork ของคุณจะไม่ซิงค์กับสาขา master
ของ Repo นี้ น่าเสียดายที่นี่อาจทำให้คุณต้องปวดหัว ขอโทษ! เราไม่ต้องการเขียนประวัติศาสตร์ใหม่ แต่ก็ไม่มีทางเลือกอื่นจริงๆ
สิ่งสำคัญที่ควรทราบคือ ซอร์สโค้ด ของ pdf-lib ไม่มีการเปลี่ยนแปลงเลย มันเหมือนเดิมทุกประการก่อนที่ประวัติคอมไพล์จะเขียนใหม่ repo ยังคงมีจำนวนคอมมิตเท่ากันทุกประการ (และแม้แต่เนื้อหาคอมมิตเดียวกัน ยกเว้นคอมมิตที่เพิ่ม pdf_specification.pdf
) สิ่งที่เปลี่ยนแปลงไปคือ SHA ของการกระทำเหล่านั้น
วิธีที่ง่ายที่สุดในการจัดการกับข้อเท็จจริงนี้คือ:
ดูคำตอบ StackOverflow นี้สำหรับคำอธิบายเชิงลึกที่ยอดเยี่ยมเกี่ยวกับสิ่งที่เขียนประวัติ git ใหม่
เอ็มไอที