En savoir plus sur pdf-lib.js.org
pdf-lib
a été créé pour remédier au manque de support robuste de l'écosystème JavaScript pour la manipulation de PDF (en particulier pour la modification de PDF).
Deux des caractéristiques distinctives de pdf-lib
sont :
Il existe d'autres bonnes bibliothèques PDF JavaScript open source disponibles. Cependant, la plupart d’entre eux ne peuvent que créer des documents, ils ne peuvent pas modifier ceux qui existent déjà. Et beaucoup d’entre eux ne travaillent que dans des environnements particuliers.
Cet exemple produit ce PDF.
Essayez la démo 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>
Cet exemple produit ce PDF (lorsque ce PDF est utilisé pour la variable existingPdfBytes
).
Essayez la démo 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>
Cet exemple produit ce PDF.
Essayez la démo JSFiddle
Voir aussi Créer et remplir des formulaires
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>
Cet exemple produit ce PDF (lorsque ce PDF est utilisé pour la variable formPdfBytes
, cette image est utilisée pour la variable marioImageBytes
et cette image est utilisée pour la variable emblemImageBytes
).
Essayez la démo JSFiddle
Voir aussi Créer et remplir des formulaires
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>
Cet exemple produit ce PDF (lorsque ce PDF est utilisé pour la variable formPdfBytes
).
Essayez la démo 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>
Cet exemple produit ce PDF (lorsque ce PDF est utilisé pour la variable firstDonorPdfBytes
et que ce PDF est utilisé pour la variable secondDonorPdfBytes
).
Essayez la démo 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>
Cet exemple produit ce PDF (lorsque cette image est utilisée pour la variable jpgImageBytes
et cette image est utilisée pour la variable pngImageBytes
).
Essayez la démo 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>
Cet exemple produit ce PDF (lorsque ce PDF est utilisé pour la variable americanFlagPdfBytes
et que ce PDF est utilisé pour la variable usConstitutionPdfBytes
).
Essayez la démo 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
s'appuie sur un module sœur pour prendre en charge l'intégration de polices personnalisées : @pdf-lib/fontkit
. Vous devez ajouter le module @pdf-lib/fontkit
à votre projet et l'enregistrer à l'aide de pdfDoc.registerFontkit(...)
avant d'intégrer des polices personnalisées.
Voir ci-dessous pour les instructions d'installation détaillées sur l'installation
@pdf-lib/fontkit
en tant que module UMD ou NPM.
Cet exemple produit ce PDF (lorsque cette police est utilisée pour la variable fontBytes
).
Essayez la démo 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>
Cet exemple produit ce PDF (lorsque cette image est utilisée pour la variable jpgAttachmentBytes
et que ce PDF est utilisé pour la variable pdfAttachmentBytes
).
Essayez la démo 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>
Cet exemple produit ce PDF .
Essayez la démo 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>
Essayez la démo 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 ( ) )
Ce script génère ce qui suit ( lorsque ce PDF est utilisé pour la variable 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 ( ) )
Ce script génère ce qui suit ( lorsque ce PDF est utilisé pour la variable 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
Cet exemple produit ce PDF .
Essayez la démo 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
prend entièrement en charge le nouveau runtime Deno ! Tous les exemples d'utilisation fonctionnent dans Deno. La seule chose que vous devez faire est de modifier les importations pour pdf-lib
et @pdf-lib/fontkit
pour utiliser le CDN Skypack, car Deno exige que tous les modules soient référencés via des URL.
Voir aussi Comment créer et modifier des fichiers PDF dans Deno avec pdf-lib
Vous trouverez ci-dessous l'exemple de création de document modifié pour 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 ) ;
Si vous enregistrez ce script sous create-document.ts
, vous pouvez l'exécuter en utilisant Deno avec la commande suivante :
deno run --allow-write create-document.ts
Le fichier out.pdf
résultant ressemblera à ce PDF.
Voici un exemple légèrement plus compliqué montrant comment intégrer une police et mesurer du texte dans 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 ) ;
Si vous enregistrez ce script sous custom-font.ts
, vous pouvez l'exécuter avec la commande suivante :
deno run --allow-write --allow-net custom-font.ts
Le fichier out.pdf
résultant ressemblera à ce PDF.
Les exemples d'utilisation fournissent un code bref et précis, démontrant les différentes fonctionnalités de pdf-lib
. Vous pouvez trouver des exemples de travail complets dans le répertoire apps/
. Ces applications sont utilisées pour effectuer des tests manuels de pdf-lib
avant chaque version (en plus des tests automatisés).
Il existe actuellement quatre applications :
node
- contient des tests pour pdf-lib
dans les environnements Node. Ces tests constituent une référence pratique lorsque vous essayez de sauvegarder/charger des PDF, des polices ou des images avec pdf-lib
à partir du système de fichiers. Ils vous permettent également d'ouvrir rapidement vos PDF dans différents visualiseurs (Acrobat, Preview, Foxit, Chrome, Firefox, etc...) pour garantir la compatibilité.web
- contient des tests pour pdf-lib
dans les environnements de navigateur. Ces tests constituent une référence pratique lorsque vous essayez d'enregistrer/charger des PDF, des polices ou des images avec pdf-lib
dans un environnement de navigateur.rn
- contient des tests pour pdf-lib
dans les environnements React Native. Ces tests constituent une référence pratique lorsque vous essayez d'enregistrer/charger des PDF, des polices ou des images avec pdf-lib
dans un environnement React Native.deno
- contient des tests pour pdf-lib
dans les environnements Deno. Ces tests constituent une référence pratique lorsque vous essayez de sauvegarder/charger des PDF, des polices ou des images avec pdf-lib
à partir du système de fichiers. Pour installer la dernière version stable :
# With npm
npm install --save pdf-lib
# With yarn
yarn add pdf-lib
Cela suppose que vous utilisez npm ou Yarn comme gestionnaire de paquets.
Vous pouvez également télécharger pdf-lib
en tant que module UMD depuis unpkg ou jsDelivr. Les versions UMD ont été compilées vers ES5, elles devraient donc fonctionner dans n'importe quel navigateur moderne. Les versions UMD sont utiles si vous n'utilisez pas de gestionnaire de packages ou de bundler de modules. Par exemple, vous pouvez les utiliser directement dans la balise <script>
d'une page HTML.
Les versions suivantes sont disponibles :
REMARQUE : si vous utilisez les scripts CDN en production, vous devez inclure un numéro de version spécifique dans l'URL, par exemple :
- https://unpkg.com/[email protected]/dist/pdf-lib.min.js
- https://cdn.jsdelivr.net/npm/[email protected]/dist/pdf-lib.min.js
Lorsque vous utilisez une version UMD, vous aurez accès à une variable globale window.PDFLib
. Cette variable contient toutes les classes et fonctions exportées par pdf-lib
. Par exemple:
// NPM module
import { PDFDocument , rgb } from 'pdf-lib' ;
// UMD module
var PDFDocument = PDFLib . PDFDocument ;
var rgb = PDFLib . rgb ;
pdf-lib
s'appuie sur un module sœur pour prendre en charge l'intégration de polices personnalisées : @pdf-lib/fontkit
. Vous devez ajouter le module @pdf-lib/fontkit
à votre projet et l'enregistrer à l'aide de pdfDoc.registerFontkit(...)
avant d'intégrer des polices personnalisées (voir l'exemple d'intégration de polices). Ce module n'est pas inclus par défaut car tous les utilisateurs n'en ont pas besoin et il augmente la taille du bundle.
L'installation de ce module est simple. Tout comme pdf-lib
lui-même, @pdf-lib/fontkit
peut être installé avec npm
/ yarn
ou en tant que module UMD.
# With npm
npm install --save @pdf-lib/fontkit
# With yarn
yarn add @pdf-lib/fontkit
Pour enregistrer l'instance fontkit
:
import { PDFDocument } from 'pdf-lib'
import fontkit from '@pdf-lib/fontkit'
const pdfDoc = await PDFDocument . create ( )
pdfDoc . registerFontkit ( fontkit )
Les versions suivantes sont disponibles :
REMARQUE : si vous utilisez les scripts CDN en production, vous devez inclure un numéro de version spécifique dans l'URL, par exemple :
- 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
Lorsque vous utilisez une version UMD, vous aurez accès à une variable globale window.fontkit
. Pour enregistrer l'instance fontkit
:
var pdfDoc = await PDFLib . PDFDocument . create ( )
pdfDoc . registerFontkit ( fontkit )
La documentation de l'API est disponible sur le site du projet à l'adresse https://pdf-lib.js.org/docs/api/.
Le dépôt du site du projet (et les fichiers de documentation générés) se trouve ici : https://github.com/Hopding/pdf-lib-docs.
Lorsque vous travaillez avec des PDF, vous rencontrerez fréquemment les termes « encodage de caractères » et « police ». Si vous avez de l’expérience dans le développement Web, vous vous demandez peut-être pourquoi ceux-ci sont si répandus. Ne s’agit-il pas simplement de détails ennuyeux dont vous ne devriez pas vous soucier ? Les bibliothèques et les lecteurs PDF ne devraient-ils pas être capables de gérer tout cela à votre place, comme le peuvent les navigateurs Web ? Malheureusement, ce n'est pas le cas. La nature du format de fichier PDF fait qu'il est très difficile d'éviter de penser aux encodages de caractères et aux polices lorsque vous travaillez avec des PDF.
pdf-lib
fait de son mieux pour simplifier les choses pour vous. Mais il ne peut pas faire de magie. Cela signifie que vous devez être conscient des éléments suivants :
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
. Lorsque vous intégrez votre propre police, vous pouvez utiliser tous les caractères Unicode qu'elle prend en charge. Cette fonctionnalité vous libère des limitations imposées par les polices standards. La plupart des fichiers PDF utilisent des polices intégrées. Vous pouvez intégrer et utiliser une police personnalisée comme ceci (voir aussi) : 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 ,
} )
Notez que des erreurs d'encodage seront générées si vous essayez d'utiliser un caractère avec une police qui ne le prend pas en charge. Par exemple, Ω
ne figure pas dans le jeu de caractères WinAnsi. Donc, essayer de le dessiner sur une page avec la police Helvetica standard générera l'erreur suivante :
Error: WinAnsi cannot encode "Ω" (0x03a9)
at Encoding.encodeUnicodeCodePoint
L'intégration d'une police dans un document PDF augmente généralement la taille du fichier. Vous pouvez réduire l'augmentation de la taille d'un fichier en sous-définissant la police afin que seuls les caractères nécessaires soient incorporés. Vous pouvez créer un sous-ensemble d'une police en définissant l'option subset
sur true
. Par exemple:
const font = await pdfDoc . embedFont ( fontBytes , { subset : true } ) ;
Notez que les sous-ensembles ne fonctionnent pas pour toutes les polices. Voir #207 (commentaire) pour plus de détails.
pdf-lib
peut créer, remplir et lire les champs de formulaires PDF. Les types de champs suivants sont pris en charge :
Consultez les exemples d’utilisation de création et de remplissage de formulaires pour des exemples de code. Les tests 1, 14, 15, 16 et 17 dans les exemples complets contiennent un exemple de code fonctionnel pour la création de formulaires et le remplissage dans une variété d'environnements JS différents.
IMPORTANT : La police par défaut utilisée pour afficher le texte dans les boutons, les listes déroulantes, les listes d'options et les champs de texte est la police Helvetica standard. Cette police ne prend en charge que les caractères de l'alphabet latin (voir Polices et Unicode pour plus de détails). Cela signifie que si l'un de ces types de champs est créé ou modifié pour contenir du texte en dehors de l'alphabet latin (comme c'est souvent le cas), vous devrez intégrer et utiliser une police personnalisée pour mettre à jour l'apparence des champs. Sinon, une erreur sera générée (probablement lorsque vous enregistrez le PDFDocument
).
Vous pouvez utiliser une police intégrée lorsque vous remplissez les champs du formulaire comme suit :
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 ( ) ;
Les champs de formulaire existants sont accessibles avec les méthodes suivantes de PDFForm
:
PDFForm.getButton
PDFForm.getCheckBox
PDFForm.getDropdown
PDFForm.getOptionList
PDFForm.getRadioGroup
PDFForm.getTextField
De nouveaux champs de formulaire peuvent être créés avec les méthodes suivantes de PDFForm
:
PDFForm.createButton
PDFForm.createCheckBox
PDFForm.createDropdown
PDFForm.createOptionList
PDFForm.createRadioGroup
PDFForm.createTextField
Vous trouverez ci-dessous quelques-unes des méthodes les plus couramment utilisées pour lire et remplir les sous-classes susmentionnées de 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
peut extraire le contenu des champs de texte (voir PDFTextField.getText
), mais il ne peut pas extraire le texte brut d'une page en dehors d'un champ de formulaire. Il s'agit d'une fonctionnalité difficile à implémenter, mais elle entre dans le cadre de cette bibliothèque et pourrait être ajoutée à pdf-lib
à l'avenir. Voir #93, #137, #177, #329 et #380.pdf-lib
peut supprimer et modifier le contenu des champs de texte (voir PDFTextField.setText
), mais il ne fournit pas d'API pour supprimer ou modifier le texte d'une page en dehors d'un champ de formulaire. Il s'agit également d'une fonctionnalité difficile à mettre en œuvre, mais elle entre dans le cadre de pdf-lib
et pourrait être ajoutée à l'avenir. Voir #93, #137, #177, #329 et #380.pdf-lib
ne prend pas en charge l'utilisation de HTML ou CSS lors de l'ajout de contenu à un PDF. De même, pdf-lib
ne peut pas intégrer de contenu HTML/CSS dans des PDF. Aussi pratique qu'une telle fonctionnalité puisse être, elle serait extrêmement difficile à mettre en œuvre et dépasse largement la portée de cette bibliothèque. Si vous avez besoin de cette fonctionnalité, envisagez d’utiliser Puppeteer. Les discussions sont le meilleur endroit pour discuter avec nous, poser des questions et en savoir plus sur pdf-lib !
Voir également MAINTAINERSHIP.md#communication et MAINTAINERSHIP.md#discord.
pdf-lib
ne prend actuellement pas en charge les documents cryptés. Vous ne devez pas utiliser pdf-lib
avec des documents cryptés. Cependant, c'est une fonctionnalité qui pourrait être ajoutée à pdf-lib
. Veuillez créer un problème si vous trouvez cette fonctionnalité utile !
Lorsqu'un document crypté est transmis à PDFDocument.load(...)
, une erreur sera générée :
import { PDFDocument , EncryptedPDFError } from 'pdf-lib'
const encryptedPdfBytes = ...
// Assignment fails. Throws an `EncryptedPDFError`.
const pdfDoc = PDFDocument . load ( encryptedPdfBytes )
Ce comportement par défaut correspond généralement à ce que vous souhaitez. Il vous permet de détecter facilement si un document donné est crypté et vous empêche d'essayer de le modifier. Cependant, si vous souhaitez vraiment charger le document, vous pouvez utiliser l'option { ignoreEncryption: true }
:
import { PDFDocument } from 'pdf-lib'
const encryptedPdfBytes = ...
// Assignment succeeds. Does not throw an error.
const pdfDoc = PDFDocument . load ( encryptedPdfBytes , { ignoreEncryption : true } )
Notez que l'utilisation de cette option ne décrypte pas le document . Cela signifie que toutes les modifications que vous tentez d'apporter au PDFDocument
renvoyé peuvent échouer ou avoir des résultats inattendus.
Vous ne devriez pas utiliser cette option. Il n'existe que pour des raisons de compatibilité ascendante.
Nous apprécions les contributions de la communauté open source ! Si vous souhaitez contribuer à pdf-lib
, veuillez jeter un œil au fichier CONTRIBUTING.md. Il contient des informations pour vous aider à configurer et à exécuter pdf-lib
sur votre ordinateur. (Nous essayons de rendre cela aussi simple et rapide que possible ! )
Consultez MAINTAINERSHIP.md pour plus de détails sur la façon dont ce dépôt est maintenu et comment nous utilisons les problèmes, les relations publiques et les discussions.
pdfkit
est une bibliothèque de génération de PDF pour Node et le navigateur. Cette bibliothèque a été extrêmement utile comme référence et preuve d'existence lors de la création pdf-lib
. Le code de pdfkit
pour l'intégration de polices, l'intégration PNG et l'intégration JPG a été particulièrement utile.pdf.js
est une bibliothèque de rendu PDF pour le navigateur. Cette bibliothèque a été utile comme référence lors de l'écriture de l'analyseur pdf-lib
. Une partie du code pour le décodage de flux a été portée directement sur TypeScript pour être utilisée dans pdf-lib
.pdfbox
est une bibliothèque de génération et de modification de PDF écrite en Java. Cette bibliothèque a été une référence inestimable lors de la mise en œuvre d'API de création de formulaires et de remplissage pour pdf-lib
.jspdf
est une bibliothèque de génération de PDF pour le navigateur.pdfmake
est une bibliothèque de génération de PDF pour le navigateur.hummus
est une bibliothèque de génération et de modification de PDF pour les environnements Node. hummus
est un wrapper Node autour d'une bibliothèque C++, il ne fonctionne donc pas dans de nombreux environnements JavaScript, comme le navigateur ou React Native.react-native-pdf-lib
est une bibliothèque de génération et de modification de PDF pour les environnements React Native. react-native-pdf-lib
est un wrapper autour des bibliothèques C++ et Java.pdfassembler
est une bibliothèque de génération et de modification de PDF pour Node et le navigateur. Son utilisation nécessite certaines connaissances sur la structure logique des documents PDF. Ce dépôt contenait un fichier appelé pdf_specification.pdf
dans le répertoire racine. Il s'agit d'une copie de la spécification PDF 1.7, mise à disposition gratuitement par Adobe. Le 30/08/2021, nous avons reçu une réclamation DMCA nous obligeant à supprimer le fichier de ce dépôt. La simple suppression du fichier via un nouveau commit sur master
était insuffisante pour satisfaire la plainte. Le fichier devait être complètement supprimé de l’historique git du dépôt. Malheureusement, le fichier a été ajouté il y a plus de deux ans, ce qui signifie que nous avons dû réécrire l'historique git du dépôt et forcer push à master
?.
Nous avons supprimé le fichier et réécrit l'historique du dépôt à l'aide de BFG Repo-Cleaner comme indiqué ici. Pour une transparence totale, voici les commandes exactes que nous avons exécutées :
$ 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
Si vous êtes un utilisateur de pdf-lib
, vous ne devriez pas vous en soucier ! Continuez simplement à utiliser pdf-lib
comme d'habitude ? !
Si vous êtes un développeur pdf-lib
(ce qui signifie que vous avez créé pdf-lib
et/ou avez un PR ouvert), cela vous affecte. Si vous avez forké ou cloné le dépôt avant le 30/08/2021, l'historique git de votre fork n'est pas synchronisé avec la branche master
de ce dépôt. Malheureusement, cela sera probablement un casse-tête pour vous. Désolé! Nous ne voulions pas réécrire l’histoire, mais il n’y avait vraiment pas d’alternative.
Il est important de noter que le code source de pdf-lib n'a pas changé du tout. C'est exactement la même chose qu'avant la réécriture de l'historique de Git. Le dépôt a toujours exactement le même nombre de commits (et même le même contenu de commit, à l'exception du commit qui a ajouté pdf_specification.pdf
). Ce qui a changé, ce sont les SHA de ces commits.
La façon la plus simple de gérer ce fait est de :
Consultez cette réponse StackOverflow pour une explication approfondie et approfondie de ce qu'implique une réécriture de l'historique git.
MIT