Generar un PDF en Spring Boot con iTextPDF y JHipster

Si estás desarrollando una aplicación en Java con Spring Boot y JHipster, probablemente te hayas encontrado con la necesidad de generar documentos PDF. En este artículo, exploraremos cómo puedes crear un PDF utilizando la biblioteca iTextPDF, partiendo de una plantilla HTML que puedes personalizar según tus necesidades. Este enfoque no solo te permitirá mantener el diseño que deseas, sino también añadir atributos dinámicos.
Requisitos Previos
Antes de empezar, asegúrate de tener configurado tu proyecto de Spring Boot con JHipster. Debes tener las siguientes dependencias en tu archivo pom.xml
:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.15</version>
</dependency>
Paso 1: Crear una Plantilla HTML
Primero, necesitas crear una plantilla HTML que sirva como base para tu PDF. Esta plantilla puede contener cualquier contenido que desees, desde textos e imágenes hasta atributos personalizados para cada PDF generado. Aquí tienes un ejemplo básico de una plantilla HTML:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Factura</title>
<style>
body { font-family: Arial, sans-serif; }
.header { text-align: center; }
.content { margin: 20px; }
</style>
</head>
<body>
<div class="header">
<h1>Factura</h1>
</div>
<div class="content">
<p>Nombre: {{nombre}}</p>
<p>Monto: {{monto}}</p>
</div>
</body>
</html>
En esta plantilla, hemos utilizado placeholders {{nombre}}
y {{monto}}
que se reemplazarán con valores dinámicos en tiempo de ejecución.
Paso 2: Crear el Servicio para Generar el PDF
Ahora vamos a crear un servicio en Spring Boot que generará el PDF a partir de la plantilla HTML. Utilizaremos la librería iTextPDF para este propósito.
import com.itextpdf.html2pdf.HtmlConverter;
import org.springframework.stereotype.Service;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.util.Map;
@Service
public class PdfService {
public byte[] generatePdf(String templatePath, Map<String, String> placeholders) throws IOException {
// Read the HTML template as a string
String htmlContent = new String(Files.readAllBytes(Paths.get(templatePath)), StandardCharsets.UTF_8);
// Replace placeholders with actual values
for (Map.Entry<String, String> entry : placeholders.entrySet()) {
htmlContent = htmlContent.replace("{{" + entry.getKey() + "}}", entry.getValue());
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
HtmlConverter.convertToPdf(htmlTemplate, outputStream);
} catch (Exception e) {
e.printStackTrace();
}
return outputStream.toByteArray();
}
}
En este servicio, estamos utilizando HtmlConverter
de iTextPDF para convertir el HTML en un PDF. Recibimos como parámetros la ruta donde está la plantilla HTML («templatePath») y un Map con los atributos a sustituir en la plantilla HTML y generamos el PDF en un flujo de salida («outputStream»). En este caso devolvemos directamente el PDF generado. Sin embargo, existe otra opción para guardar el PDF generado en el servidor y devolver ese PDF. Para guardar el PDF en una ruta solo debemos sustituir la línea de «HtmlConverter.convertToPdf(htmlTemplate, outputStream)» por la siguiente línea de código:
HtmlConverter.convertToPdf(htmlContent, new FileOutputStream(outputPdfPath));
En este caso, se generaría un nuevo archivo, que sería el PDF, en la ruta deseada («outputPdfPath»).
Paso 3: Crear un Controlador para Manejar las Solicitudes
Ahora, necesitamos un controlador que maneje las solicitudes de generación de PDF. Este controlador llamará al servicio que creamos anteriormente.
javaCopiar códigoimport org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
@RestController
public class PdfController {
private final PdfService pdfService;
public PdfController(PdfService pdfService) {
this.pdfService = pdfService;
}
@PostMapping("/generate-pdf")
public void generatePdf(@RequestBody PdfRequestDto requestDto, HttpServletResponse response) throws IOException {
// Define the paths to the HTML template and output PDF
String templatePath = "src/main/resources/templates/PDF/invoice_template.html";
// Convert DTO to a Map for placeholder replacement
Map<String, String> placeholders = new HashMap<>();
placeholders.put("nombre", requestDto.getName());
placeholders.put("monto", requestDto.getAmount());byte[] pdfContents = pdfService.generatePdf(templatePath, placeholders);
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=factura.pdf");
response.getOutputStream().write(pdfContents);
}
}
Este controlador expone un endpoint /generate-pdf
que permite generar un PDF al proporcionar el nombre y el monto. El PDF se enviará como una descarga al cliente. Cabe destacar que, para este ejemplo, hemos escrito la ruta de la plantilla HTML en el código directamente, aunque lo ideal sería leer esta ruta desde un archivo de properties o desde otro objeto de Java.
Prueba del Endpoint
Para probar que nuestro servicio funciona correctamente, podemos hacer una llamada a la API como la siguiente y deberíamos de obtener el PDF generado:
POST
localhost:8080/generate-pdf
{
"name": "Juan",
"amount": "1000"
}
Personalización de la Plantilla HTML
Una de las grandes ventajas de usar una plantilla HTML es la facilidad de personalización. Puedes añadir estilos CSS, imágenes, tablas y cualquier otro elemento que desees. Además, puedes hacer que tu plantilla reciba más atributos dinámicos según las necesidades de tu aplicación.
Conclusión
Generar un PDF en Spring Boot utilizando iTextPDF y JHipster es un proceso relativamente sencillo que te permite crear documentos atractivos y personalizados. Al utilizar una plantilla HTML, puedes asegurarte de que el diseño sea flexible y se adapte a tus requerimientos. No olvides explorar más sobre las funcionalidades de iTextPDF para sacar el máximo provecho en tus proyectos de Java.
¡Ahora que conoces cómo generar PDFs en Spring Boot, es momento de implementarlo en tu aplicación y mejorar la experiencia de tus usuarios!