Procesar archivos PDF personalizados.
Introducción
Netuno genera archivos PDF con soporte para imágenes, tablas, fuentes y mucho más, a través del recurso PDF, que permite una abstracción low-code de iTextPDF para los distintos lenguajes de programación soportados por Netuno.
La aplicación que viene con Netuno denominada demo (aplicación de demostración) contiene bastantes ejemplos de las posibles implementaciones de código en varios lenguajes, incluida la demostración de la exportación a PDF mediante el servicio export-pdf, que se encuentra en:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
netuno/apps/demo/server/services/samples/javascript/export-pdf.js
netuno/apps/demo/server/services/samples/typescript/export-pdf.ts
netuno/apps/demo/server/services/samples/python/export-pdf.py
netuno/apps/demo/server/services/samples/ruby/export-pdf.rb
netuno/apps/demo/server/services/samples/kotlin/export-pdf.kts
netuno/apps/demo/server/services/samples/groovy/export-pdf.groovy
Inicialización
En primer lugar es necesario crear el objeto que va a contener el contexto del nuevo documento que se está creando; por defecto, el tamaño de las páginas es A4.
Al crear el documento se define dónde se generará.
Si no se define nada, se generará en la salida de datos del servicio, por ejemplo:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentoPdf = _pdf.newDocument()
const documentoPdf = _pdf.newDocument()
documentoPdf = _pdf.newDocument()
documentoPdf = _pdf.newDocument()
val documentoPdf = _pdf.newDocument()
def documentoPdf = _pdf.newDocument()
Para generar un archivo PDF dentro de la carpeta docs de la aplicación, se puede hacer así:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentoPdf = _pdf.newDocument(_app.file("docs/archivo.pdf").output())
const documentoPdf = _pdf.newDocument(_app.file("docs/archivo.pdf").output())
documentoPdf = _pdf.newDocument(_app.file("docs/archivo.pdf").output())
documentoPdf = _pdf.newDocument(_app.file("docs/archivo.pdf").output())
val documentoPdf = _pdf.newDocument(_app.file("docs/archivo.pdf").output())
def documentoPdf = _pdf.newDocument(_app.file("docs/archivo.pdf").output())
Si se va a generar el documento en un nuevo archivo fuera de la aplicación, por ejemplo:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentoPdf = _pdf.newDocument(_os.file("/tmp/archivo.pdf").output())
const documentoPdf = _pdf.newDocument(_os.file("/tmp/archivo.pdf").output())
documentoPdf = _pdf.newDocument(_os.file("/tmp/archivo.pdf").output())
documentoPdf = _pdf.newDocument(_os.file("/tmp/archivo.pdf").output())
val documentoPdf = _pdf.newDocument(_os.file("/tmp/archivo.pdf").output())
def documentoPdf = _pdf.newDocument(_os.file("/tmp/archivo.pdf").output())
O también en el storage de la aplicación:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output())
const documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output())
documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output())
documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output())
val documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output())
def documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output())
Por defecto, el documento se crea con el formato de página A4.
Formato de página
Para personalizar el formato de la página basta con indicarlo al crear el documento.
Crea un nuevo documento para la salida de datos del servicio con páginas en formato carta:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentoPdf = _pdf.newDocument(_pdf.pageSize("letter"))
const documentoPdf = _pdf.newDocument(_pdf.pageSize("letter"))
documentoPdf = _pdf.newDocument(_pdf.pageSize("letter"))
documentoPdf = _pdf.newDocument(_pdf.pageSize("letter"))
val documentoPdf = _pdf.newDocument(_pdf.pageSize("letter"))
def documentoPdf = _pdf.newDocument(_pdf.pageSize("letter"))
Crea un nuevo documento para un archivo en la raíz de la aplicación con el formato de página B3:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentoPdf = _pdf.newDocument(_app.file("archivo.pdf").output(), _pdf.pageSize("B3"))
const documentoPdf = _pdf.newDocument(_app.file("archivo.pdf").output(), _pdf.pageSize("B3"))
documentoPdf = _pdf.newDocument(_app.file("archivo.pdf").output(), _pdf.pageSize("B3"))
documentoPdf = _pdf.newDocument(_app.file("archivo.pdf").output(), _pdf.pageSize("B3"))
val documentoPdf = _pdf.newDocument(_app.file("archivo.pdf").output(), _pdf.pageSize("B3"))
def documentoPdf = _pdf.newDocument(_app.file("archivo.pdf").output(), _pdf.pageSize("B3"))
Crea un nuevo documento en el storage de la aplicación con el formato de página legal:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output(), _pdf.pageSize("legal"))
const documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output(), _pdf.pageSize("legal"))
documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output(), _pdf.pageSize("legal"))
documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output(), _pdf.pageSize("legal"))
val documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output(), _pdf.pageSize("legal"))
def documentoPdf = _pdf.newDocument(_storage.filesystem("server", "archivo.pdf").output(), _pdf.pageSize("legal"))
Consulte la documentación sobre la definición del tamaño de las páginas.
Los documentos PDF se pueden crear con una definición personalizada del tamaño de página; para ello, utilice pageSize pasando el valor del ancho y la altura de la página, por ejemplo:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_pdf.pageSize(50, 30)
_pdf.pageSize(50, 30)
_pdf.pageSize(50, 30)
_pdf.pageSize(50, 30)
_pdf.pageSize(50, 30)
_pdf.pageSize(50, 30)
Cabecera HTTP
Para crear un servicio en la API REST que devuelva un archivo PDF como salida de datos, es necesario añadir en la cabecera el parámetro Content-Type del protocolo HTTP.
Ejemplo de cómo definir el contenido como PDF:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_header.contentType("pdf")
_header.contentType("pdf")
_header.contentType("pdf")
_header.contentType("pdf")
_header.contentType("pdf")
_header.contentType("pdf")
El código pdf es una abreviatura de:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_header.contentType("application/pdf")
_header.contentType("application/pdf")
_header.contentType("application/pdf")
_header.contentType("application/pdf")
_header.contentType("application/pdf")
_header.contentType("application/pdf")
Salto de página
Para crear una nueva página se utiliza areaBreak:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
documentoPdf.add(
_pdf.areaBreak()
)
documentoPdf.add(
_pdf.areaBreak()
)
documentoPdf.add(
_pdf.areaBreak()
)
documentoPdf.add(
_pdf.areaBreak()
)
documentoPdf.add(
_pdf.areaBreak()
)
documentoPdf.add(
_pdf.areaBreak()
)
Párrafo
Añade un nuevo párrafo al documento:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
documentoPdf.add(
_pdf.paragraph("Mi texto aquí...")
.setFontSize(15)
)
documentoPdf.add(
_pdf.paragraph("Mi texto aquí...")
.setFontSize(15)
)
documentoPdf.add(
_pdf.paragraph("Mi texto aquí...")
.setFontSize(15)
)
documentoPdf.add(
_pdf.paragraph("Mi texto aquí...")
.setFontSize(15)
)
documentoPdf.add(
_pdf.paragraph("Mi texto aquí...")
.setFontSize(15)
)
documentoPdf.add(
_pdf.paragraph("Mi texto aquí...")
.setFontSize(15)
)
Para añadir un párrafo en una posición fija:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
documentoPdf.add(
documentoPdf.add(
_pdf.paragraph("Mi texto fijo...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
documentoPdf.add(
documentoPdf.add(
_pdf.paragraph("Mi texto fijo...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
documentoPdf.add(
documentoPdf.add(
_pdf.paragraph("Mi texto fijo...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
documentoPdf.add(
documentoPdf.add(
_pdf.paragraph("Mi texto fijo...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
documentoPdf.add(
documentoPdf.add(
_pdf.paragraph("Mi texto fijo...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
documentoPdf.add(
documentoPdf.add(
_pdf.paragraph("Mi texto fijo...")
.setFixedPosition(100, 500, 200)
.setFontSize(15)
)
)
En el código anterior, en el método setFixedPosition, el primer parámetro es la posición X (100), el segundo parámetro es la posición Y (500) y el tercer parámetro es la anchura (200).
Atención: si el valor de Y se define como 0, significa que queda en el fondo de la página; por tanto, para subirlo hay que aumentar el valor de Y. Cuanto mayor sea el valor de Y, más arriba aparecerá, pero si es demasiado alto y supera la longitud de la página, no será visible.
Documentación con todos los métodos del objeto de Párrafo de iText.
Fuente
Para definir una fuente nativa podemos hacerlo de la siguiente forma:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const helvetica = _pdf.font("helvetica")
const helveticaNegrita = _pdf.font("helvetica-bold")
const helveticaNegritaOblicua = _pdf.font("helvetica-boldoblique")
const helveticaOblicua = _pdf.font("helvetica-oblique")
const helvetica = _pdf.font("helvetica")
const helveticaNegrita = _pdf.font("helvetica-bold")
const helveticaNegritaOblicua = _pdf.font("helvetica-boldoblique")
const helveticaOblicua = _pdf.font("helvetica-oblique")
helvetica = _pdf.font("helvetica")
helveticaNegrita = _pdf.font("helvetica-bold")
helveticaNegritaOblicua = _pdf.font("helvetica-boldoblique")
helveticaOblicua = _pdf.font("helvetica-oblique")
helvetica = _pdf.font("helvetica")
helveticaNegrita = _pdf.font("helvetica-bold")
helveticaNegritaOblicua = _pdf.font("helvetica-boldoblique")
helveticaOblicua = _pdf.font("helvetica-oblique")
val helvetica = _pdf.font("helvetica")
val helveticaNegrita = _pdf.font("helvetica-bold")
val helveticaNegritaOblicua = _pdf.font("helvetica-boldoblique")
val helveticaOblicua = _pdf.font("helvetica-oblique")
def helvetica = _pdf.font("helvetica")
def helveticaNegrita = _pdf.font("helvetica-bold")
def helveticaNegritaOblicua = _pdf.font("helvetica-boldoblique")
def helveticaOblicua = _pdf.font("helvetica-oblique")
Para definir una fuente personalizada a medida, podemos utilizar storage:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
const viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
val viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
def viksiScript = _pdf.font(_storage.filesystem("server", "samples/export-pdf", "viksi-script.ttf"), true)
También podemos utilizar un archivo dentro de la aplicación, como demuestra este ejemplo, en el que la fuente está dentro de la carpeta fonts en la raíz de la aplicación:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
const roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
val roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
def roboto = _pdf.font(_app.file("fonts/roboto.ttf"), true)
O incluso utilizar un archivo en cualquier ruta del sistema; en este ejemplo, la fuente está dentro de la carpeta fonts, que está dentro de la carpeta de archivos temporales del sistema:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
const roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
val roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
def roboto = _pdf.font(_os.file("/tmp/fonts/roboto.ttf"), true)
Documentación con todos los métodos del objeto de Fuente de iText.
Para utilizar la fuente en los textos, se debe pasar la constante de la fuente al párrafo, de esta forma:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
documentoPdf.add(
_pdf.paragraph("Utilizando la fuente en negrita.")
.setFont(helveticaNegrita)
.setFontSize(15)
)
documentoPdf.add(
_pdf.paragraph("Utilizando la fuente en negrita.")
.setFont(helveticaNegrita)
.setFontSize(15)
)
documentoPdf.add(
_pdf.paragraph("Utilizando la fuente en negrita.")
.setFont(helveticaNegrita)
.setFontSize(15)
)
documentoPdf.add(
_pdf.paragraph("Utilizando la fuente en negrita.")
.setFont(helveticaNegrita)
.setFontSize(15)
)
documentoPdf.add(
_pdf.paragraph("Utilizando la fuente en negrita.")
.setFont(helveticaNegrita)
.setFontSize(15)
)
documentoPdf.add(
_pdf.paragraph("Utilizando la fuente en negrita.")
.setFont(helveticaNegrita)
.setFontSize(15)
)
Imagen
La inserción de imágenes en el documento PDF generado programáticamente se hace de esta forma:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
documentoPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
documentoPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
documentoPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
documentoPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
documentoPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
documentoPdf.add(
_pdf.image(_storage.filesystem("server", "samples/export-pdf", "logo.png"))
.scaleAbsolute(120, 36)
)
Tenga en cuenta que el método scaleAbsolute es muy útil para redimensionar y ajustar el tamaño de la imagen.
Como alternativa, podemos utilizar un archivo dentro de la aplicación, como en este ejemplo:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const imagenLogo = _pdf.image(_app.file("public/images/logo.png")
const imagenLogo = _pdf.image(_app.file("public/images/logo.png")
imagenLogo = _pdf.image(_app.file("public/images/logo.png")
imagenLogo = _pdf.image(_app.file("public/images/logo.png")
val imagenLogo = _pdf.image(_app.file("public/images/logo.png")
def imagenLogo = _pdf.image(_app.file("public/images/logo.png")
O incluso utilizar un archivo en cualquier ruta del sistema, como en este ejemplo:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const imagenLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
const imagenLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
imagenLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
imagenLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
val imagenLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
def imagenLogo = _pdf.image(_os.file("/tmp/images/pdf-logo.png")
Para añadir una imagen en una posición fija:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
documentoPdf.add(
imagenLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
documentoPdf.add(
imagenLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
documentoPdf.add(
imagenLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
documentoPdf.add(
imagenLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
documentoPdf.add(
imagenLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
documentoPdf.add(
imagenLogo
.scaleAbsolute(120, 36)
.setFixedPosition(100, 500)
)
En el código anterior, en el método setFixedPosition, el primer parámetro es la posición X (100) y el segundo parámetro es la posición Y (500).
Atención: si el valor de Y se define como 0, significa que queda en el fondo de la página; por tanto, para subirlo hay que aumentar el valor de Y. Cuanto mayor sea el valor de Y, más arriba aparecerá, pero si es demasiado alto y supera la longitud de la página, no será visible.
Documentación con todos los métodos del objeto de Imagen de iText.
Tabla
Es posible crear tablas, lo que permite presentar un conjunto de datos de forma más legible.
El número de columnas de la tabla se define con el parámetro: _pdf.table(numeroColumnas)
En el ejemplo siguiente, numeroColumnas es el número 1, es decir, una columna.
Como añadimos dos celdas a la tabla, la segunda celda pasa a la línea siguiente.
Observe:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
documentoPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Persona")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nicole")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
documentoPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Persona")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nicole")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
documentoPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Persona")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nicole")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
documentoPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Persona")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nicole")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
documentoPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Persona")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nicole")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
documentoPdf.add(
_pdf.table(1)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Persona")
.setFont(helvetica)
.setFontSize(10)
)
.setBorder(_pdf.border("solid", 2))
.setBackgroundColor(_pdf.colorRGB(1, 0, 0))
)
.addCell(
_pdf.cell()
.add(
_pdf.paragraph("Nicole")
.setFont(helvetica)
.setFontSize(10)
)
.setBackgroundColor(_pdf.colorGray(0.5))
)
)
Con el método addCell se permite insertar la definición de las celdas con su respectivo contenido.
Documentación con todos los métodos del objeto de Celda de iText.
Cerrar y guardar el documento
El documento solo se guarda o genera por completo cuando se llama al método close, de la siguiente forma:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
documentoPdf.close()
documentoPdf.close()
documentoPdf.close()
documentoPdf.close()
documentoPdf.close()
documentoPdf.close()
El lugar donde se genera el documento se define en la inicialización; por tanto, es en la inicialización del documento donde definimos dónde se generará el documento final, si será en la salida de datos del servicio (output) o en un archivo.
Editar archivo
Es posible editar un documento PDF ya existente, por ejemplo:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentoPdf = _pdf.openDocument(_app.file("archivo.pdf"))
const documentoPdf = _pdf.openDocument(_app.file("archivo.pdf"))
documentoPdf = _pdf.openDocument(_app.file("archivo.pdf"))
documentoPdf = _pdf.openDocument(_app.file("archivo.pdf"))
val documentoPdf = _pdf.openDocument(_app.file("archivo.pdf"))
def documentoPdf = _pdf.openDocument(_app.file("archivo.pdf"))
El documento final generado se enviará en la salida de datos del servicio.
Es muy útil para utilizar un PDF como base, como si fuera una plantilla.
Ejemplo para editar un documento en el storage de la aplicación:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentoPdf = _pdf.openDocument(_storage.filesystem('server', 'archivo.pdf'))
const documentoPdf = _pdf.openDocument(_storage.filesystem('server', 'archivo.pdf'))
documentoPdf = _pdf.openDocument(_storage.filesystem('server', 'archivo.pdf'))
documentoPdf = _pdf.openDocument(_storage.filesystem('server', 'archivo.pdf'))
val documentoPdf = _pdf.openDocument(_storage.filesystem('server', 'archivo.pdf'))
def documentoPdf = _pdf.openDocument(_storage.filesystem('server', 'archivo.pdf'))
Utiliza un documento como base, pero guarda los cambios en un nuevo archivo PDF:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentoPdf = _pdf.openDocument(
_app.file("documento-base.pdf"),
_app.file("documento-final.pdf")
)
const documentoPdf = _pdf.openDocument(
_app.file("documento-base.pdf"),
_app.file("documento-final.pdf")
)
documentoPdf = _pdf.openDocument(
_app.file("documento-base.pdf"),
_app.file("documento-final.pdf")
)
documentoPdf = _pdf.openDocument(
_app.file("documento-base.pdf"),
_app.file("documento-final.pdf")
)
val documentoPdf = _pdf.openDocument(
_app.file("documento-base.pdf"),
_app.file("documento-final.pdf")
)
def documentoPdf = _pdf.openDocument(
_app.file("documento-base.pdf"),
_app.file("documento-final.pdf")
)
Ejemplo usando como base un documento en el storage, pero lo guarda en otro:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const documentoPdf = _pdf.openDocument(
_storage.filesystem("server", "contrato-base.pdf"),
_storage.filesystem("server", "contrato-final.pdf")
)
const documentoPdf = _pdf.openDocument(
_storage.filesystem("server", "contrato-base.pdf"),
_storage.filesystem("server", "contrato-final.pdf")
)
documentoPdf = _pdf.openDocument(
_storage.filesystem("server", "contrato-base.pdf"),
_storage.filesystem("server", "contrato-final.pdf")
)
documentoPdf = _pdf.openDocument(
_storage.filesystem("server", "contrato-base.pdf"),
_storage.filesystem("server", "contrato-final.pdf")
)
val documentoPdf = _pdf.openDocument(
_storage.filesystem("server", "contrato-base.pdf"),
_storage.filesystem("server", "contrato-final.pdf")
)
def documentoPdf = _pdf.openDocument(
_storage.filesystem("server", "contrato-base.pdf"),
_storage.filesystem("server", "contrato-final.pdf")
)
Con el documento cargado podemos añadir contenidos y, al cerrarlo con el método close al final, se genera el documento final con el nuevo contenido añadido programáticamente.
Ejemplo de servicio que utiliza un PDF existente como plantilla para generar una salida de archivo PDF con contenido dinámico añadido:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_header.contentType("pdf")
const documentoPdf = _pdf.openDocument(_app.file("plantilla-1.pdf"))
documentoPdf.add(
_pdf.paragraph("Mi contenido dinámico.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
documentoPdf.close()
_header.contentType("pdf")
const documentoPdf = _pdf.openDocument(_app.file("plantilla-1.pdf"))
documentoPdf.add(
_pdf.paragraph("Mi contenido dinámico.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
documentoPdf.close()
_header.contentType("pdf")
documentoPdf = _pdf.openDocument(_app.file("plantilla-1.pdf"))
documentoPdf.add(
_pdf.paragraph("Mi contenido dinámico.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
documentoPdf.close()
_header.contentType("pdf")
documentoPdf = _pdf.openDocument(_app.file("plantilla-1.pdf"))
documentoPdf.add(
_pdf.paragraph("Mi contenido dinámico.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
documentoPdf.close()
_header.contentType("pdf")
val documentoPdf = _pdf.openDocument(_app.file("plantilla-1.pdf"))
documentoPdf.add(
_pdf.paragraph("Mi contenido dinámico.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
documentoPdf.close()
_header.contentType("pdf")
def documentoPdf = _pdf.openDocument(_app.file("plantilla-1.pdf"))
documentoPdf.add(
_pdf.paragraph("Mi contenido dinámico.")
.setFixedPosition(37, 730, 100)
.setFontSize(15)
)
documentoPdf.close()
Leer archivo
Para leer un documento PDF, extrayendo la información de texto.
Utilizamos el método extract, que obtiene todos los datos del archivo PDF en un objeto JSON.
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const datosPdf = _pdf.extract(_app.file("archivo-1.pdf"))
_out.json(datosPdf)
const datosPdf = _pdf.extract(_app.file("archivo-1.pdf"))
_out.json(datosPdf)
datosPdf = _pdf.extract(_app.file("archivo-1.pdf"))
_out.json(datosPdf)
datosPdf = _pdf.extract(_app.file("archivo-1.pdf"))
_out.json(datosPdf)
val datosPdf = _pdf.extract(_app.file("archivo-1.pdf"))
_out.json(datosPdf)
def datosPdf = _pdf.extract(_app.file("archivo-1.pdf"))
_out.json(datosPdf)
El JSON devuelto tiene la clave content con todo el contenido de texto del archivo PDF, y tiene la clave metadata con las distintas propiedades del archivo PDF.
Aquí tiene un ejemplo del JSON devuelto por extract:
{
"content": "Todo el contenido en texto del archivo PDF viene aquí...",
"metadata":{
"Content-Type":"application/pdf",
"dc:format":"application/pdf; version=1.4",
"dc:title":"Linux 1",
"pdf:PDFVersion":"1.4",
"pdf:charsPerPage":"580",
"pdf:containsDamagedFont":"false",
"pdf:containsNonEmbeddedFont":"false",
"pdf:docinfo:producer":"Skia/PDF m125 Google Docs Renderer",
"pdf:docinfo:title":"Archivo 1",
"pdf:encrypted":"false",
"xmpTPg:NPages":"3",
...
}
}
Existen muchos otros datos que se obtienen en metadata, pero que se han omitido en los ... para que el ejemplo no sea demasiado largo.
Convertir
Es posible convertir programáticamente el PDF a texto o incluso a HTML.
PDF a texto
Podemos extraer todo el contenido del archivo PDF en texto corrido utilizando el método:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_pdf.toText(...)
_pdf.toText(...)
_pdf.toText(...)
_pdf.toText(...)
_pdf.toText(...)
_pdf.toText(...)
Ejemplo de cómo utilizarlo para leer un archivo en la raíz de la aplicación:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_out.print(_pdf.toText(_app.file("mi-documento.pdf")))
_out.print(_pdf.toText(_app.file("mi-documento.pdf")))
_out.print(_pdf.toText(_app.file("mi-documento.pdf")))
_out.print(_pdf.toText(_app.file("mi-documento.pdf")))
_out.print(_pdf.toText(_app.file("mi-documento.pdf")))
_out.print(_pdf.toText(_app.file("mi-documento.pdf")))
O incluso utilizando un archivo en el storage de la aplicación:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_out.print(_pdf.toText(_storage.filesystem("server", "mi-documento.pdf")))
_out.print(_pdf.toText(_storage.filesystem("server", "mi-documento.pdf")))
_out.print(_pdf.toText(_storage.filesystem("server", "mi-documento.pdf")))
_out.print(_pdf.toText(_storage.filesystem("server", "mi-documento.pdf")))
_out.print(_pdf.toText(_storage.filesystem("server", "mi-documento.pdf")))
_out.print(_pdf.toText(_storage.filesystem("server", "mi-documento.pdf")))
PDF a HTML
Podemos extraer todo el contenido del archivo PDF en HTML utilizando el método:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_pdf.toHTML(...)
_pdf.toHTML(...)
_pdf.toHTML(...)
_pdf.toHTML(...)
_pdf.toHTML(...)
_pdf.toHTML(...)
Ejemplo de cómo utilizarlo para leer un archivo en la raíz de la aplicación:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_out.print(_pdf.toHTML(_app.file("mi-documento.pdf")))
_out.print(_pdf.toHTML(_app.file("mi-documento.pdf")))
_out.print(_pdf.toHTML(_app.file("mi-documento.pdf")))
_out.print(_pdf.toHTML(_app.file("mi-documento.pdf")))
_out.print(_pdf.toHTML(_app.file("mi-documento.pdf")))
_out.print(_pdf.toHTML(_app.file("mi-documento.pdf")))
O incluso utilizando un archivo en el storage de la aplicación:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_out.print(_pdf.toHTML(_storage.filesystem("server", "mi-documento.pdf")))
_out.print(_pdf.toHTML(_storage.filesystem("server", "mi-documento.pdf")))
_out.print(_pdf.toHTML(_storage.filesystem("server", "mi-documento.pdf")))
_out.print(_pdf.toHTML(_storage.filesystem("server", "mi-documento.pdf")))
_out.print(_pdf.toHTML(_storage.filesystem("server", "mi-documento.pdf")))
_out.print(_pdf.toHTML(_storage.filesystem("server", "mi-documento.pdf")))
HTML a PDF
Es posible generar archivos PDF a partir de código HTML utilizando el método:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_pdf.fromHTML(...)
_pdf.fromHTML(...)
_pdf.fromHTML(...)
_pdf.fromHTML(...)
_pdf.fromHTML(...)
_pdf.fromHTML(...)
Ejemplo de cómo utilizarlo para generar un archivo de descarga en el servicio:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const icono = _app.file("public/images/icon.png");
const archivoPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto;
}
div.barra-lateral {
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 100px;
background: #1B5886;
}
div.barra-lateral > div {
position: absolute;
top: 350px;
transform: rotate(-90deg) translate(-50%, -34px);
font-family: Limelight;
font-size: 40px;
color: #89CFF1;
}
main {
padding-left: 150px;
}
h1 {
margin: 0 auto;
text-align: center;
font-family: Limelight;
color: #BA250E;
}
table {
margin: 0 auto;
border: 1px solid black;
border-spacing: 0;
border-collapse: collapse;
}
table > thead {
background: #40712A;
color: #fff;
}
table td, table th {
padding: 5px;
text-align: center;
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1;
}
a {
font-family: Limelight;
font-size: 16px;
font-weight: bold;
text-decoration: none;
color: #1E5FB5;
}
</style>
</head>
<body>
<div class="barra-lateral">
<div>Demostración</div>
</div>
<main>
<h1>PDF a partir del HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
Este es un HTML de ejemplo para la generación de un archivo PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Nombre</th>
<th>Edad</th>
</tr>
</thread>
<tbody>
<tr>
<td>María Luisa</td>
<td>23</td>
</tr>
<tr>
<td>José Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`);
_header.contentTypePDF();
_out.copy(archivoPdf.input());
const icono = _app.file("public/images/icon.png");
const archivoPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto;
}
div.barra-lateral {
position: fixed;
top: 0;
bottom: 0;
left: 0;
width: 100px;
background: #1B5886;
}
div.barra-lateral > div {
position: absolute;
top: 350px;
transform: rotate(-90deg) translate(-50%, -34px);
font-family: Limelight;
font-size: 40px;
color: #89CFF1;
}
main {
padding-left: 150px;
}
h1 {
margin: 0 auto;
text-align: center;
font-family: Limelight;
color: #BA250E;
}
table {
margin: 0 auto;
border: 1px solid black;
border-spacing: 0;
border-collapse: collapse;
}
table > thead {
background: #40712A;
color: #fff;
}
table td, table th {
padding: 5px;
text-align: center;
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1;
}
a {
font-family: Limelight;
font-size: 16px;
font-weight: bold;
text-decoration: none;
color: #1E5FB5;
}
</style>
</head>
<body>
<div class="barra-lateral">
<div>Demostración</div>
</div>
<main>
<h1>PDF a partir del HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
Este es un HTML de ejemplo para la generación de un archivo PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Nombre</th>
<th>Edad</th>
</tr>
</thread>
<tbody>
<tr>
<td>María Luisa</td>
<td>23</td>
</tr>
<tr>
<td>José Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`);
_header.contentTypePDF();
_out.copy(archivoPdf.input());
icono = _app.file("public/images/icon.png")
archivoPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto
}
div.barra-lateral {
position: fixed
top: 0
bottom: 0
left: 0
width: 100px
background: #1B5886
}
div.barra-lateral > div {
position: absolute
top: 350px
transform: rotate(-90deg) translate(-50%, -34px)
font-family: Limelight
font-size: 40px
color: #89CFF1
}
main {
padding-left: 150px
}
h1 {
margin: 0 auto
text-align: center
font-family: Limelight
color: #BA250E
}
table {
margin: 0 auto
border: 1px solid black
border-spacing: 0
border-collapse: collapse
}
table > thead {
background: #40712A
color: #fff
}
table td, table th {
padding: 5px
text-align: center
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1
}
a {
font-family: Limelight
font-size: 16px
font-weight: bold
text-decoration: none
color: #1E5FB5
}
</style>
</head>
<body>
<div class="barra-lateral">
<div>Demostración</div>
</div>
<main>
<h1>PDF a partir del HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
Este es un HTML de ejemplo para la generación de un archivo PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Nombre</th>
<th>Edad</th>
</tr>
</thread>
<tbody>
<tr>
<td>María Luisa</td>
<td>23</td>
</tr>
<tr>
<td>José Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`)
_header.contentTypePDF()
_out.copy(archivoPdf.input())
icono = _app.file("public/images/icon.png")
archivoPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto
}
div.barra-lateral {
position: fixed
top: 0
bottom: 0
left: 0
width: 100px
background: #1B5886
}
div.barra-lateral > div {
position: absolute
top: 350px
transform: rotate(-90deg) translate(-50%, -34px)
font-family: Limelight
font-size: 40px
color: #89CFF1
}
main {
padding-left: 150px
}
h1 {
margin: 0 auto
text-align: center
font-family: Limelight
color: #BA250E
}
table {
margin: 0 auto
border: 1px solid black
border-spacing: 0
border-collapse: collapse
}
table > thead {
background: #40712A
color: #fff
}
table td, table th {
padding: 5px
text-align: center
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1
}
a {
font-family: Limelight
font-size: 16px
font-weight: bold
text-decoration: none
color: #1E5FB5
}
</style>
</head>
<body>
<div class="barra-lateral">
<div>Demostración</div>
</div>
<main>
<h1>PDF a partir del HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
Este es un HTML de ejemplo para la generación de un archivo PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Nombre</th>
<th>Edad</th>
</tr>
</thread>
<tbody>
<tr>
<td>María Luisa</td>
<td>23</td>
</tr>
<tr>
<td>José Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`)
_header.contentTypePDF()
_out.copy(archivoPdf.input())
val icono = _app.file("public/images/icon.png")
val archivoPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto
}
div.barra-lateral {
position: fixed
top: 0
bottom: 0
left: 0
width: 100px
background: #1B5886
}
div.barra-lateral > div {
position: absolute
top: 350px
transform: rotate(-90deg) translate(-50%, -34px)
font-family: Limelight
font-size: 40px
color: #89CFF1
}
main {
padding-left: 150px
}
h1 {
margin: 0 auto
text-align: center
font-family: Limelight
color: #BA250E
}
table {
margin: 0 auto
border: 1px solid black
border-spacing: 0
border-collapse: collapse
}
table > thead {
background: #40712A
color: #fff
}
table td, table th {
padding: 5px
text-align: center
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1
}
a {
font-family: Limelight
font-size: 16px
font-weight: bold
text-decoration: none
color: #1E5FB5
}
</style>
</head>
<body>
<div class="barra-lateral">
<div>Demostración</div>
</div>
<main>
<h1>PDF a partir del HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
Este es un HTML de ejemplo para la generación de un archivo PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Nombre</th>
<th>Edad</th>
</tr>
</thread>
<tbody>
<tr>
<td>María Luisa</td>
<td>23</td>
</tr>
<tr>
<td>José Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`)
_header.contentTypePDF()
_out.copy(archivoPdf.input())
final icono = _app.file("public/images/icon.png")
final archivoPdf = _pdf.fromHTML(`
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Limelight&family=Roboto" rel="stylesheet">
<style>
* {
font-family: Roboto
}
div.barra-lateral {
position: fixed
top: 0
bottom: 0
left: 0
width: 100px
background: #1B5886
}
div.barra-lateral > div {
position: absolute
top: 350px
transform: rotate(-90deg) translate(-50%, -34px)
font-family: Limelight
font-size: 40px
color: #89CFF1
}
main {
padding-left: 150px
}
h1 {
margin: 0 auto
text-align: center
font-family: Limelight
color: #BA250E
}
table {
margin: 0 auto
border: 1px solid black
border-spacing: 0
border-collapse: collapse
}
table > thead {
background: #40712A
color: #fff
}
table td, table th {
padding: 5px
text-align: center
}
table > tbody > tr:nth-child(even) {
background: #e1e1e1
}
a {
font-family: Limelight
font-size: 16px
font-weight: bold
text-decoration: none
color: #1E5FB5
}
</style>
</head>
<body>
<div class="barra-lateral">
<div>Demostración</div>
</div>
<main>
<h1>PDF a partir del HTML</h1>
<div style="text-align: center; margin: 30px 0;">
<img width="50" src="${icon.uri()}">
</div>
<p>
Este es un HTML de ejemplo para la generación de un archivo PDF.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam
tellus arcu, pharetra quis condimentum eget, dapibus convallis metus.
</p>
<table>
<thead>
<tr>
<th>Nombre</th>
<th>Edad</th>
</tr>
</thread>
<tbody>
<tr>
<td>María Luisa</td>
<td>23</td>
</tr>
<tr>
<td>José Matos</td>
<td>38</td>
</tr>
</tbody>
</table>
<hr style="margin-top: 50px; height: 1px; background: #50B6C6; border: none;"/>
<div>
<a href="https://netuno.org" target="_blank">Netuno.org</a>
</div>
</main>
</body>
</html>
`)
_header.contentTypePDF()
_out.copy(archivoPdf.input())
Vídeos
A continuación se muestran algunos vídeos de ejemplo sobre cómo realizar la generación de archivos PDF programáticamente: