Estoy generando un informe en pdf desde una página html con una tabla .
Estoy usando wkhtmltopdf para este propósito.
cuando se genera pdf, se rompe en cualquier lugar de la etiqueta tr .
Quiero evitarlo.
Estoy generando un informe en pdf desde una página html con una tabla .
Estoy usando wkhtmltopdf para este propósito.
cuando se genera pdf, se rompe en cualquier lugar de la etiqueta tr .
Quiero evitarlo.
Respuestas:
Actualización 17.09.2015: Verifique la versión que está utilizando: se dice que wkhtmltopdf 0.12.2.4 soluciona el problema (no lo he verificado) .
Este es un problema conocido en wkhtmltopdf. El algoritmo de salto de página utilizado por webkit (el WK en WKhtmltopdf) no funciona realmente bien para tablas grandes. Sugiero dividir la tabla en partes más pequeñas que se dividen más fácilmente en páginas y usar mucho el CSS:
table, tr, td, th, tbody, thead, tfoot {
page-break-inside: avoid !important;
}
También eche un vistazo a los siguientes problemas de wkhtmltopdf, tienen comentarios interesantes que discuten, por ejemplo, el problema de división de tablas. Hay una solución JS que divide las tablas programáticamente en 168 que podría ayudarlo (aunque no la uso).
Actualización 08.11.2013
Hay mucha discusión sobre esto en el número 168 vinculado anteriormente. Alguien ha logrado compilar una versión de wkhtmltopdf que admite una mejor división de tablas, pero desafortunadamente parece que no se lanzó oficialmente y podría contener otros errores. No sé cómo obtenerlo y no sé cómo compilar en Windows, pero cualquier persona interesada puede consultar, por ejemplo, el comentario aquí. (ver nueva actualización a continuación).
Actualización 24.02.2014 Le complacerá saber que en wkhtmltopdf 0.12 esta función, entre otras, se ha mejorado considerablemente. Sin embargo, espere 0.12.1 y pruebe a fondo antes de comenzar a usar cualquier versión nueva, todavía es un poco inestable, aunque los nuevos chicos que están trabajando con antialize están haciendo un gran trabajo (ashkulz rocks). Manténgase actualizado en wkhtmltopdf.org y github . El sitio de código de Google está obsoleto y se está migrando lentamente.
display: inline-block
. ¡Lo cambié a block
y el con los cambios encima de todo comenzó a funcionar!
Es una publicación antigua, pero como estaba perdiendo mucho tiempo tratando de encontrar una solución adecuada, la pondré aquí, tal vez sea útil para alguien.
Entonces, por lo que leí, el problema con
page-break-inside: avoid
es que no funciona. Pero en realidad, si lo configura en un elemento que tiene display:block
, funciona como se esperaba (como se indica en algún lugar de SO). así que para una estructura simple de la tabla css con
td div, th div{
page-break-inside: avoid;
}
y estructura de la mesa
<table>
....
<tr>
<td><div>some text</div></td>
<td><div>more text</div></td>
</tr>
....
</table>
funcionará como se esperaba.
Tenía un caso un poco más complicado con los intervalos de filas, por lo que la solución de arriba fue romperlo en pedazos, lo que no era el efecto deseado. Lo resolví usando divs para cada conjunto de líneas en filas. Mi jquery js hace todo el trabajo:
$(window).load(function () {
var sizes = {};
$('#the_table tr:first th').each(function (a, td) {
var w = $(td).width();
if (sizes.hasOwnProperty('' + a)) {
if (sizes['' + a] < w)
sizes['' + a] = w;
}
else {
sizes['' + a] = w;
}
});
var tableClone = $('#the_table').clone();
$('#the_table').replaceWith('<div class="container"></div>');
var curentDivTable;
var cDiv = $('.container');
tableClone.find('tr').each(function (i, ln) {
var line = $(ln);
if (line.hasClass('main_row')) {
var div = $('<div class="new-section"><table><tbody>')
currentDivTable = div.find('tbody');
cDiv.append(div);
}
currentDivTable.append(line);
});
//optional - maybe in % its better than px
var sum = 0;
$.each(sizes, function (a, b) {
sum += b;
});
var widths = {};
$.each(sizes, function (a, b) {
var p = Math.ceil(b * 100 / sum);
widths['' + a] = p + '%';
});
//setup
$('.container table').each(function (a, tbl) {
$(tbl).find('tr:first td, tr:first th').each(function (b, td) {
$(td).width(widths['' + b]);
});
$(tbl).addClass('fixed');
});
});
css:
div.new-section {
page-break-inside: avoid;
}
.container, .new-section, .new-section table.fixed{
width: 100%;
}
.new-section table.fixed{
table-layout:fixed;
}
No sé si todo es necesario y no creo que sea perfecto, pero funciona. Probado solo en cromo
Desde 0.12, este problema se ha resuelto pero, a veces, cuando una tabla es demasiado larga para caber en la página, wkhtmltopdf la divide en dos partes y repite los encabezados de columna en la nueva página y estos encabezados de columna aparecen superpuestos a la primera fila.
Encontré una solución temporal a este problema en la sección de problemas de github wkhtmltopdf: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2531
Simplemente agregue estas líneas a su vista css:
tr {
page-break-inside: avoid;
}
He investigado estos problemas durante días y finalmente encontré la solución perfecta. Puede hacer referencia a este proyecto phpwkhtmltopdf . Busque en el directorio article
y encontrará 3 soluciones para 3 problemas. En resumen, la solución definitiva es agregar el estilo CSS
thead {
display: table-row-group;
}
tr {
page-break-before: always;
page-break-after: always;
page-break-inside: avoid;
}
table {
word-wrap: break-word;
}
table td {
word-break: break-all;
}
Si es chino, no dude en consultar este sitio关于 wkhtmltopdf , 你 一定 想 知道 这些 Consulte la esencia si desea la esencia de wkhtmltopdf
Descubrí que wkhtmltopdf 0.12.2.1 en adelante ha solucionado este problema.
En mi caso particular, por alguna razón, ninguna de las respuestas anteriores funcionó para mí. Lo que terminó funcionando fue en realidad una combinación de varias cosas.
Instalé (en Ubuntu 16.04) el contenedor de python Wkhtmltopdf llamado pdfkit usando pip3, y luego, en lugar de instalar Wkhtmltopdf a través de apt-get, instalé el binario estático (versión 0.12.3) siguiendo el siguiente script, tomado de aquí
#!/bin/sh
sudo apt-get install -y openssl build-essential xorg libssl-dev
wget http://download.gna.org/wkhtmltopdf/0.12/0.12.3/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
tar -xJf wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
cd wkhtmltox
sudo chown root:root bin/wkhtmltopdf
sudo cp -r * /usr/
Se agregó este CSS (como se sugiere en una de las respuestas aquí):
tr, td div, th div{
page-break-inside: avoid;
}
Y luego también agregue etiquetas <thead>
y <tbody>
como se sugiere aquí también (sin estas, la tabla aún se rompería de una manera fea):
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
</tr>
</thead>
<tbody>
<tr>
<td>Value 1</td>
<td>Value 2</td>
</tr>
</tbody>
</table>
Con estas modificaciones, ahora puedo usar con éxito las plantillas de Mako para generar el HTML y luego enviarlo a Wkhtmltopdf y obtener un PDF bellamente paginado.
Intenté todo tipo de manipulaciones en mis tablas, pero nada de lo que intenté pudo evitar que los saltos de página se colocaran en el medio de una fila. Desesperado, probé diferentes versiones y encontré lo siguiente:
Wkhtmltopdf 0.12.2.1: Malo
Wkhtmltopdf 0.12.3: Malo
Wkhtmltopdf 0.12.1: Bueno
Mi solución fue cambiar a la versión 0.12.1, que resolvió mis problemas. Por supuesto, es posible que se hayan debido en parte a que no soy un super TOC con mi html, pero como el HTML se genera dentro de TinyMCE (por los usuarios), realmente no tengo muchas opciones.
Además, las tablas anidadas no funcionan en ninguna versión para mí.
¿Cómo usar saltos de página dentro de PDF sin romper un tr?
Aquí hay una solución que puede usar en cualquier archivo html .....
Después de iniciar su tr, debe tomar un div dentro del tr y darle este css al div:
<tr>
<div style="page-break-inside:avoid !important; page-break-after:auto !important; overflow: hidden; display:block !important; width:100% ">
</tr>
Estaba enfrentando el mismo problema, agregue después de muchas pruebas y errores, este css resolvió el problema
tr {
display: inline-table;
}
Con la adición de lo que dice Nanotelep, aquí está la implementación de trabajo del algoritmo de división de página de tabla manual. https://github.com/AAverin/JSUtils/tree/master/wkhtmltopdfTableSplitHack
Las respuestas anteriores no me funcionaron. Tuve que deshabilitar específicamente la opción de zoom en mi configuración de pdfkit.
PDFKit.configure do |config|
config.default_options = {
print_media_type: false,
page_size: "A4",
encoding: "UTF-8",
## Make sure the zoom option is not enabled!
## zoom: '1.3',
disable_smart_shrinking: false,
footer_right: "Page [page] of [toPage]"
}
end
Para cualquiera que todavía tenga problemas con esto, una cosa para recordar es que la tabla tiene que ser un hijo directo de body , de lo contrario el CSS no funcionará (al menos eso es lo que me pasó a mí).
display: table-cell;
aplicado. Hacer esos estilos @media only screen
corrigió los saltos de página. Si no puede hacer que los saltos de página funcionen, intente dividir y conquistar eliminando la mitad del CSS en etapas y ver si funciona.
Otra opción: coloque cada uno tr
por su cuenta tbody
y luego aplique las reglas css de ruptura de paginación al archivo tbody
. Las tablas admiten varios tbody
s.
Un poco de marcado adicional, pero funciona decentemente para mí.
Resolví el problema usando una combinación de algunas soluciones sugeridas.
Envolví mi tabla en un div y definí el siguiente CSS.
.wrapping-div {
display: block;
page-break-inside: avoid !important;
}
.wrapping-div table, .wrapping-div tbody, .wrapping-div tr, .wrapping-div td, .wrapping-div th {
page-break-inside: avoid !important;
}
La estructura de la tabla cuando terminó se definió como el siguiente ejemplo:
<div class="wrapping-div">
<table>
<tbody>
<tr>
<th>
header
</th>
<td>
content
</td>
</tr>
</tbody>
</table>
</div>
No necesitaba crear ningún div dentro de las etiquetas td o th.
Cosas importantes que noté al intentar resolver el problema:
Espero que esto ayude.
He luchado mucho con el problema, usando la última versión 0.12.4 de h4cc / wkhtmltopdf-amd64 y finalmente lo hice funcionar al degradar la versión del paquete a 0.12.3
!
Para evitar el salto de página, podemos usar la opción de evitar el salto de página de CSS.
tr { page-break-inside: avoid; }
Divida cualquier contenido (imagen / texto) y haga que aparezca en la página siguiente
.sample-image { page-break-before: always; }
¿Tienes una cabecera de mesa? y un cuerpo de mesa?
<table>
<tbody>
<tr><th>Name</th><th>Value</th></tr>
<tr><td>url</td><td>stackoverflow.com</td></tr>
<tr><td>ip</td><td>123.123.123.123</td></tr>
</tbody>
</table>
Ese es el formato adecuado de una tabla, mientras que a la mayoría de los navegadores no les importa, convertidores como el que mencionas sí, si faltan etiquetas <tbody>
o <th>
etiquetas, te sugiero que intentes agregarlas primero.