วิธีจัดการกับตัวแบ่งหน้าเมื่อพิมพ์ตาราง HTML ขนาดใหญ่


261

ฉันมีโครงการที่ต้องพิมพ์ตาราง HTML ที่มีหลายแถว

ปัญหาของฉันคือวิธีพิมพ์ตารางในหลาย ๆ หน้า บางครั้งมันจะตัดแถวครึ่งทำให้ไม่สามารถอ่านได้เพราะครึ่งหนึ่งอยู่ที่ขอบเลือดออกของหน้ากระดาษและส่วนที่เหลือจะพิมพ์ที่ด้านบนของหน้าถัดไป

ทางออกที่เป็นไปได้เพียงอย่างเดียวที่ฉันคิดได้คือใช้ DIV แบบเรียงซ้อนแทนที่จะใช้ตารางและบังคับให้หยุดพักหน้าหากจำเป็น .. แต่ก่อนที่จะผ่านการเปลี่ยนแปลงทั้งหมดฉันคิดว่าฉันสามารถถามได้ที่นี่ก่อน


28
บนแทนเจนต์มันอาจคุ้มค่าที่จะเพิ่ม a <thead>ลงในตารางของคุณด้วย css ต่อไปนี้thead {display: table-header-group; }เพื่อพิมพ์ส่วนหัวของตารางในหน้าถัดไปทั้งหมด (มีประโยชน์สำหรับตารางข้อมูล loooooong)
David กล่าวว่าคืนสถานะโมนิก้า

คำตอบ:


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 ระบุว่าแอตทริบิวต์สไตล์ตัวแบ่งหน้าจะนำไปใช้กับองค์ประกอบระดับบล็อกเท่านั้น โหมดการแสดงผลเริ่มต้นสำหรับแถวของตารางคือแถวของตาราง น่าเสียดายที่ไม่มีองค์ประกอบของตารางเป็นองค์ประกอบระดับบล็อกตามค่าเริ่มต้นรวมถึงตัวตารางเอง
lsuarez

2
@ SinanÜnürมันไม่ใช่ข้อกำหนดดังนั้นคุณจึงไม่สามารถไว้ใจได้และน่าเสียดายที่จากการทดสอบของฉันฉันเห็นว่า webkit เห็น "อาจ" และไม่สนใจอะไรเลย น่าแปลกที่ IE นั้นรองรับการพิมพ์ตารางขนาดใหญ่ค่อนข้างดี ไม่เคยคิดว่าฉันจะร้องเพลงสรรเสริญในจุดที่กำหนด
lsuarez

6
ฉันสามารถยืนยันได้ว่านี่ใช้งานไม่ได้กับ Chrome หรือเบราว์เซอร์ Webkit อื่น ๆ (เช่น Safari, Opera) - เว้นแต่ว่าโดย "ใช้งานได้ดี" คุณหมายถึง "ไม่รวมคุณสมบัติที่ถือว่าเป็นตัวเลือก" ฉันคิดว่าสิ่งที่คนส่วนใหญ่ต้องการคือการเรียกใช้ส่วนหัวและส่วนท้ายและตารางที่อนุญาตให้มีการแบ่งหน้าระหว่างแถวเท่านั้นซึ่งไม่ได้นำมาใช้ใน Webkit ตั้งแต่ 2015/11/13
DoctorDestructo

47

หมายเหตุ: เมื่อใช้การแบ่งหน้า - หลัง: สำหรับแท็กเสมอมันจะสร้างตัวแบ่งหน้าหลังจากบิตสุดท้ายของตารางการสร้างหน้าว่างเปล่าทั้งหมดในตอนท้ายทุกครั้ง! ในการแก้ไขปัญหานี้ให้เปลี่ยนเป็น 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
ฉันกำลังพยายามแก้ปัญหาเดียวกัน แต่ไม่ทำลายข้อมูลตารางและหายไปข้อมูลเพิ่มเติมแทนที่จะแสดงในหน้าถัดไป มีเดาอะไรไหม
ตัวชี้ 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:blockใช้TRแท็กและใช้งานpage-break-inside:avoidได้จะทำงานได้ แต่ยุ่งกับเค้าโครงตารางของคุณ


2
นี่เป็นวิธีที่ง่ายต่อการเพิ่ม divs แบบไดนามิกกับ jQuery:$(document).ready(function(){$("table tbody th, table tbody td").wrapInner("<div></div>");});
คริสบลูม

1
ขอบคุณ Sinan ürün, Vicenteherrera และ Chrisbloom7 ฉันใช้การรวมกันของคำตอบของคุณและตอนนี้ใช้งานได้!
Nurhak Kaya

คุณอาจลองตั้งค่า @media CSS เป็นtr { display: block; }สำหรับพิมพ์อย่างเดียวแทนที่จะเพิ่ม<div>องค์ประกอบที่ไม่เกี่ยวข้องทั้งหมด (ยังไม่ได้ทดสอบ แต่ควรดูที่)
Stephen R

11

ไม่มีคำตอบที่นี่สำหรับฉันใน Chrome AAverin บน GitHub ได้สร้างJavascript ที่มีประโยชน์สำหรับวัตถุประสงค์นี้และสิ่งนี้ได้ผลสำหรับฉัน:

เพียงเพิ่ม js ลงในโค้ดของคุณและเพิ่มคลาส 'splitForPrint' ลงในตารางของคุณและจะแบ่งตารางออกเป็นหลายหน้าอย่างเรียบร้อยและเพิ่มส่วนหัวของตารางลงในแต่ละหน้า


คุณมีตัวอย่างเกี่ยวกับวิธีการใช้สิ่งนี้หรือไม่? ฉันได้รับการพยายามที่จะกำหนด className โต๊ะของฉันเป็นsplitForPrintแต่ใน JS มีที่ไหนเลยที่จะเอาการอ้างอิงขององค์ประกอบโดยใช้ splitForPrintclassName เฉพาะส่วนที่var splitClassName = 'splitForPrint';แต่นั่นมัน
Compaq LE2202x

ลงคะแนนเนื่องจากสคริปต์ที่คุณเชื่อมโยงไปนั้นไม่สามารถแก้ปัญหาของ OP ได้โดยไม่ต้องเก็บเชอร์รี่และตั้งค่าใหม่และคุณไม่ได้ให้ตัวอย่างใด ๆ เกี่ยวกับวิธีดำเนินการดังกล่าว
Chris Bloom

ทำงานเหมือนมีเสน่ห์สำหรับฉันไม่มีวิธีแก้ไขปัญหาอื่นทำงาน +1 ต้องเพิ่ม CSS เล็กน้อยเพื่อให้ได้ตัวแบ่งที่ถูกต้อง. page-break {page-break-after: always; }
fhugas

ใช่โดยเพิ่ม. page-break {page-break-after: always; } มันช่วยชีวิตฉันไว้!
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
ไม่ทำงานในโครเมี่ยม ถูกเพิกเฉยราวกับว่าเมื่อ 6/13/2012 เมื่อใช้กับ 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 ด้วยการปรับแต่งบางอย่าง

โดยทั่วไป; เราไม่สามารถทำลายtrs หรือtdเพราะมันไม่ใช่องค์ประกอบระดับบล็อก ดังนั้นเราจึงฝังdivs ในแต่ละและใช้ของเรากฎกับpage-break-* divประการที่สอง; เราเพิ่มช่องว่างไว้ด้านบนของแต่ละ divs เหล่านี้เพื่อชดเชยสิ่งประดิษฐ์สไตล์ใด ๆ

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

การปรับระยะขอบและการบุนวมนั้นจำเป็นต่อการชดเชยส่วนที่กระวนกระวายใจซึ่งถูกนำมาใช้ (โดยการเดาของฉัน - จาก bootstrap) ฉันไม่แน่ใจว่าฉันกำลังนำเสนอทางออกใหม่จากคำตอบอื่น ๆ สำหรับคำถามนี้ แต่ฉันคิดว่านี่อาจจะช่วยใครซักคน


1

ฉันประสบปัญหาเดียวกันและค้นหาวิธีแก้ปัญหาทุกหนทุกแห่งในที่สุดฉันก็พบสิ่งที่เหมาะกับฉันสำหรับเบราว์เซอร์ทุกตัว

html {
height: 0;
}

ใช้ css นี้หรือแทน css คุณสามารถใช้ javascript นี้ได้

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

หวังว่าสิ่งนี้จะได้ผลสำหรับคุณเช่นกัน


0

ฉันตรวจสอบโซลูชันมากมายและทุกคนทำงานได้ไม่ดี

ดังนั้นฉันจึงลองกลอุบายเล็ก ๆ และใช้งานได้:

tfoot with style: position: fixed; bottom: 0px; ถูกวางไว้ที่ด้านล่างของหน้าสุดท้าย แต่ถ้าส่วนท้ายสูงเกินไปมันจะทับซ้อนกับเนื้อหาของตาราง

tfoot ที่มีเท่านั้น: display: table-footer-group; ไม่ได้ซ้อนทับกัน แต่ไม่ได้อยู่ที่ด้านล่างของหน้าสุดท้าย ...

ลองใส่ 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

ฉันได้ลองใช้คำแนะนำทั้งหมดที่ให้ไว้ข้างต้นแล้วและพบวิธีแก้ไขปัญหาเบราว์เซอร์ข้ามที่เรียบง่ายและใช้งานได้สำหรับปัญหานี้ ไม่จำเป็นต้องใช้สไตล์หรือตัวแบ่งหน้าสำหรับโซลูชันนี้ สำหรับวิธีแก้ปัญหารูปแบบของตารางควรเป็นดังนี้:

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