DowYuu言
最近某專案需求要列印特定區塊中的內容,第一時間想到就是用html2canvas搭配jsPDF進行區塊擷取輸出,使用者在自行用PDF去做列印動作。
但會遇到個問題,若有跨頁時,可能會有文字被一刀切成兩半的問題,十分影響閱讀… 這種情況想也不用想一定會被客戶抱怨。
此時的經理說了看要不要用瀏覽器內建的列印功能,點下去就跳視窗出來印,也不用存PDF了…… 對齁怎麼沒想到!!!
先上大大提供的示範
1 |
|
DivIdToPrint
為要列印的區塊id
,大概概念為:
- 開個新視窗
- 取得
DivIdToPrint
的區塊內容並塞進去新視窗中 - 在新視窗
onload
時執行視窗列印window.print()
- 列印後關閉該新視窗
基本上這樣的程式碼符合今天的主題了,但是但是你會發現他有些美中不足的地方…
列印區塊套個CSS吧
當你把原本設置的漂漂亮亮的區塊用上面的方式送去列印,會發現整個區塊像是裸體一樣被印出來…因為沒有引入CSS。
這邊引入CSS的方法千百萬種,可以加個<head>
並引入你原本的CSS,或寫個專門列印用的CSS,又或直接寫個<style>
塞進去…等等看你心情囉!
我自己是用加了<head>
並引入原本的CSS的做法啦,改動程式碼如下:
1 |
|
引入的<link>
當然可以動態的方式抓出來放進去,但這部分就請自行處理囉XD
設置套用於列印時的樣式
在CSS中有個專門為列印用的media,設置在裡面的樣式僅會套用時列印時,寫法簡單直觀。在你的CSS檔案中使用:
1 |
|
或者你也可以另外寫一個檔案專門為列印時套用,在你的CSS檔案中使用@import
引入。
1 |
|
又或是同樣另外寫一個檔案專門為列印時套用,在你的html
頁面中用<link>
且設置media="print"
引入。
1 |
|
列印專用樣式設定
有些樣式設定是專門為列印用,你平常幾乎不會看到。
列印用字體單位
相對於平常CSS用的px、em,針對列印用的尺寸單位推薦使用以下單位:
em
、 cm
、mm
、in
、pt
、pc
、%
詳細可見字體單位說明。
列印頁面尺寸@page
這邊寫到一些目前我有記錄到或用到的,有部分屬性目前瀏覽器沒支援我就不寫了,詳細文件詳見 W3C。
size 尺寸與頁面方向
可設置:
- 寬度與高度(若只有設置一個值則寬度=高度)
- 通用尺寸保留字: A4、A5…
- 頁面方向:portrait(直向,預設)、 landscape(橫向)
頁面寬高或保留字可與方向搭配使用。
1 |
|
詳細設置請看此。
orphans 底部保留最小行數
必須在頁面底部保留的段落的最小行數。
1 |
|
widows 頂部保留最小行數
必須在頁面頂部保留的段落的最小行數。
1 |
|
:first
列印時的第一頁。
1 |
|
詳細設置請看此。
:left 與 :right 左手頁面與右手頁面
像是我們在印雙面文件時,若希望頁面留幾公分來裝訂,正面可能就要在左手邊留白,反面要在右手邊留白……:left
和:right
就是為此而生。
用戶端會自動分別目前印到的頁數為左手頁面或右手頁面,進而去套用:left
或:right
的屬性設置。
要依據文件內容書寫方向自己去判定第一頁為:left
或:right
。
1 |
|
break 分頁斷點
相關屬性有三個,皆為分頁斷點設定,分別在是在元素本身、元素前、元素後插入分頁斷點。
分新舊寫法但目前瀏覽器保留舊寫法並會將舊寫法轉為新寫法。
新寫法 | 舊寫法 | 說明 |
break-inside |
page-break-inside |
元素本身 |
break-before |
page-break-before |
元素前 |
break-after |
page-break-after |
元素後 |
break-inside 元素本身斷點
break-inside (新) |
page-break-inside (舊) |
說明 |
auto | auto | 預設,如果需要則會在元素內插入分頁斷點 |
avoid | avoid | 避免在元素內插入分頁斷點 |
break-before 元素前斷點
break-before (新) |
page-break-before (舊) |
說明 |
auto | auto | 預設,如果需要則會在元素前插入分頁斷點 |
avoid | avoid | 避免在元素前插入分頁斷點 |
page | always | 在元素前總是插入分頁斷點 |
left | left | 在元素前插入分頁斷點直到它到達一個左手頁面 |
right | right | 在元素前插入分頁斷點直到它到達一個右手頁面 |
break-after 元素後斷點
break-after (新) |
page-break-after (舊) |
說明 |
auto | auto | 預設,如果需要則會在元素後插入分頁斷點 |
avoid | avoid | 避免在元素後插入分頁斷點 |
page | always | 在元素後總是插入分頁斷點 |
left | left | 在元素後插入分頁斷點直到到達一個左手頁面 |
right | right | 在元素後插入分頁斷點直到到達一個右手頁面 |
常用於一個<div>
要自己一頁的需求,可以設置如下:
1 |
|
列印遇到的一些坑
印不出顏色
主流瀏覽器
可在元素上設定color-adjust
屬性即可(IE無效):
1 |
|
或者想要在列印模式下全部元素都有顏色,就狠一點一次來:
1 |
|
尊爵不凡IE
請自行去瀏覽器中設定,這邊示範IE11流程:
- 點擊右上角齒輪符號的「工具」(或按下
Alt
+X
) - 點擊「列印」
- 點擊「設定列印格式」
- 出現「設定列印格式」視窗後,在左上角紙張選項中,勾選起「列印背景色彩與影像」即可
IE的表格沒框線
正當我興高采烈的用IE列印時…
某幾格怎麼沒有線????
一查發現,如果你不幸的要兼容IE大大,在IE上列印超過一頁時,<table>
內有使用rowspan
的格子 border會消失不見。
最好的解決方式就是不要使用rowspan
,但說真的某些表格不用rowspan
真的很醜或很奇怪…
我自己專案是情況是沒辦法不用rowspan
,所以改用底色去區隔格子與格子之間,不過也不是所有情況都適用,況且有人不喜歡列印時有底色怕會浪費墨水…
網路上有些教學是使用絕對定位的元素蓋在上面,或是什麼把上下連結部分的線用border-color: transparent;
給隱藏掉… 做出來的效果可以自己去看看你滿不滿意囉。
只能說,珍惜生命,遠離IE吧。
想要自訂頁碼
先說我自己沒試過,不過看到網路上有相關範例就放上來。