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


261

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

私の問題は、表が複数ページにわたって印刷される方法です。場合によっては、行が半分にカットされ、半分がページの端にあり、残りが次のページの上部に印刷されるため、読み取れなくなります。

私が考えることができる唯一のもっともらしい解決策は、テーブルの代わりにスタックDIVを使用し、必要に応じて改ページを強制することです。しかし、全体の変更を行う前に、前にここで質問できると思いました。


28
接線で<thead>は、次のcssを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の一部であり、明らかに誰も気にしないので、実装の欠如はしばらくの間問題になる可能性があることに注意してください。
2012年

16
CSS 2.1仕様では、改ページスタイルの属性はブロックレベルの要素にのみ適用されることが示されています。テーブル行のデフォルトの表示モードはtable-rowです。残念ながら、デフォルトでは、テーブル自体を含め、テーブル要素はブロックレベル要素ではありません。
lsuarez 2012年

2
@SinanÜnürこれは必須ではないので、それに依存することはできません。残念ながら、私のテストから、webkitが「それ以上」を見て無視したことがわかります。不思議なことに、IEはかなり優れた大きなテーブル印刷サポートを備えています。どんな点でも賞賛を歌うとは思わなかった。
lsuarez

6
これがChromeやその他のWebkitブラウザ(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ソリューションです。
ライアン

1
私は同じ解決策を試していますが、次のページに表示するのではなく、テーブルデータを壊さず、余分なデータを消去しません。推測は?
Nullポインタ

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>");});
クリス・ブルーム

1
sinanürün、vicenteherrera、Chrisbloom7に感謝します。私はあなたの答えの組み合わせを適用しました、そしてそれは今うまくいきます!
Nurhak Kaya

tr { display: block; }無関係な<div>要素をすべて追加するのではなく、@ media CSSをPrint Onlyに設定してみてください。(テストはしていませんが、一見の価値があります)
Stephen R

11

ここでの答えはどれも私にとってChromeではうまくいきませんでした。GitHubのAAverinは、この目的のためにいくつかの有用なJavascriptを作成しました、これは私にとってた:

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


これを適用する方法のサンプルはありますか?テーブルclassNameを割り当てようとしましたがsplitForPrint、JSではclassNameを使用して要素の参照を取得する場所がありませんsplitForPrint。それだけの部分だけvar splitClassName = 'splitForPrint';です。
Compaq LE2202x 2014

リンクしたスクリプトはOPの問題を解決するためにかなりの選択と再構成を行わないため、反対票を投じました。
Chris Bloom

私にとって魅力のように機能しましたが、他のソリューションはどれも機能しませんでした。+1正しい改行を取得するために少しcssを追加する必要がありました。.page-break {page-break-after:always; }
フガス

はい、.page-break {page-break-after:always;を追加して }それは私の日を救った!
milodky、2016年

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
Chromeでは機能しません。TRに適用すると
2012年

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固有の可能性があります)を行いました。

基本的に; 我々は壊すことができないtrのを、またはtd彼らはブロックレベル要素ではないだからね。したがってdiv、それぞれにs を埋め込み、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の代わりにこのJavaScriptを使用できます

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

これがあなたのためにも働くことを願っています。


0

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

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

スタイルのtfoot:position: fixed; bottom: 0px; 最後のページの下部に配置されますが、フッターが高すぎると、テーブルのコンテンツと重なってしまいます。

tfootのみ: 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つ目は実際のフッターに配置されます。


-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

まあみんな...ここまでのほとんどのソリューションはうまくいきませんでした。これが私にとってはうまくいった方法です。

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>

最初のヘッドセットはダミーとして使用されるため、改ページ中に2番目のヘッド(元のヘッド)の上部の境界線が欠落することはありません。


-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.