PDF Maker é uma biblioteca para geração de documentos PDF em JavaScript.
Este projeto é inspirado no pdfmake e baseia-se no pdf-lib e no fontkit. Não existiria sem o excelente trabalho e o profundo conhecimento aportado pelos autores desses projetos.
A função makePdf()
cria dados PDF a partir de uma determinada definição de documento . Esta definição é um objeto simples.
A propriedade mais importante na definição é denominada content
. Esta propriedade aceita uma lista de blocos . Existem diferentes tipos de blocos, como blocos de texto, blocos de imagem, blocos de layout de colunas e linhas.
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 ) ;
Existem mais exemplos na pasta samples/.
Todas as fontes estão incorporadas no PDF e devem ser registradas na propriedade fonts
. Os dados de fonte são aceitos no formato .ttf
ou .otf
, como ArrayBuffer ou Uint8Array. Cada família de fontes pode conter diferentes variantes que são selecionadas com base nas propriedades bold
e italic
. A família de fontes registrada primeiro se torna a padrão.
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
] ,
} ;
Imagens JPG e PNG são suportadas. Quando a mesma imagem é usada mais de uma vez, os dados da imagem são incluídos apenas uma vez no PDF. O tamanho de uma imagem pode ser limitado usando as propriedades width
e height
.
// An image block
{ image : 'images/logo.png' , width : 200 , height : 100 } ,
Para organizar os blocos horizontalmente, eles podem ser incluídos em um bloco com a propriedade columns
. Quando as colunas possuem uma propriedade width
, ela é respeitada. O ID do espaço restante é distribuído uniformemente em todas as colunas.
{
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
] ,
}
Um layout de linha pode ser usado para agrupar múltiplas linhas em um único bloco, por exemplo, para aplicar propriedades comuns ou para incluir linhas em um layout de colunas adjacentes.
{
rows : [
{ text : 'Row 1' } ,
{ text : 'Row 2' } ,
{ text : 'Row 3' } ,
] ,
textAlign : 'right' ,
}
Cada bloco pode ter uma propriedade graphics
que aceita uma lista de formas para desenhar naquele bloco ou uma função que retorna uma lista de formas. A função será chamada com a largura e altura do bloco. Isto pode ser usado para desenhar formas que dependem do tamanho do bloco.
As formas podem ser linhas, retângulos, círculos ou caminhos SVG. No exemplo a seguir, uma propriedade gráfica é usada para desenhar um fundo amarelo atrás do texto e uma borda azul na borda esquerda.
{
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 } ,
}
Veja também o exemplo gráfico.
A propriedade margin
pode ser usada para adicionar espaço ao redor dos blocos. Ele aceita um único valor (aplica-se a todas as quatro arestas) e um objeto com qualquer uma das propriedades top
, right
, bottom
, left
, x
e y
. As y
x
ser usadas como abreviações para definir left
e right
ou top
e bottom
ao mesmo tempo. Os valores podem ser fornecidos como números (em pt) ou como strings com uma unidade. Se uma string for fornecida, ela deverá conter uma das unidades pt
, in
, mm
ou cm
;
{
margin : { x : 5 , top : 10 } ,
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'dolor sit amet' } ,
] ,
}
As margens top
e bottom
dos blocos adjacentes são recolhidas em uma única margem cujo tamanho é o máximo das duas margens. As margens da coluna não entram em colapso.
A propriedade padding
pode ser usada para adicionar espaço entre o conteúdo e as bordas dos blocos.
A propriedade pageSize
de nível superior pode ser usada para definir o tamanho da página. Vários tamanhos padrão são suportados, como A4
, Letter
e Legal
. O padrão é A4. Um tamanho de página personalizado pode ser especificado como um objeto com as propriedades width
e height
. Os valores podem ser fornecidos como números (em pt) ou como strings com uma unidade.
{
pageSize : { width : '20cm' , height : '20cm' }
}
A propriedade pageOrientation
pode ser usada para definir a orientação da página. O valor pode ser portrait
ou landscape
. O padrão é retrato.
{
pageSize : 'A5' ,
pageOrientation : 'landscape' ,
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'dolor sit amet' } ,
] ,
}
Cabeçalhos e rodapés repetidos em cada página podem ser definidos usando as propriedades opcionais header
e footer
. Ambos aceitam um único bloco ou uma função que retorna um bloco. A função será chamada com o número da página e o número total de páginas. O número da página começa em 1.
{
footer : ( { pageNumber , pageCount } ) => ( {
text : `Page ${ pageNumber } of ${ pageCount } ` ,
textAlign : 'right' ,
margin : { x : '20mm' , bottom : '1cm' } ,
} ) ,
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'dolor sit amet' } ,
] ,
}
As quebras de página são incluídas automaticamente. Quando um bloco não cabe na página atual, uma nova página é adicionada ao documento. Para inserir uma quebra de página antes ou depois de um bloco, defina a propriedade breakBefore
ou breakAfter
de um bloco como always
. Para evitar uma quebra de página, defina esta propriedade como avoid
.
As quebras de página também são inseridas automaticamente entre as linhas de um bloco de texto. Para evitar uma quebra de página em um bloco de texto, defina a propriedade breakInside
como avoid
.
{
content : [
{ text : 'Lorem ipsum' } ,
{ text : 'This text will go on a new page' , breakBefore : 'always' } ,
] ,
}
Embora ainda não haja documentação gerada, você pode consultar a pasta api para obter uma especificação de todas as propriedades suportadas em uma definição de documento.
Confira também os exemplos na pasta samples/.
MIT