Introducci贸n
Contenido
El formato PDF es uno de los formatos de documentos m谩s comunes para transferir informaci贸n. En aplicaciones web din谩micas, es posible que necesite exportar datos a un documento y PDF suele ser una opci贸n popular. En este art铆culo, discutiremos c贸mo generar archivos PDF en NodeJS usando el paquete NPM pdfkit
.
PDFKit es una biblioteca de generaci贸n de PDF de JavaScript para Node.js que proporciona una manera f谩cil de crear documentos PDF imprimibles de varias p谩ginas.
Introducci贸n a PDFKit
Creemos un directorio de proyecto, cd
en 茅l e inicializar el proyecto Node con la configuraci贸n predeterminada:
$ mkdir pdfkit-project
$ cd pdfkit-project
$ npm init -y
Entonces vamos install pdfkit
:
$ npm install pdfkit
Para usar el m贸dulo en el proyecto, lo importaremos a trav茅s de require()
:
const PDFDocument = require('pdfkit');
Crear un documento PDF usando PDFKit
Para crear un documento PDF, necesitaremos importar el fs
(sistema de archivos) m贸dulo tambi茅n. Canalizaremos el contenido de nuestro archivo PDF en un fs
flujo de escritura para guardarlo. Echemos un vistazo a c贸mo hacer eso:
const PDFDocument = require('pdfkit');
const fs = require('fs');
let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('SampleDocument.pdf'));
pdfDoc.text("My Sample PDF Document");
pdfDoc.end();
Primero, importamos los m贸dulos requeridos, luego de lo cual, instanciamos el PDFDocument
. Esta instancia es una secuencia legible. Estaremos canalizando esa secuencia a una secuencia de escritura para guardar el archivo.
Si no est谩 familiarizado con el funcionamiento de las transmisiones, consulte nuestra Introducci贸n a las transmisiones de Node.js.
Estamos usando el pipe()
funci贸n para hacer esto y guardar el resultado SampleDocument.pdf
en nuestro directorio ra铆z. Una vez creado, podemos agregarle contenido, a trav茅s del text
funci贸n. Por supuesto que queremos end()
la corriente al final.
Cuando ejecutamos el c贸digo, un archivo PDF llamado SampleDocument.pdf
se crea en la carpeta ra铆z de nuestro proyecto:
$ node index.js
Nota: Antes de intentar sobrescribir un archivo PDF existente, debe ser gratuito. Es decir, todas las Windows con ese archivo PDF deben cerrarse o el programa arrojar谩 un error.
Formateo de texto en archivo PDF
Por supuesto, pdfkit
nos permite hacer mucho m谩s que agregar texto sin formato a un documento. Echemos un vistazo a algunas de las caracter铆sticas que ofrece.
Colocaci贸n de texto
Por defecto, el pdfkit
El m贸dulo realiza un seguimiento de d贸nde se debe agregar el texto al documento, esencialmente imprime cada llamada al text()
funci贸n en una nueva l铆nea.
Puede cambiar d贸nde se imprime el texto dentro de la p谩gina actual, agregando las coordenadas xey de la ubicaci贸n donde desea que el texto se coloque como argumentos a la text()
funci贸n.
Por ejemplo:
pdfDoc.text("Text positioned at (200,200)", 200, 200);
Esto es 煤til porque le permite ajustar la posici贸n del texto, especialmente porque los documentos PDF tienen un aspecto universal independientemente de la m谩quina / sistema operativo en el que est茅n abiertos. Esto tambi茅n le permitir铆a, por ejemplo, imprimir texto sobre otro texto:
const PDFDocument = require('pdfkit');
const fs = require('fs');
var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('SampleDocument.pdf'));
pdfDoc.text("From Mon-Sat we will have a 10% discount on selected items!", 150, 150);
pdfDoc
.fillColor('red')
.fontSize(17)
.text("20%", 305, 150);
pdfDoc.end();
Ejecutar este c贸digo nos dar铆a:
Ajuste y alineaci贸n de texto
los pdfkit
m贸dulo envuelve autom谩ticamente las l铆neas para que quepan entre los m谩rgenes, o en el width
proporcionado (al escribir texto en columnas). En otras palabras, el lineBreak
la opci贸n es true
por defecto. Puedes cambiarlo a false
al llamar al text()
funci贸n:
pdfDoc.text("very long text ".repeat(20), { lineBreak : false });
Las nuevas p谩ginas tambi茅n se agregan autom谩ticamente seg煤n sea necesario, es decir, tan pronto como el contenido que desea agregar no encaja en la p谩gina actual en su totalidad. Sin embargo, tambi茅n puede pasar a la p谩gina siguiente antes de completar la anterior simplemente llamando a:
pdfDoc.addPage();
En cuanto a la alineaci贸n, pdfkit
nos proporciona las opciones habituales – left
(defecto), right
, center
y justify
. Tenga en cuenta que establecer una alineaci贸n espec铆fica con lineBreak
ajustado a false
no funcionar谩, incluso si el texto cabe en una l铆nea.
Tal como lineBreak
, la align
El par谩metro se establece pasando un objeto que contiene pares clave-valor al text()
funci贸n. Veamos algunos ejemplos de alineaci贸n:
const PDFDocument = require('pdfkit');
const fs = require('fs');
var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('text_alignment.pdf'));
pdfDoc.text("This text is left aligned", { align: 'left'})
pdfDoc.text("This text is at the center", { align: 'center'})
pdfDoc.text("This text is right aligned", { align: 'right'})
pdfDoc.text("This text needs to be slightly longer so that we can see that justification actually works as intended", { align: 'justify'})
pdfDoc.end();
Ejecutar el c贸digo anterior nos dar铆a un PDF con este aspecto:
Estilo de texto
los pdfkit
El m贸dulo tambi茅n proporciona opciones que se pueden utilizar para aplicar estilo al texto en sus documentos PDF. Echaremos un vistazo a algunas de las opciones de estilo m谩s importantes, puede encontrar la lista completa de opciones en el Gu铆a PDF.
Podemos pasar diferentes opciones como pares clave-valor al text()
funci贸n, y tambi茅n encadenar varias otras funciones antes de llamar text()
en absoluto.
Una cosa muy importante a tener en cuenta es que las funciones encadenadas, como fillColor()
(y despu茅s font()
, fontSize()
, etc.) afectar谩 a todo el texto despu茅s de esa llamada:
const PDFDocument = require('pdfkit');
const fs = require('fs');
var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('text_styling.pdf'));
pdfDoc
.fillColor('blue')
.text("This is a link", { link: 'https://pdfkit.org/docs/guide.pdf', underline: true });
pdfDoc
.fillColor('black')
.text("This text is underlined", { underline: true });
pdfDoc.text("This text is italicized", { oblique: true });
pdfDoc.text("This text is striked-through", { strike: true });
pdfDoc.end();
La ejecuci贸n de este c贸digo generar谩 un archivo PDF con el siguiente contenido:
Cambiar estilos en el medio de un p谩rrafo es un poco m谩s complicado, ya que encadenar m煤ltiples text()
functions agrega una nueva l铆nea despu茅s de cada una de forma predeterminada. Podemos evitar esto configurando el lineBreak
opci贸n de la primera text()
llamar a false
:
const PDFDocument = require('pdfkit');
const fs = require('fs');
var pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('text_styling2.pdf'));
pdfDoc
.fillColor('blue')
.text("This text is blue and italicized", {oblique : true, lineBreak : false})
.fillColor('red')
.text(" This text is red");
pdfDoc.end();
Lo que nos dar铆a el resultado deseado:
Crear listas
Para agregar una lista de elementos en su documento PDF, el PDFDocument
instancia tiene un list()
funci贸n que toma una matriz de elementos de cadena (o matrices anidadas de cadenas) y las muestra como una lista de vi帽etas:
const PDFDocument = require('pdfkit');
const fs = require('fs');
let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('lists.pdf'));
let myArrayOfItems = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];
pdfDoc.list(myArrayOfItems);
// Move down a bit to provide space between lists
pdfDoc.moveDown(0.5);
let innerList = ['Nested Item 1', 'Nested Item 2'];
let nestedArrayOfItems = ['Example of a nested list', innerList];
pdfDoc.list(nestedArrayOfItems);
pdfDoc.end();
Lo que nos da:
Fuentes
PDFKit viene con 14 fuentes est谩ndar que se pueden usar en documentos PDF. Cualquiera de estas fuentes se puede pasar al font()
funci贸n de la PDFDocument
clase, y encadenado con text()
:
pdfDoc.font('Times-Roman').text('A text in Times Roman')
Tambi茅n puede agregar fuentes adicionales pasando la ruta al archivo de fuentes como argumento a la font()
funci贸n, as铆 como el nombre de la fuente espec铆fica que desea en caso de que el archivo tenga una colecci贸n de fuentes. Alternativamente, puede darle un nombre a la nueva fuente para que se pueda acceder a ella por ese nombre en lugar de la ruta del archivo:
pdfDoc.registerFont('Name of the font', '/file_path', 'specific_font_name_in_case_of_a_collection')
Llamadas a font()
se puede encadenar con otras funciones, al igual que en el fillColor()
ejemplo.
Tambi茅n puede establecer el tama帽o de fuente mediante el fontSize()
funci贸n. Echemos un vistazo a algunos ejemplos:
const PDFDocument = require('pdfkit');
const fs = require('fs');
let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('fonts.pdf'));
pdfDoc.font('ZapfDingbats').text('This is a symbolic font.');
pdfDoc.font('Times-Roman').fontSize(25).fillColor('blue').text('You can set a color for any font');
pdfDoc.font('Courier').fontSize(5).fillColor('black').text('Some text to demonstrate.');
pdfDoc.end();
Ejecutar esto nos dar铆a el siguiente PDF como resultado:
Agregar im谩genes
Otra cosa com煤n que quiz谩s desee agregar a sus archivos PDF son las im谩genes. Puedes llamar al image()
funci贸n en la instancia del documento y pasar la ruta o el URI de la imagen que desea incluir.
Tambi茅n puede establecer opciones como el ancho, alto, alineaci贸n horizontal y vertical de la imagen pasando un objeto que contenga pares clave-valor como argumento a la image()
funci贸n. De forma predeterminada, las im谩genes se cargan en su tama帽o original.
Si configura el width
y height
– la imagen se estirar谩 para ajustarse a los par谩metros especificados. Si se omite uno de estos, la imagen se escala proporcionalmente al par谩metro proporcionado:
const PDFDocument = require('pdfkit');
const fs = require('fs');
let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('images.pdf'));
pdfDoc.text('By default, the image is loaded in its full size:')
pdfDoc.image('raspberries.jpg');
pdfDoc.moveDown(0.5)
pdfDoc.text('Scaled to fit width and height')
pdfDoc.image('raspberries.jpg', {width: 150, height: 150});
pdfDoc.moveDown(0.5)
pdfDoc.text('Scaled to fit width')
pdfDoc.image('raspberries.jpg', {width: 150});
pdfDoc.end();
Ejecutar este c贸digo nos dar铆a:
Tambi茅n puede escalar la imagen dando un scale
factor. Adem谩s, puede dar un fit
o cover
matriz, donde la imagen se escalar谩 para ajustarse al rect谩ngulo provisto o para cubrirlo, respectivamente. Si proporciona un fit
o cover
matriz, tambi茅n puede establecer la alineaci贸n horizontal (align
) y la alineaci贸n vertical (valign
):
const PDFDocument = require('pdfkit');
const fs = require('fs');
let pdfDoc = new PDFDocument;
pdfDoc.pipe(fs.createWriteStream('images.pdf'));
pdfDoc.text('Scaled by a factor, keeps the original proportions:')
pdfDoc.image('raspberries.jpg', {scale: 0.75});
pdfDoc.moveDown(0.5)
pdfDoc.text('Fit with horizontal alignment:')
pdfDoc.image('raspberries.jpg', {fit: [400, 150], align: 'center'});
pdfDoc.end();
Esto nos dar铆a:
Conclusi贸n
En este art铆culo hemos visto c贸mo generar archivos PDF en Node.js usando PDFKit. Hemos explorado algunas de las opciones disponibles para formatear texto y c贸mo agregar im谩genes a nuestros archivos. La biblioteca tiene una extensa documentaci贸n que cubre mucho m谩s sobre la creaci贸n de archivos PDF en aplicaciones Node.js.