web-dev-qa-db-ja.com

大きなHTMLテーブルを印刷するときに改ページを処理する方法

私は多くの行を持つHTMLテーブルを印刷する必要があるプロジェクトがあります。

私の問題は、表が複数ページにわたって印刷される方法です。半分はページのにじみが出て、残りは次のページの上に印刷されるため、行が半分になって判読できないことがあります。

私が考えることができる唯一のもっともらしい解決策は、テーブルの代わりに積み重ねられたDIVを使い、必要なら改ページを強制することです。

247
h3.
<!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>
261
Sinan Ünür

注意:常にpage-break-after:タグを使用する場合、テーブルの最後のビットの後に改ページが作成され、毎回最後に空白のページが作成されます。これを修正するには、単に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>
41
Josh P

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はブロック要素に対してのみ考慮され、セル、テーブル、行に対してもインラインブロックに対しても考慮されていないようです。

TRタグをdisplay:blockタグに使用し、そこでpage-break-inside:avoidタグを使用すると、うまくいきますが、テーブルのレイアウトがめちゃくちゃになります。

20
vicenteherrera

ここでの答えのどれもChromeで私のために働きませんでした。 GitHubのAAverinはこの目的のために 便利なJavascriptを作成しました そしてこれは私のために働きました:

コードにjsを追加して、テーブルにクラス 'splitForPrint'を追加するだけで、テーブルが複数のページにきちんと分割され、各ページにテーブルヘッダーが追加されます。

9
MDave

これらのCSSプロパティを使用してください。

page-break-after

page-break-before 

例えば:

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

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

via

6
marcgg

私は最近この問題を良い解決策で解決しました。

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();
}

魅力のように動作します!

4
Wendel Tavares

私は同じ問題に直面し、どこでも解決策を探しました。最後に、私はすべてのブラウザーで機能する何かを思いつきました。

html {
height: 0;
}

このCSSを使用するか、CSSの代わりにこのJavaScriptを使用できます

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

これがあなたにも役立つことを願っています。

1
Jay

私は@ vicenteherreraのアプローチに従って、いくつかの調整を加えました(それはおそらくブートストラップ3特有のものです)。

基本的に; trsやtdsはブロックレベルの要素ではないので、分割することはできません。そのため、それぞれにdivsを埋め込み、divに対してpage-break-*の規則を適用します。第二に。スタイリングアーティファクトを補正するために、これらの各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
Aaron

私は多くの解決策をチェックしました、そして誰もがうまくいっていませんでした。

だから私は小さなトリックを試してみました、それはうまくいきます:

tfoot with style:position: fixed; bottom: 0px;は最後のページの一番下に配置されますが、フッターが高すぎるとtableの内容と重なってしまいます。

display: table-footer-group;はオーバーラップしていませんが、最後のページの一番下にはありません。

2つのtfootを置いてみましょう:

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つは最後以外のページに配置され、2つ目はあなたの実際のフッターに配置されます。

0
Zenon K.