큰 HTML 테이블을 인쇄 할 때 페이지 나누기를 처리하는 방법


261

많은 행이있는 HTML 테이블을 인쇄 해야하는 프로젝트가 있습니다.

내 문제는 테이블이 여러 페이지에 인쇄되는 방식입니다. 때로는 행을 반으로 잘라서 절반이 페이지의 가장자리에 있고 나머지는 다음 페이지의 맨 위에 인쇄되기 때문에 읽을 수 없습니다.

내가 생각할 수있는 유일한 그럴듯한 해결책은 테이블 대신 스택 DIV를 사용하고 필요한 경우 페이지 나누기를 강제하는 것입니다. 그러나 전체 변경을 수행하기 전에 여기에서 요청할 수 있다고 생각했습니다.


28
접선 <thead>에서 다음 CSS로 테이블에 a 를 추가하여 thead {display: table-header-group; }모든 후속 페이지에서 테이블 헤더를 인쇄하십시오 (loooooong 데이터 테이블에 유용).
데이비드는 모니카 복원

답변:


277
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
<style type="text/css">
    table { page-break-inside:auto }
    tr    { page-break-inside:avoid; page-break-after:auto }
    thead { display:table-header-group }
    tfoot { display:table-footer-group }
</style>
</head>
<body>
    <table>
        <thead>
            <tr><th>heading</th></tr>
        </thead>
        <tfoot>
            <tr><td>notes</td></tr>
        </tfoot>
        <tbody>
        <tr>
            <td>x</td>
        </tr>
        <tr>
            <td>x</td>
        </tr>
        <!-- 500 more rows -->
        <tr>
            <td>x</td>
        </tr>
    </tbody>
    </table>
</body>
</html>

18
WebKit 브라우저 (예 : Safari 및 Chrome)
Michael Haren

5
이것이 표준을 준수하는 방법이지만 현재 표준을 구현하는 유일한 브라우저는 Opera입니다. 이것은 css2의 일부이므로 구현이 없기 때문에 아무도 신경 쓰지 않기 때문에 한동안 문제가 될 수 있습니다.
pkh

16
CSS 2.1 사양은 페이지 나누기 스타일 속성이 블록 수준 요소에만 적용됨을 나타냅니다. 테이블 행의 기본 표시 모드는 table-row입니다. 불행히도 테이블 자체를 포함하여 기본적으로 테이블 요소가 블록 레벨 요소가 아닙니다.
lsuarez

2
@ SinanÜnür 그것은 요구 사항이 아니므로 의존 할 수 없으며 불행히도 내 테스트에서 웹킷이 "아마"를보고 그 이상을 무시한 것을 볼 수 있습니다. 이상하게도 IE는 훌륭한 테이블 인쇄 기능을 제공합니다. 어느 시점에서나 그 찬양을 부르겠다고 생각하지 않았습니다.
lsuarez

6
Chrome 또는 다른 웹킷 브라우저 (예 : Safari, Opera)에서는 제대로 작동하지 않는다는 것을 확인할 수 있습니다. 나는 대부분의 사람들이 원하는 것은 머리글과 바닥 글 및 행 사이의 페이지 나누기 만 허용하는 테이블을 실행하는 것이라고 생각합니다 .2015 / 11 / 13 기준으로 Webkit에서는 구현되지 않습니다.
DoctorDestructo

47

참고 : 태그에 대해 page-break-after : always를 사용하면 테이블의 마지막 비트 다음에 페이지 나누기가 생성되어 매번 끝에 완전히 빈 페이지가 생성됩니다! 이 문제를 해결하려면 page-break-after : auto로 변경하십시오. 제대로 중단되고 빈 페이지가 추가로 생성되지 않습니다.

<html>
<head>
<style>
@media print
{
  table { page-break-after:auto }
  tr    { page-break-inside:avoid; page-break-after:auto }
  td    { page-break-inside:avoid; page-break-after:auto }
  thead { display:table-header-group }
  tfoot { display:table-footer-group }
}
</style>
</head>

<body>
....
</body>
</html>

Chrome에서 나를 위해 작동하며 멋진 일반 CSS 솔루션입니다.
Ryan

1
같은 솔루션을 시도하고 있지만 다음 페이지에 테이블 데이터를 표시하는 대신 테이블 데이터를 중단하지 않고 추가 데이터를 사라지지 않습니다. 어떤 추측?
널 포인터

24

Sinan Ünür 솔루션에서 확장 :

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
<style type="text/css">
    table { page-break-inside:auto }
    div   { page-break-inside:avoid; } /* This is the key */
    thead { display:table-header-group }
    tfoot { display:table-footer-group }
</style>
</head>
<body>
    <table>
        <thead>
            <tr><th>heading</th></tr>
        </thead>
        <tfoot>
            <tr><td>notes</td></tr>
        </tfoot>
        <tr>
            <td><div>Long<br />cell<br />should'nt<br />be<br />cut</div></td>
        </tr>
        <tr>
            <td><div>Long<br />cell<br />should'nt<br />be<br />cut</div></td>
        </tr>
        <!-- 500 more rows -->
        <tr>
            <td>x</td>
        </tr>
    </tbody>
    </table>
</body>
</html>

page-break-inside:avoid일부 브라우저에서는 셀, 테이블, 행이 아닌 인라인 블록이 아닌 블록 요소에 대해서만 고려되는 것으로 보입니다 .

당신이하려고하면 태그, 거기에 사용 , 그것은 당신의 테이블 레이아웃 주위 작동하지만 놨.display:blockTRpage-break-inside:avoid


2
jquery를 사용하여 div를 동적으로 추가하는 쉬운 방법은 다음과 같습니다.$(document).ready(function(){$("table tbody th, table tbody td").wrapInner("<div></div>");});
Chris Bloom

1
sinan ürün, vicenteherrera 및 Chrisbloom7에게 감사합니다. 귀하의 답변을 조합하여 적용했으며 이제는 작동합니다!
Nurhak Kaya

tr { display: block; }불필요한 <div>요소를 모두 추가하는 대신 @media CSS를 인쇄 전용으로 설정해보십시오 . (테스트를 거치지 않았지만 살펴볼 가치가 있음)
Stephen R

11

여기에 대한 답변 중 어느 것도 Chrome에서 효과가 없었습니다. GitHub의 AAverin 은이 목적을 위해 유용한 자바 스크립트를 만들었 으며 이것은 나를 위해 일했습니다.

js를 코드에 추가하고 클래스 'splitForPrint'를 테이블에 추가하면 테이블을 여러 페이지로 깔끔하게 분할하고 각 페이지에 테이블 헤더를 추가 할 수 있습니다.


이것을 적용하는 방법에 대한 샘플이 있습니까? className을 테이블로 할당하려고 splitForPrint했지만 JS에는 className을 사용하여 요소의 참조를 얻지 못했습니다 splitForPrint. var splitClassName = 'splitForPrint';하지만 그 부분 만 있습니다.
Compaq LE2202x 3

링크 한 스크립트가 체리 따기와 재구성을 많이하지 않으면 서 OP의 문제를 해결하지 못하여 어떻게 진행되는지에 대한 예를 제공하지 않았기 때문에 투표에 실패했습니다.
Chris Bloom

나를 위해 매력처럼 일했지만 다른 솔루션은 작동하지 않았습니다. +1 올바른 휴식을 취하기 위해 약간의 CSS를 추가해야했습니다. .page-break {page-break-after : always; }
fhugas

.page-break {page-break-after :를 추가하면 항상; } 내 하루를 구했다!
milodky

7

다음 CSS 속성을 사용하십시오.

page-break-after

page-break-before 

예를 들어 :

<html>
<head>
<style>
@media print
{
table {page-break-after:always}
}
</style>
</head>

<body>
....
</body>
</html>

통하다


잘 모르겠습니다. 확인해야합니다. 그렇지 않은 경우 다른 배열로 분할하고 빈 div로 배열을 분리하십시오
marcgg

테이블 행이나 셀에는 적용해야하지만 테이블에는 적용하지 않아야한다고 생각합니다. 그 외에는 작동해야합니다.
Pekka

2
크롬에서는 작동하지 않습니다. TR
ladieu에

5

최근 에이 문제를 좋은 해결책으로 해결했습니다.

CSS :

.avoidBreak { 
    border: 2px solid;
    page-break-inside:avoid;
}

JS :

function Print(){
    $(".tableToPrint td, .tableToPrint th").each(function(){ $(this).css("width",  $(this).width() + "px")  });
    $(".tableToPrint tr").wrap("<div class='avoidBreak'></div>");
    window.print();
}

매력처럼 작동합니다!


2

@vicenteherrera의 접근 방식을 따르고 약간의 조정 (부트 스트랩 3에 따라 다름)이 발생했습니다.

원래; 블록 레벨 요소가 아니기 때문에 trs 또는 tds를 깰 수 없습니다 . 따라서 우리는 div각각 에을 포함 시키고에 대한 page-break-*규칙을 적용 합니다 div. 둘째로; 스타일링 아티팩트를 보완하기 위해 각 div 상단에 패딩을 추가합니다.

<style>
    @media print {
        /* avoid cutting tr's in half */
        th div, td div {
            margin-top:-8px;
            padding-top:8px;
            page-break-inside:avoid;
        }
    }
</style>
<script>
    $(document).ready(function(){
        // Wrap each tr and td's content within a div
        // (todo: add logic so we only do this when printing)
        $("table tbody th, table tbody td").wrapInner("<div></div>");
    })
</script>

여백과 패딩 조정은 (부스트 스트랩에서 추측 한) 일종의 지터를 상쇄시키기 위해 필요했습니다. 이 질문에 대한 다른 답변의 새로운 솔루션을 제시하고 있는지 확실하지 않지만 이것이 누군가에게 도움이 될 것이라고 생각합니다.


1

나는 같은 문제에 직면하여 모든 곳에서 해결책을 찾았다. 마지막으로 모든 브라우저에서 나에게 도움이되는 것을 잊었다.

html {
height: 0;
}

이 CSS를 사용하거나 CSS 대신 에이 자바 스크립트를 가질 수 있습니다

$("html").height(0);

이것이 당신에게도 효과가 있기를 바랍니다.


0

많은 솔루션을 확인했지만 아무도 잘 작동하지 않았습니다.

그래서 작은 트릭을 시도하고 작동합니다.

스타일을 가진 tfoot :position: fixed; bottom: 0px; 은 마지막 페이지의 맨 아래에 배치되지만 바닥 글이 너무 높으면 테이블 내용과 겹칩니다.

풋풋 만 : display: table-footer-group; 겹치지 않지만 마지막 페이지의 맨 아래에는 없습니다 ...

두 발을 넣어 보자.

TFOOT.placer {
  display: table-footer-group;
  height: 130px;
}

TFOOT.contenter {
  display: table-footer-group;
  position: fixed;
  bottom: 0px;	
  height: 130px;
}
<TFOOT  class='placer'> 
  <TR>
    <TD>
      <!--  empty here
-->
    </TD>
  </TR>
</TFOOT>	
<TFOOT  class='contenter'> 
  <TR>
    <TD>
      your long text or high image here
    </TD>
  </TR>
</TFOOT>

하나는 마지막이 아닌 페이지에 예약하고 두 번째는 실제 바닥 글에 넣습니다.


-1

위의 모든 제안을 시도한 결과이 문제에 대한 간단하고 작동하는 크로스 브라우저 솔루션을 찾았습니다. 이 솔루션에 필요한 스타일이나 페이지 나누기가 없습니다. 솔루션의 경우 테이블 형식은 다음과 같아야합니다.

<table>
    <thead>  <!-- there should be <thead> tag-->
        <td>Heading</td> <!--//inside <thead> should be <td> it should not be <th>-->
    </thead>
    <tbody><!---<tbody>also must-->
        <tr>
            <td>data</td>
        </tr>
        <!--100 more rows-->
    </tbody>
</table>

크로스 브라우저에서 테스트되고 작동하는 위의 형식


-2

Well Guys ... 여기에있는 대부분의 솔루션은 효과가 없었습니다. 이것이 제가 일하는 방식입니다 ..

HTML

<table>
  <thead>
   <tr>
     <th style="border:none;height:26px;"></th>
     <th style="border:none;height:26px;"></th>
     .
     .
   </tr>
   <tr>
     <th style="border:1px solid black">ABC</th>
     <th style="border:1px solid black">ABC</th>
     .
     .
   <tr>
  </thead>
<tbody>

    //YOUR CODE

</tbody>
</table>

첫 번째 헤드 세트는 더미 헤드로 사용되므로 페이지 나누기 중에 두 번째 헤드 (예 : 원래 헤드)에 위쪽 테두리가 누락되지 않습니다.


-3

수락 된 답변이 모든 브라우저에서 나에게 도움이되지는 않았지만 다음 CSS는 나를 위해 일했습니다.

tr    
{ 
  display: table-row-group;
  page-break-inside:avoid; 
  page-break-after:auto;
}

html 구조는 다음과 같습니다.

<table>
  <thead>
    <tr></tr>
  </thead>
  <tbody>
    <tr></tr>
    <tr></tr>
    ...
  </tbody>
</table>

필자의 경우와 관련하여 몇 가지 추가 문제가 thead tr있었지만 테이블 행이 끊어지지 않는 원래 문제가 해결되었습니다.

헤더 문제로 인해 결국 다음과 같이 끝났습니다.

#theTable td *
{
  page-break-inside:avoid;
}

이것은 행이 깨지는 것을 막지 못했습니다. 각 셀의 내용 만

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.