PDF Maker est une bibliothèque permettant de générer des documents PDF en JavaScript.
Ce projet s'inspire de pdfmake et s'appuie sur pdf-lib et fontkit. Il n'existerait pas sans l'excellent travail et les connaissances approfondies apportées par les auteurs de ces projets.
La fonction makePdf()
crée des données PDF à partir d'une définition de document donnée. Cette définition est un objet simple.
La propriété la plus importante dans la définition est nommée content
. Cette propriété accepte une liste de blocs . Il existe différents types de blocs, tels que les blocs de texte, les blocs d'images, les blocs de disposition en colonnes et en lignes.
const fontData = await readFile ( 'Roboto-Regular.ttf' ) ;
const fontDataItalic = await readFile ( 'Roboto-Italic.ttf' ) ;
const pdfData = await makePdf ( {
// Fonts must be registered (see below)
fonts : {
Roboto : [ { data : fontData } , { data : fontDataItalic , italic : true } ] ,
} ,
// Content as an array of blocks
content : [
// Blocks can contain text and text properties
{ text : 'Lorem ipsum' , fontStyle : 'italic' , textAlign : 'center' , fontSize : 24 } ,
// Text can also be an array of text spans with different properties
{
text : [
'dolor sit amet, consectetur adipiscing elit ' ,
{ text : 'sed do eiusmod' , fontStyle : 'italic' } ,
' tempor, incididunt ut labore et dolore magna aliqua.' ,
] ,
} ,
] ,
} ) ;
await writeFile ( `hello.pdf` , pdfData ) ;
Il y a plus d'exemples dans le dossier examples/.
Toutes les polices sont intégrées au PDF et doivent être enregistrées auprès de la propriété fonts
. Les données de police sont acceptées au format .ttf
ou .otf
, comme ArrayBuffer ou Uint8Array. Chaque famille de polices peut contenir différentes variantes sélectionnées en fonction des propriétés bold
et italic
. La famille de polices enregistrée en premier devient la famille par défaut.
const documentDefinition = {
fonts : {
'DejaVu-Sans' : [
// Different font versions for fontFamily "DejaVu-Sans"
// TTF / OTF font data as ArrayBuffer or Uin8Array
{ data : fontDataDejaVuSansNormal } ,
{ data : fontDataDejaVuSansBold , bold : true } ,
{ data : fontDataDejaVuSansItalic , italic : true } ,
{ data : fontDataDejaVuSansBoldItalic , bold : true , italic : true } ,
] ,
Roboto : [
// Different font versions for fontFamily "Roboto"
{ data : fontDataRobotoNormal } ,
{ data : fontDataRobotoMedium , bold : true } ,
] ,
} ,
content : [
{ text : 'lorem ipsum' , fontFamily : 'Roboto' , fontWeight : 'bold' } , // will use Roboto Medium
{ text : 'dolor sit amet' } , // will use DejaVu-Sans (the font registered first), normal
] ,
} ;
Les images JPG et PNG sont prises en charge. Lorsque la même image est utilisée plusieurs fois, les données de l'image ne sont incluses qu'une seule fois dans le PDF. La taille d'une image peut être limitée à l'aide des propriétés width
et height
.
// An image block
{ image : 'images/logo.png' , width : 200 , height : 100 } ,
Pour disposer les blocs horizontalement, ils peuvent être inclus dans un bloc avec une propriété columns
. Lorsque les colonnes ont une propriété width
, celle-ci est respectée. L'espace restant est réparti uniformément sur toutes les colonnes.
{
columns : [
{ text : 'Column 1' , width : 100 } , // 100 pt wide
{ text : 'Column 2' } , // gets half of the remaining width
{ text : 'Column 3' } , // gets half of the remaining width
] ,
}
Une disposition en lignes peut être utilisée pour regrouper plusieurs lignes en un seul bloc, par exemple pour appliquer des propriétés communes ou pour enfermer des lignes dans une disposition en colonnes environnantes.
{
rows : [
{ text : 'Row 1' } ,
{ text : 'Row 2' } ,
{ text : 'Row 3' } ,
] ,
textAlign : 'right' ,
}
Chaque bloc peut avoir une propriété graphics
qui accepte une liste de formes à dessiner dans ce bloc ou une fonction qui renvoie une liste de formes. La fonction sera appelée avec la largeur et la hauteur du bloc. Cela peut être utilisé pour dessiner des formes qui dépendent de la taille du bloc.
Les formes peuvent être des lignes, des rectangles, des cercles ou des chemins SVG. Dans l'exemple suivant, une propriété graphique est utilisée pour dessiner un arrière-plan jaune derrière le texte et une bordure bleue sur le bord gauche.
{
text : 'Lorem ipsum' ,
graphics : ( { width , height } ) => [
{ type : 'rect' , x : 0 , y : 0 , width , height , fillColor : 'yellow' } ,
{ type : 'line' , x1 : 0 , y1 : 0 , x2 : 0 , y2 : height , lineColor : 'blue' , lineWidth : 2 } ,
] ,
padding : { left : 5 } ,
}
Voir également l'exemple graphique.
La propriété margin
peut être utilisée pour ajouter de l'espace autour des blocs. Il accepte soit une valeur unique (s'applique aux quatre arêtes), soit un objet avec l'une des propriétés top
, right
, bottom
, left
, x
et y
. Les propriétés x
et y
peuvent être utilisées comme raccourcis pour définir simultanément left
et right
ou top
et bottom
. Les valeurs peuvent être données sous forme de nombres (en pt) ou sous forme de chaînes avec une unité. Si une chaîne est donnée, elle doit contenir l'une des unités pt
, in
, mm
ou cm
;
{
margin : { x : 5 , top : 10 } ,
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'dolor sit amet' } ,
] ,
}
Les marges top
et bottom
des blocs adjacents sont réduites en une seule marge dont la taille est la plus grande des deux marges. Les marges des colonnes ne s'effondrent pas.
La propriété padding
peut être utilisée pour ajouter de l'espace entre le contenu et les bords des blocs.
La propriété pageSize
de niveau supérieur peut être utilisée pour définir la taille de la page. Différents formats standard sont pris en charge, tels que A4
, Letter
et Legal
. La valeur par défaut est A4. Une taille de page personnalisée peut être spécifiée sous forme d'objet avec les propriétés width
et height
. Les valeurs peuvent être données sous forme de nombres (en pt) ou sous forme de chaînes avec une unité.
{
pageSize : { width : '20cm' , height : '20cm' }
}
La propriété pageOrientation
peut être utilisée pour définir l'orientation de la page. La valeur peut être portrait
ou landscape
. La valeur par défaut est portrait.
{
pageSize : 'A5' ,
pageOrientation : 'landscape' ,
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'dolor sit amet' } ,
] ,
}
Les en-têtes et pieds de page qui se répètent sur chaque page peuvent être définis à l’aide des propriétés facultatives header
et footer
page. Les deux acceptent soit un seul bloc, soit une fonction qui renvoie un bloc. La fonction sera appelée avec le numéro de page et le nombre total de pages. Le numéro de page commence à 1.
{
footer : ( { pageNumber , pageCount } ) => ( {
text : `Page ${ pageNumber } of ${ pageCount } ` ,
textAlign : 'right' ,
margin : { x : '20mm' , bottom : '1cm' } ,
} ) ,
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'dolor sit amet' } ,
] ,
}
Les sauts de page sont inclus automatiquement. Lorsqu'un bloc ne tient pas sur la page actuelle, une nouvelle page est ajoutée au document. Pour insérer un saut de page avant ou après un bloc, définissez la propriété breakBefore
ou breakAfter
d'un bloc sur always
. Pour éviter un saut de page, définissez cette propriété sur avoid
.
Les sauts de page sont également automatiquement insérés entre les lignes d'un bloc de texte. Pour empêcher un saut de page dans un bloc de texte, définissez la propriété breakInside
sur avoid
.
{
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'This text will go on a new page' , breakBefore : 'always' } ,
] ,
}
Bien qu'il n'y ait pas encore de documentation générée, vous pouvez vous référer au dossier api pour une spécification de toutes les propriétés prises en charge dans une définition de document.
Consultez également les exemples dans le dossier examples/.
MIT