evite quebra de página dentro da linha da tabela

97

Quero evitar a quebra de página dentro da linha da tabela em html, quando converter html para PDF por wkhtmltopdf. Eu uso a quebra de página dentro: evitar com tabela - funciona, mas eu tenho tantas linhas, então não funciona. Se definir a exibição de tr como bloco ou alguma outra coisa, ele muda a formatação da tabela e insere borda dupla. Ou é possível inserir o cabeçalho da tabela em cada página, onde a tabela foi dividida.

Ankit Mittal
fonte
1
Desculpe, qual é o problema ao usar page-break-inside: avoid;?
Christian de
2
@ChristianVarga quando eu uso a quebra de página dentro: evitar com tr, não funciona
Ankit Mittal
1
A quebra de página com tabelas é bastante problemática. Dê uma olhada nesta solução alternativa de JavaScript code.google.com/p/wkhtmltopdf/issues/detail?id=168#c4
Jona
2
na verdade, tentei page-break-inside:avoidcom todos os elementos da tabela como tr td, mas não funcionou.
Ankit Mittal
3
Sim, Google para WebGL, javascript rápido cegante, cliente nativo portátil, mas ainda não podemos imprimir tabelas de dados. Quem precisaria fazer isso ??? Quase todas as empresas do mundo. A propósito, eu tentei imprimir uma planilha no Google Docs agora mesmo, e travava constantemente meu Chrome. Acho que o Google Docs imprime via pdf. : /
Sam Watkins

Respostas:

74

Você pode tentar isso com CSS:

<table class="print-friendly">
 <!-- The rest of your table here -->
</table>

<style>
    table.print-friendly tr td, table.print-friendly tr th {
        page-break-inside: avoid;
    }
</style>

A maioria das regras CSS não se aplicam a <tr>tags diretamente, exatamente por causa do que você apontou acima - elas têm um displayestilo único , que não permite essas regras CSS. No entanto, o <td>e <th>marcas dentro deles normalmente fazer permitir que este tipo de especificação - e você pode facilmente aplicar tais regras a ALL criança- <tr>"s e <td>está usando CSS como mostrado acima.

Troy Alford
fonte
18
Infelizmente, isso (ainda) não funciona com navegadores baseados em webkit.
Attila Fulop
2
Sim - existem algumas esquisitices. Veja a resposta de @Peter nesta questão: stackoverflow.com/questions/7706504/… para mais informações.
Troy Alford
3
Só funciona se você pegar a mesa inteira, não apenas tr / td: stackoverflow.com/a/13525758/729324
marcovtwout
1
Eu tive problemas com isso no IE8, possivelmente em outros, onde faz com que a tabela inteira tente caber em uma página e elimina qualquer estouro. Ele também parecia ignorar a opção "dimensionar para ajustar" para essas tabelas.
Tom Pietrosanti
6
@AttilaFulop Ainda? Sua postagem tem 3 anos e ainda não consigo fazê-la funcionar. Obrigado
relipse
32

A melhor maneira que encontrei de lidar com esse problema em navegadores webkit é colocar um div dentro de cada elemento td e aplicar o estilo de quebra de página: evitar ao div, como este:

...
<td>
  <div class="avoid">
    Cell content.
  </div>
</td>
...
<style type="text/css">
  .avoid {
    page-break-inside: avoid !important;
    margin: 4px 0 4px 0;  /* to keep the page break from cutting too close to the text in the div */
  }
</style>

Mesmo que o Chrome supostamente não reconheça o 'quebra de página dentro: evitar;' , isso parece evitar que o conteúdo da linha seja dividido ao meio por uma quebra de página ao usar wktohtml para gerar PDFs. O elemento tr pode pairar um pouco sobre a quebra de página, mas o div e qualquer coisa dentro dele não.

Aaron Hill
fonte
Isso margin: 4px 0 4px 0;funcionou para mim, eu estava perdendo um recorde ocasionalmente. Obrigado
Wartodust
Um problema com essa abordagem é que às vezes apenas algumas células de uma linha são quebradas para a próxima página, embora cada célula sozinha não seja quebrada.
WorldSEnder
@WorldSEnder Sim. Você encontrou uma solução alternativa para isso?
ranjansaga
4
Não funciona. Nada funciona. Tentei todas as "soluções" na internet e não há solução. Só temos que aceitar um software de merda que nem consegue renderizar uma tabela.
Niklas R.
17

Eu usei o truque 4px de @AaronHill acima ( link ) e funcionou muito bem! Usei embora uma regra de css mais simples sem precisar adicionar uma classe a cada <td>na tabela.

@media print {
    table tbody tr td:before,
    table tbody tr td:after {
        content : "" ;
        height : 4px ;
        display : block ;
    }
}
fídias
fonte
10

Eu encontrei uma nova maneira de resolver este problema, pelo menos para mim (Chrome versão 63.0.3239.84 (versão oficial) (64 bits) no MacOS Sierra)

Adicione uma regra CSS à tabela pai:

table{
    border-collapse:collapse;
}

e para o td:

tr td{
    page-break-inside: avoid;
    white-space: nowrap;
}

Na verdade, encontrei essa solução no Stack Overflow, mas ela não apareceu nas pesquisas iniciais do Google: CSS para interromper a quebra de página dentro da linha da tabela

Parabéns a @ Ibrennan208 por resolver o problema!

Jason Silver
fonte
seu problema resolvido de corte de linha de mesa, seu projeto de quebra de outro
aviboy2006,
9

O uso de quebra de página CSS não funcionará (esse é um problema do navegador do webkit).

Há um hack wkhtmltopdf de divisão de tabela JavaScript que divide uma tabela longa em tabelas menores automaticamente, dependendo do tamanho da página que você especificar (em vez de quebrar a página após um valor estático de x linhas): https://gist.github.com/3683510

Richard Pursehouse
fonte
Este hack js funcionará se eu quiser apenas imprimir a página da web sem wkhtmltopdf?
120196
Este é o único que funcionou para mim. Também funciona com a biblioteca HTML-PDF.
gilbert-v
8

Escrevi o seguinte JavaScript com base na resposta de Aaron Hill:

//Add a div to each table cell so these don't break across pages when printed
//See http://stackoverflow.com/a/17982110/201648
$(document).ready(function () {
    var ctlTd = $('.dontSplit td');
    if (ctlTd.length > 0)
    {
        //console.log('Found ctlTd');
        ctlTd.wrapInner('<div class="avoidBreak" />');
    }
});

Onde dontSplit é a classe da tabela em que você não deseja que o td seja dividido entre as páginas. Use-o com o seguinte CSS (novamente, atribuído a Aaron Hill):

 .avoidBreak {
    page-break-inside: avoid !important;
    margin: 4px 0 4px 0;  /* to keep the page break from cutting too close to the text in the div */
  }

Isso parece estar funcionando bem na versão mais recente do Chrome.

Aaron Newton
fonte
1
Estou renderizando grandes tabelas em formato PDF usando wkhtmltopdf, e esta é a única solução que produziu resultados aceitáveis. Poderia ser melhor (o Webkit não repete as bordas das células após uma quebra de página), mas pelo menos o conteúdo está lá. Obrigado!
Jonathon Hill
7

A única maneira que descobri de funcionar foi colocar cada elemento TR dentro de seu próprio elemento TBODY e aplicar as regras de quebra de página ao elemento TBODY via css

Troy Morehouse
fonte
1
Isso funciona melhor do que o resto para mim no Chromium versão 40.0.2214.111 (64 bits) no Arch Linux. É feio e parece hacky - mas aparentemente vários tbodyelementos são válidos dentro de table stackoverflow.com/questions/3076708/…
ElDog
Isso não funciona para mim (Chrome 56.0.2924.87 (64 bits), Mac OS 10.12.2).
Nhat Dinh de
4

Tente com

white-space: nowrap; 

estilo a td para evitar que se quebre em novas linhas.

vinayakshukre
fonte
1
Muito mais simples do que as outras soluções. Isso é algo novo?
bendecko
3

Descobri que page-break-inside: avoidisso não funcionará se algum dos elementos pais da tabela for display: inline-blockou flex. Certifique-se de que todos os elementos pais sejam display: block.

Considere também substituindo table, tr, td's displayestilos com CSS gridpara o layout de impressão se você continuar a ter problemas com a mesa.

Stephen Saucier
fonte
2

A solução 2020

A única coisa que consegui trabalhar de forma consistente em todos os navegadores é colocar cada linha dentro de seu próprio elemento de tabela . Isso também funciona com o nó HTML-PDF. Em seguida, defina tudo como page-break-inside: avoid.

table,
tr,
td,
div {
    page-break-inside: avoid;
}

A única desvantagem disso é que você deve definir manualmente a largura das colunas, caso contrário, parecerá um tanto estranho. O seguinte funcionou bem para mim com duas colunas.

td:first-child { width: 30% }
td:last-child { width: 70% }
Gilbert-v
fonte
Você poderia fornecer um exemplo de HTML de tabela? Obrigado.
PavanBhushan