CSS3輸出PDF打印的小技巧

前文再續,書接上一回,自從《PHP輸出PDF打印HTML5+CSS3打印格式控制》以後,實現了用HTML5+CSS3直接輸出成PDF文件,以知足各類奇葩的打印格式需求。這個的確給調試打印打來了各類便利,不過隨着深刻使用,也碰到一些個小問題。php

Linux系統沒有中文字體

其實這個是前文忘記交代的問題。把系統部署到Linux的時候就發生了,不過這個問題其實比較好解決,直接在服務器安裝文泉驛的開源中文字體便可。ubunutu服務器直接:css

apt-get install ttf-wqy-zenhei

在打印CSS中,修改以下:html

@page {
  size: A4;
  margin: 12mm 10mm;
  padding: 0;
  font-family: "Wenquanyi Micro Hei", "Microsoft YaHei", Simsun, sans-serif;
  font-size: 10pt;
}

對,加個字體生命便可,是否是很簡單呢?前端

Princewkhtmltopdf這兩個引擎,從本質上說,就是一個瀏覽器引擎,固然他們有比較特殊的渲染機制,尤爲是實現CSS3標準的特性,而且他們能夠將結果輸出到PDF文件流。web

爲啥要引入這個東東呢,主要的問題在於,目前主流的瀏覽器,在對打印部分的CSS3標準支持的還頗有限。就算我針對性的作出html的打印樣式,但客戶的打印格式,確定會存在一些比較特殊的要求。除此以外,直接打印html還存在一些不穩定、不肯定的地方,須要有前端的經驗去進行「特製」,但這就致使了可能爲了實現一個需求而進行特製,但下次就忘記了,或者要教會別的人也學會這種「特殊」方法,可能也花很多時間。因此相對而言,採用CSS3,傳統html,不須要額外學習什麼東西,同時,輸出成PDF,輸出的內容也至關的穩定。瀏覽器

非標準紙張的針打紙張尺寸設置

針打紙張的尺寸比較特殊,非標準印刷紙張。但使用Chrome瀏覽器對PDF文件打印輸出的時候,老版本的Chrome紙張尺寸只有幾個標準的紙張尺寸,這問題也困擾了我一段時期。bash

國內外彷佛對這個問題,也沒有比較深刻一點資料。不事後來無心中更新了Chrome到56版本,發現Chrome已經支持在選擇打印機的時候,自動識別打印機裏面設置的特殊紙張格式,你能夠在選擇了打印機之後,找到這個特殊的紙張格式。服務器

因此,你要作的只有兩件事:ide

1. 在打印機首選項裏面,添加你的針打紙張尺寸,多數針打都支持:佈局

2. 在Chrome(具體是什麼版本支持的,我沒去細究了)打印的時候,選好對應的打印機:

至此,整個ERP系統的全部打印需求都已知足了,合同、發票、出入庫單、送貨單、物料編碼不乾膠。

下一階段,打算基於nw.js或者Electron.js,將整個客戶端打包,主要是想經過客戶端發起webscoekt來實現實時的消息推送,若是基於瀏覽器窗口的話,很差管理webscoekt客戶端鏈接數。

除此以外,由於已經徹底是純JS前端的APP應用了,單個窗體過程,存在一個數據對象太多的問題。由於整個界面都是無刷新的,因此各類類型的數據獲取之後,靠客戶端的窗口進程來維持着大量的數據對象,Chrome也是有極限的。一些不常更新的數據,其實能夠做爲本地持久化保存的方案進行處理。

CSS3控制打印的小技巧

回到正題了,其實CSS3控制打印,也沒有什麼特別神祕的東西。

基礎的技巧,我就不說了,能夠直接看這篇教程《Designing For Print With CSS》,老外介紹的很詳細了。

由於在調試的時候,能夠直接用html預覽基本效果,因此調試過程也至關的輕鬆。不過有幾點值得注意的:

1. 在打印調試的時候,使用mm或者cm,比較易於控制實際的打印效果,px時不太適合的。

2. em、rem屬性一樣適用於打印的樣式,他們真的很方便,很是符合設計要求。

3. 字體使用pt單位。字號和具體的mm尺寸轉換表(原諒我圖找得有點崩):

4. 最後的最後,奇淫巧技時間到。就算利用到了CSS三、輸出到PDF,可是客戶的打印需求可能仍是存在一些比較特殊的狀況,這裏仍是就要利用table來實現。

有個這樣的需求:

送貨單的樣式,頁頭有送貨單擡頭、客戶信息、送貨信息、付款說明等,內容部分是一個Table,裏面是送貨單的明細,頁腳附有一段說明文字,以後是簽名欄。

當Table的明細內容超多的時候,要展示到第二頁(這不是廢話嗎,還有第3、4、五等等),可是要求Table表頭能在每一頁都展示。

同時,第二頁也要求有頁頭、頁腳(也就是重複出現)。

最終的打印輸出結果要求以下圖:

首先,重複表頭,咱們並不須要分隔輸出這個Table,只要利用CSS3的特性便可:

table {
	page-break-inside: auto
}

tr {
	page-break-inside: avoid;
	page-break-after: auto
}

thead {
	display: table-header-group
}

tfoot {
	display: table-footer-group
}

其次,對於頁頭、頁腳的多頁展示。雖然在@page,支持有@top-center、@bottom-center等,容許你設置具體的方位上的頁頭頁腳內容,好比:

@page {
	@top-left {
		content: "手寫單號#<?php echo $deliveryCode; ?>";
	}
	@top-right {
		content: "<?php echo $delivery->code; ?>";
	}
}

可是顯然,這種方式並不支持設置包含html的內容,雖然你能夠經過css控制他們的位置,寬度等。因此須要放一些包含html標籤的內容的畫,咱們就須要考慮用別的辦法了,那麼究竟是什麼辦法呢?其實什麼特別的都不用作,只要利用回上述的table部分的樣式便可,也就是說,直接利用css控制table的thead和tfoot的重複渲染特性來實現。

因此,咱們又回到了table佈局的年代:

<table border="0" width="100%" cellpadding="0" cellspacing="0">
	<thead>
	<tr>
		<td class="delivery-thead">頁頭</td>
	</tr>
	</thead>
	<tbody>
	<tr>
		<td class="delivery-tbody">明細</td>
	</tr>
	</tbody>
	<tfoot>
	<tr>
		<td class="delivery-tfoot">頁腳</td>
	</tr>
	</tfoot>
</table>

就這樣,你只要將具體內容,放入delivery-tbody中便可完成整個需求,很簡單,對不對?

相關文章
相關標籤/搜索