關(guān)于wkhtmltopdf,你一定想知道這些


- 前言
- 實(shí)踐
- 長(zhǎng)表格
- 寬表格
- 其他選項(xiàng)
- 總結(jié)

前言

如果你有 Markdown 或者 HTML 轉(zhuǎn)到 PDF 的需求, 有非常大的可能你選了一圈方案, 最后找到了大名鼎鼎的wkhtmltopdf. 但找到它之后并沒有解決所有問題, 相反, 它會(huì)帶來(lái)更多的問題.
首先說一下它的優(yōu)點(diǎn):

  • 由于是基于 WebKit, 所以渲染結(jié)果和 Chrome( 包括其他基于 Chromium的瀏覽器幾乎完全一致)
  • 可以和前端公用一套 CSS 樣式, 結(jié)果還是體驗(yàn)的一致性
  • 支持大量的定制, 包括頁(yè)頭頁(yè)腳, 頁(yè)碼, 目錄等等, 后面會(huì)詳細(xì)說

再來(lái)說一下缺點(diǎn):

  • 對(duì)特別長(zhǎng)的表格支持有問題. 其實(shí)原因還是來(lái)自 WebKit 引擎, 因?yàn)閃ebKit本身是用來(lái)渲染網(wǎng)頁(yè)的, 而網(wǎng)頁(yè)是不需要上下分頁(yè)的, 所以引擎本身并不支持表格跨頁(yè)顯示, 需要做一些特殊處理, 劃重點(diǎn)了.
  • 對(duì)于特別寬的表格, 如果不做處理, 它會(huì)被橫向截?cái)啵瑫r(shí)會(huì)在表格下方出現(xiàn)一個(gè) scrollbar, 但尷尬的是這個(gè) scrollbar 不能拖動(dòng), 因此也就無(wú)法解決完整顯示的問題.

所以, 優(yōu)點(diǎn)很明顯, 缺點(diǎn)也很明顯. 而且通常如果你有需求生成 PDF, 那多數(shù)情況下是有表格的, 不解決這個(gè)問題, 這個(gè)方案就無(wú)法實(shí)施若专。

實(shí)踐

下面讓我們通過實(shí)驗(yàn)一步步解決上面的兩個(gè)大問題.

長(zhǎng)表格

這里我簡(jiǎn)單寫了一長(zhǎng)段表格, 然后用 MacDown 編輯器把它導(dǎo)出為 html, 這里只是用來(lái)說明問題, 所以就沒有用我實(shí)際在生產(chǎn)環(huán)境使用的 Parsedown.寫著寫著覺得還是用代碼能說的更清晰一些从藤,
原始 markdown 文件和 html 文件就不貼在這里了, 可以查看phpwkhtmltopdf.

在 article 目錄里執(zhí)行
wkhtmltopdf longtable.html longtable-01.pdf

生成的 PDF 在分頁(yè)處如下的效果


表頭重復(fù), 字體重疊

很明顯可以看到表頭重復(fù)出現(xiàn)了. 其實(shí)實(shí)際的問題不止如此, 如果單元格很寬導(dǎo)致?lián)Q行, 很大概率會(huì)和重復(fù)顯示的表頭重疊.
我翻看了不下100個(gè)網(wǎng)頁(yè), 花費(fèi)了大量時(shí)間最終找到了解決方案

thead {
    display: table-row-group;
}

解決了表頭重復(fù)和文字重疊的問題.


表頭不重復(fù), 字體不重疊, 但一行被分割

有所改善, 但還是明顯的發(fā)現(xiàn)表格的一行被切成了兩部分.
下面這個(gè)就是如果你搜索這個(gè)問題最經(jīng)潮裙妫看到的答案了

tr {
    page-break-before: always;
    page-break-after: always;
    page-break-inside: avoid;
}

于是, 變成了這樣子


長(zhǎng)表格問題解決

長(zhǎng)表格的問題到此解決.

寬表格

同樣我將 markdown 文件和 HTML 文件放在了 github 上.
不加特殊處理, 得到的表格將是這樣的


表格右側(cè)被截?cái)?/div>

這是因?yàn)槟J(rèn)的樣式中并沒有

table {
    word-wrap: break-word;
}

的設(shè)置. 我這里的例子舉的有些不合理, 因?yàn)椴粫?huì)全是一樣長(zhǎng)的單元格寬度, 實(shí)際情況總會(huì)有長(zhǎng)有短, 當(dāng)同一列中存在一個(gè)很長(zhǎng)的單詞(或者根本不是單詞, 而僅僅是很長(zhǎng)的連起來(lái)的無(wú)意義的字符串, 像本例中那樣), 該列單元格的最短列寬就會(huì)以它為準(zhǔn). 這樣導(dǎo)致表格的總寬度很容易超出頁(yè)面限制.

因?yàn)?code>word-wrap 控制的是有多個(gè)單詞的情況, 如果只有一個(gè)單詞, 它是不做處理的. 所以需要另外加一個(gè)樣式

table td {
    word-break: break-all;
}

這樣的結(jié)果就是所有表格都完整的展示出來(lái)了.

其他選項(xiàng)

提到 wkhtmltopdf 的選項(xiàng)也真是讓人頭疼, 我本來(lái)是用了snappy和它推薦的二進(jìn)制包, 所有東西都準(zhǔn)備好了, 一個(gè)問題一直解決不了: 我已經(jīng)安裝了宋體, PDF 的正文中的宋體也可以正常顯示了, 但唯獨(dú) header/footer 里面的中文字體死活都出不來(lái). 因?yàn)槲业男枨笫且许?yè)眉和頁(yè)腳, 當(dāng)然也要有相應(yīng)的 header-linefooter-line, 如果用HTML 來(lái)填充 header, 那么 header-line 就會(huì)消失, 這時(shí)如果用 html 中的<hr>來(lái)代替, 又會(huì)看起來(lái)很奇怪, 后來(lái)發(fā)現(xiàn)直接調(diào)用二進(jìn)制文件加上相應(yīng)的選項(xiàng)在相同的機(jī)器上可以得出我需要的結(jié)果, 那么問題就很清楚了, 問題出在這個(gè) snappy 上, 于是我一氣之下直接用 PHP 的shell_exec簡(jiǎn)單封裝了一下 wkhtmltopdf, 簡(jiǎn)直不能更好用, 所有問題迎刃而解.

總結(jié)

寬度的問題其實(shí)在網(wǎng)頁(yè)設(shè)計(jì)里面更常見, 我不是專業(yè)的前端, 所以對(duì)相應(yīng)的樣式比較陌生, 導(dǎo)致花了一些時(shí)間. 但分頁(yè)的問題真是困擾了每個(gè)用過 wkhtmltopdf 的人, 隨便一搜, 幾乎全是關(guān)于這個(gè)問題, 但沒有一個(gè)人真正的給出普適的真正可用的解決方案. 本文給出了我自己的一些經(jīng)驗(yàn), 供大家參考.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吱窝,一起剝皮案震驚了整個(gè)濱河市讥邻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌院峡,老刑警劉巖兴使,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異照激,居然都是意外死亡发魄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門俩垃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)励幼,“玉大人,你說我怎么就攤上這事口柳∑凰冢” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵跃闹,是天一觀的道長(zhǎng)嵌削。 經(jīng)常有香客問我,道長(zhǎng)望艺,這世上最難降的妖魔是什么苛秕? 我笑而不...
    開封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮找默,結(jié)果婚禮上艇劫,老公的妹妹穿的比我還像新娘。我一直安慰自己惩激,他們只是感情好店煞,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咧欣,像睡著了一般浅缸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上魄咕,一...
    開封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天衩椒,我揣著相機(jī)與錄音,去河邊找鬼哮兰。 笑死毛萌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的喝滞。 我是一名探鬼主播阁将,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼右遭!你這毒婦竟也來(lái)了做盅?” 一聲冷哼從身側(cè)響起缤削,我...
    開封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吹榴,沒想到半個(gè)月后亭敢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡图筹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年帅刀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片远剩。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扣溺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出瓜晤,到底是詐尸還是另有隱情锥余,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布活鹰,位于F島的核電站哈恰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏志群。R本人自食惡果不足惜着绷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锌云。 院中可真熱鬧荠医,春花似錦、人聲如沸桑涎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)攻冷。三九已至娃胆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間等曼,已是汗流浹背里烦。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留禁谦,地道東北人胁黑。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像州泊,于是被迫代替她去往敵國(guó)和親丧蘸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)遥皂、插件力喷、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,124評(píng)論 4 61
  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案刽漂? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,761評(píng)論 1 92
  • 春來(lái)山莊鋪綠毯,籬邊簇簇露凝香冗懦。 嫣紅粉面隨風(fēng)褪爽冕,未必嬌羞愧夕陽(yáng)?
    晴鶴1閱讀 329評(píng)論 0 5
  • 簡(jiǎn)暗仇祭,簡(jiǎn)單的陰暗披蕉。 瞥一眼便固執(zhí)地迷上了。 我是一個(gè)反差較大的人乌奇,會(huì)單純地笑的像個(gè)小孩没讲,也會(huì)深沉得像是遲暮的老人。...
    循時(shí)閱讀 409評(píng)論 0 0
  • 當(dāng)年嘁信,吳綺莉不顧成龍和家人反對(duì),一意孤行疏叨,未婚生女潘靖,威脅成龍,成龍婚內(nèi)出軌吳綺莉蚤蔓,致其懷孕卦溢,當(dāng)吳綺莉生下小龍女吳卓...
    雷人創(chuàng)意閱讀 895評(píng)論 3 5