2014-11-06 42 views
19

Tôi muốn in một bảng lớn (quá lớn đến nỗi các hàng của nó rộng khoảng 3 tờ giấy) từ HTML. Nếu có thể, CSS đủ cho bố cục và giải pháp sẽ hoạt động với các trình duyệt khác nhau.In bảng HTML với nhiều cột/hàng bằng bố cục CSS?

tôi đang xác định các quy tắc phong cách sau:

table { page-break-inside:auto; } 
tr { page-break-inside:auto; } 

Khi tôi kiểm tra các yếu tố DOM ví dụ trong Firefox 33.0.2 (trên OS X) Tôi có thể thấy rằng các quy tắc được công nhận, nhưng sau đó khi tôi nhìn vào một bản xem trước in (file | In | PDF | Mở PDF trong Preview) tất cả các cột mà không phù hợp trên trang đầu tiên được cắt bỏ, tức là tôi nhận được 1 trang in ra thay vì 3. Tôi cũng đã thử Internet Explorer 11 và 10 cho cùng một hiệu ứng.

Vậy làm cách nào tôi có thể bố trí các bảng HTML lớn (cuối cùng lớn cả về cột một hàng) để in ra bằng cách sử dụng CSS?

Bonus câu hỏi: Nếu các thành phần phong cách trang-break thực sự chỉ áp dụng để ngăn chặn cấp các yếu tố như đã được nêu trong this câu trả lời trước, nó sẽ giúp đỡ nếu tôi xây dựng bảng của tôi từ div s thay vì td s khi nhắm đến sản lượng in?

CẬP NHẬT

Đây là một mẫu có liên quan mà tôi chỉ cố gắng trên JSFiddle. (Tôi không có tài khoản ở đó, vì vậy FWIK tôi không thể cung cấp một liên kết trực tiếp.)

HTML:

<body> 
<table> 
<tr> 
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_0</td> 
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_1</td> 
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_2</td> 
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_3</td> 
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_4</td> 
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_5</td> 
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_6</td> 
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_7</td> 
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_8</td> 
<td>The_quick_brown_fox_jumped_over_the_lazy_dog_A_9</td> 
</tr> 
</table> 
</body> 

CSS:

table { page-break-inside:auto; } 
td { border:1px solid lightgray; } 
tr { page-break-inside:auto; } 

Nếu tôi cố gắng để in bảng này (ví dụ: bằng cách áp dụng Khung này | In khung ... | PDF | Mở PDF ở chế độ xem trước tới JSFiddle's Kết quả xem trong Firefox 33.1 dành cho OS X và Kích thước giấy/Định hướng A4/Chân dung) Tôi nhận được một trang đầu ra. Tất cả các cột nhưng phần đầu tiên và phần thứ hai được cắt bỏ.

Trả lời

21

Bạn hoàn toàn cần phải di chuyển ra khỏi bảng nếu bạn cần in dọc có thể đọc được trên trang. Bảng rất tuyệt để hiển thị trên trang khi dữ liệu dạng bảng nhưng không phải là giải pháp khả thi để in vì chúng không tôn trọng luồng.

Có các plugin (như this one here, no affiliation – just a Google result) sẽ tự động thực hiện việc này cho bạn, nhưng đây là ví dụ. Khi bạn sử dụng, hãy đảm bảo rằng @media print được liệt kê một cách thích hợp. Để kiểm tra cục bộ, bạn có thể thay đổi điều đó thành @media screen.

Điều đó sẽ không hiển thị các quy tắc @page được liệt kê, nhưng những quy tắc này được hiển thị qua bản xem trước bản in.

Hope this helps:

Fiddle for printing in portrait

HTML

<section class="table"> 
    <div class="row"> 
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_0</div> 
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_1</div> 
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_2</div> 
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_3</div> 
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_4</div> 
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_5</div> 
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_6</div> 
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_7</div> 
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_8</div> 
    <div>The_quick_brown_fox_jumped_over_the_lazy_dog_A_9</div> 
    </div> 
</section> 

CSS

@media print { 
    @page { 
     margin: 2.5cm; 
    } 
    div.row > div { 
     display: inline-block; 
     border: solid 1px #ccc; 
     margin: 0.2cm; 
    } 
    div.row { 
     display: block; 
    } 
} 


.table { 
    display: table; 
    border-spacing: 2px; 
} 
.row { 
    display: table-row; 
} 
.row > div { 
    display: table-cell; 
    border: solid 1px #ccc; 
    padding: 2px; 
} 

Edit - In theo chiều ngang trên một số trang:

Được rồi, vì vậy đây có thể là trường hợp sử dụng ít phổ biến hơn và chúng tôi phải làm một số việc ngốc nghếch với nó - cảnh báo rất công bằng. Tôi sẽ cố gắng giải thích từng bước này vì nó khó hiểu và đáng ghét.

Fiddle for printing in landscape here!

CSS

@media print { 
    @page { 
     margin: 0; 
    } 
    body { 
     height: 100%; 
     width: 100%; 
    } 
    div.row > div { 
     display: inline-block; 
     border: solid 1px #ccc; 
     margin: 0.1cm; 
     font-size: 1rem; 
    } 
    div.row { 
     display: block; 
     margin: solid 2px black; 
     margin: 0.2cm 1cm; 
     font-size: 0; 
     white-space: nowrap; 
    } 
    .table { 
     transform: translate(8.5in, -100%) rotate(90deg); 
     transform-origin: bottom left; 
     display: block; 
    } 
} 

Đây là phần có vấn đề, vì nó đang ngồi chỉ in của bạn. Hầu hết điều này là những thứ chúng tôi đã thấy trong bản gốc (với một số chỉnh sửa khi tôi đang chơi với nó).

Phần chúng ta quan tâm đến ở đây:

.table { 
    transform: translate(8.5in, -100%) rotate(90deg); 
    transform-origin: bottom left; 
    display: block; 
} 

Những gì chúng ta đang làm là ngồi phịch toàn bộ điều trên mặt của nó, và sau đó trượt nó đến nơi mà chúng tôi hy vọng nó được. translate(8.5in, -100%) đang báo cho trình duyệt - Trượt phần tử này 8,5 inch (chiều rộng của giấy thư tiêu chuẩn ở Hoa Kỳ) sang phải và sau đó trượt nó lên 100% chiều cao của nó (dấu âm cho biết ngược với hướng xuống). Chúng tôi trượt nó sang bên phải 8,5 inch để nó sẽ xuất hiện ở đầu trang khi được xoay. Chúng tôi trượt nó lên chiều cao tính toán của nó để chúng tôi không có khoảng cách xấu xí ở bên trái của bảng khi xoay vòng xảy ra.

Sau đó, chúng tôi hướng dẫn rằng chúng tôi muốn tất cả các tính toán đó chạy liên quan đến bottom left vị trí bình thường của phần tử trong luồng tài liệu. Điều này giữ bàn dài điên rồ này khỏi bị xoay sang bên phải bằng cách đặt thuộc tính left. Thuộc tính bottom rất quan trọng bởi vì chúng tôi đang xoay vòng theo chiều kim đồng hồ một phần tư, và nếu chúng tôi đã làm điều đó từ trên cùng, nó sẽ được tắt trang bên trái. Lần lượt quý này được mô tả trong phần tiếp theo của tuyên bố transform: rotate(90deg);

Thì đấy. Điều in trên nhiều trang.

Trước khi bạn yêu cầu: Không. Không có cách nào để ngăn ngắt trang bên trong yếu tố mà tôi biết. Tôi biết nó rất đáng ghét, xấu xí và tất cả rác rưởi đó, nhưng chúng tôi chỉ có thể làm việc với những công cụ mà chúng tôi đang cung cấp.

Cập nhật Firefox xác nhận làm việc: Firefox 33.1 on Mac

+1

+1 Bạn có thể sửa đổi điều này để nó cung cấp cho một bảng ngang có toàn bộ chiều rộng in trên nhiều trang. Đây là những gì tôi dự định ban đầu. (Đây là câu trả lời hứa hẹn nhất cho đến nay.) – Drux

+0

@Drux - Cập nhật bản gốc. Mừng vì tôi có thể giúp. –

+1

Chờ đợi, tại sao sử dụng bố cục div cho dữ liệu dạng bảng khi có thể in '@media print {table, tbody, tr, th, td {display: block; }} '. +1 nhân tiện. –

2

Nếu bạn muốn để buộc ngắt trang bạn nên sử dụng page-break-before hoặc page-break-after. Bạn cần phải biết rằng phần tử được tạo kiểu phải chứa phần tử cấp khối không trống và nó không thể được định vị hoàn toàn. Tuy nhiên nó là khá không phù hợp về các yếu tố bảng. Điều này dẫn chúng tôi đến câu hỏi cuối cùng của bạn: có, nó sẽ phù hợp hơn để xây dựng các bảng của bạn với divs.

Tuy nhiên, xem xét những gì bạn muốn đạt được (in bảng ngang lớn) bạn nên biết rằng việc cố gắng vừa với 3 trang vào 1 không thể hoạt động vì nội dung của bạn sẽ không thể đọc được. Trên thực tế, cách thực hành tốt nhất là sử dụng bố cục dọc thay vì (chỉ để in hoặc cho cả trang web và in).

+0

1 Bạn có một tài liệu tham khảo cho một writeup mà làm cho một luận cứ thuyết phục cho việc sử dụng thay thế một cách bố trí dọc trong tình huống như vậy. Điều này có lẽ sẽ thuyết phục một khách hàng thay đổi các yêu cầu hiện tại. – Drux

+0

@Drux Chắc chắn rồi. Bạn có thể cung cấp thêm một chút ngữ cảnh cho bảng để tôi có thể cung cấp cho bạn các ví dụ có liên quan không? Như mục đích của bàn là gì? – Pipo

+0

Các cột tương ứng với một khoảng thời gian. Các hàng tương ứng với các đối tượng có sự kiện liên quan được lên lịch vào những ngày cụ thể trong khoảng thời gian đó. Các ô chứa id sự kiện. Các id sự kiện đủ dài để trong khoảng thời gian dài (ví dụ: 2 tháng), bảng có thể rộng hơn một trang in. Nó sẽ là tốt để in nó (có lẽ với cột tiêu đề cho id đối tượng lặp đi lặp lại trên mỗi trang in ngang) bất kể. – Drux

8

page-break-inside: auto; là kiểu mặc định, vì vậy trừ khi bạn có quy tắc đặt chúng khác nhau, các quy tắc đó sẽ không làm gì cả.

Nếu bảng của bạn không bị chia nhỏ thành nhiều trang thì rất có thể vì có một số quy tắc khác bạn đã thêm, điều này ngăn cản nó - tôi đoán là overflow: hidden.

Điều đầu tiên bạn nên làm là xóa tất cả các kiểu và xem có in trên nhiều trang hay không. Nếu có, hãy bắt đầu thêm kiểu của bạn trở lại (quy tắc theo quy tắc hoặc nếu cần thiết theo từng dòng) để tìm sự cố.

+0

Tôi vừa thử những gì bạn đề xuất (xem câu hỏi đã chỉnh sửa) nhưng vẫn gặp sự cố tương tự. Bạn có thể mô tả các bước lặp lại để in bảng này không? – Drux

+2

Điều này không trả lời được câu hỏi. –

+0

'overflow: hidden' là vấn đề của tôi. Cảm ơn! –

Các vấn đề liên quan