Carlos Andrés hace 6 años
Generar PDF desde un HTML JAVA
Solicito una ayuda por parte de ustedes debido a que tengo un inconveniente para realizar una conversión de un `html`, los contextualizo:
Estoy usando una librería `HTTPClient`, estoy navegando y consumiendo una web por medio `POST`, esta web me retorna un `html` con sus estilos incrustados `inline` y en la estiqueta `HEAD` y debo de respetar los estilos e imprimirla tal cual me la retorna, los inconvenientes presentados es que el `html` no tiene las etiquetas bien cerradas, adicional a esto el `html` esta todo diseñado con tablas y porcentajes para los tamaños y cuando la exporto con `itext` todo se descuadra, cuando lo voy a convertir a `PDF` me generar un error de conversion y adicional a esto debo de unir varias paginas según el tamaño de la pagina es decir: si es pequeño le debo adicionar una hoja en blanco, si es muy grande lo imprimo en varias hojas.
Teniendo esta situación, no se si solucionarlo en el `backend` o en el `frontend`, me pueden aconsejar por favor como podria solucionarlo y que `librerías` podria usar.
Responder 6 respuestas
Que tal Carlos, muy buenas tardes.
**Comprendo perfectamente el calvario por el que estás pasando al pasar código HTML a PDF** y eso precisamente pasa porque los *parsers* normalmente no "respetan" todos los estilos como el navegador web lo hace.
Aquí hay algo importante que hay que comentarles a nuestros clientes (usuarios); **un PDF va a tener muchas más restricciones que el contenido que se ve en una página de internet**.
Aquí te pongo varias cosas que en PDF no van a funcionar o que tienen restricciones:
1. Estilos porcentuales en tamaños de columnas de tablas
2. Para las tablas, en el caso de PDF normalmente los bordes se tiene que especificar a nivel de atributo `style`
Es decir, en lugar de:
```
<table border="0"></table>
```
Se debe poner:
```
<td style="border:0">...</td>
```
3. Se recomienda establecer un **CSS por defecto**; en iText puedes especificar un CSS inicial (normalmente este CSS se guarda como texto en un archivo `config-app.properties`)
```
h2{font-size:17.0f;}
h3{font-size:15.0f;}
p {font-size: 14px;margin-bottom:10px;}
table {width:100%;}
td {font-size: 12px;padding:10px;}
tr {font-size: 12px;padding:0px;}
ol, ul {font-size: 14px;margin: 10px 0;}
ul ul,ul ol,ol ul,ol ol {margin-top: 0;margin-bottom: 0;}
img {margin:0;} td p img {margin-right:10px;}
h2{font-size:17.0f;}
h3{font-size:15.0f;}
p {font-size: 14px;margin-bottom:10px;}
table {width:100%;}
td {font-size: 12px;padding:4px;}
tr {}
ol, ul {font-size: 14px;margin: 10px 0;}
ul ul,ul ol,ol ul,ol ol {margin-top: 0;margin-bottom: 0;}
img {margin:0;}
td p img {margin-right:10px;}
```
Por ejemplo una llave con valor en un archivo `config-app.properties` podría verse así:
```
defaultCSS=h2{font-size:17.0f;} h3{font-size:15.0f;} p {font-size: 14px;margin-bottom:10px;} table {width:100%;} td {font-size: 12px;padding:4px;} tr {} ol, ul {font-size: 14px;margin: 10px 0;} ul ul,ul ol,ol ul,ol ol {margin-top: 0;margin-bottom: 0;} img {margin:0;} td p img {margin-right:10px;}
```
4. En la versión 7 de iText hubo muchas mejoras, mira aquí hay varios ejemplos [itext-7-converting-html-pdf-pdfhtml / chapter-2-defining-styles-css](https://developers.itextpdf.com/content/itext-7-converting-html-pdf-pdfhtml/chapter-2-defining-styles-css)
Saludos.
Además de lo anterior, una biblioteca que te puede ayudar mucho a "corregir" tu HTML mal formado es [jsoup](https://jsoup.org/) que es un *HTML parser* que funciona con Java.
Incluso puede quitar código malicioso usando un [Sanitizer](https://jsoup.org/cookbook/cleaning-html/whitelist-sanitizer) que no es otra cosa más que una clase de Java que permite definir una **Whitelist** de los tags y atributos que "permites" que tu usuario pueda usar en tus documentos (incluso puedes quitar tags y atributos que el PDF no vaya a respetar).
¿Cómo ves esto te sirve?
Ahora bien, para el problema de las páginas cuando es mucho contenido, con *iText* puedes programáticamente crear tantas páginas como decidas.
De hecho se puede configurar para que automáticamente vaya agregando páginas dependiendo del contenido.
Incluso si quisieras por ejemplo algo más avanzado que se haga en partes de tu documento (por ejemplo en el footer o header), hay algo que se llaman [Page Events](https://developers.itextpdf.com/examples/page-events/page-events-headers-and-footers) con los cuales puedes personalizar con código Java lo que vayas necesitando que se repita en cada página.
Continuemos...
Con respecto al soporte de CSS en iText, aquí te dejo un link donde hay una tabla de lo que se soporta en iText 5.x y lo que no: [iText CSS Properties Support when using HTML to PDF features](https://wiki.base22.com/display/btg/iText+5+CSS+Properties+Support+when+using+HTML+to+PDF+features)
Como verás muchas propiedades NO son soportadas (por ejemplo backgrounds) o algunas propiedades de bordes.
En la versión 7 iText el soporte mejoró pero aún así es limitado.
Carlos Andrés hace 6 años...
Genial; muchísimas gracias ya logré realizar la conversión, después de mucho esfuerzo, fue mejor actualizar la versión del `iText 5` a la versión `iText 7.1.2`, la cual no me generaba tanto conflicto como la `iText 5` muy gentiles con la orientación.
Que tal Carlos,
Que bien que la versión 7 de `iText` te funcionó mejor.
Seguimos en contacto.
Por favor inicia sesión para participar en esta pregunta