? 最近公司有一個(gè)中的需求,是將html表單轉(zhuǎn)換成pdf 。
? 無(wú)非方式就只有兩種,前端的方式咱就不說(shuō)了,您能看到這里,必然是采用了市場(chǎng)占有率最高的wkhtmltopdf。
? 優(yōu)缺點(diǎn)都很明顯,廢話不多說(shuō),直接說(shuō)我踩過(guò)的坑和填過(guò)的坑。
? No1.? 有登陸權(quán)限驗(yàn)證的頁(yè)面需要打印為pdf 。如果你要打印的頁(yè)面是基于權(quán)限認(rèn)證的,那你打印出來(lái),必然是跳轉(zhuǎn)到認(rèn)證頁(yè)面的pdf。
? ? ? ? ? ?看到這里,不要懵逼。
? ? ? ? ? wkhtmltopdf 支持賬號(hào)密碼和驗(yàn)證碼登陸,同時(shí)也支持采用cookie 的方式進(jìn)行登陸。大部分時(shí)候采用cookies 登陸即可。
? ? ? ? ? 具體的實(shí)現(xiàn)方式如下:
ProcessStartInfo psi =?new?ProcessStartInfo();
psi.FileName =?"wkhtmltopdf.exe";
string?cookieArgs =?"";
var?cookies = HttpContext.Current.Request.Cookies;
if?(cookies !=?null)
{
????var?sb =?new?System.Text.StringBuilder();
????// you probably only need the ".ASPXFORMSAUTH"
????// and "ASP.NET_SessionId" cookies
????// but I pass everything just in case
????foreach?(string?key?in?cookies.AllKeys)
????{
????????string?value = cookies[key].Value;
????????sb.AppendFormat("--cookie {0} {1} ", key, value);???????????????????
????}
????cookieArgs = sb.ToString();
}
psi.Arguments = urlToPrint +?" -q "?+ cookieArgs +?" -";
Process.Start(psi);
?No2.打印的內(nèi)容不全。?
這時(shí)候要分析具體原因,在wkhtmltopdf 里有一個(gè)參數(shù)是--window-status ,這個(gè)參數(shù)可以支持ajax異步請(qǐng)求 的。
做法是: 在調(diào)用wkhtmltopdf 時(shí),傳入?yún)?shù) ,比如 傳入 “? ?--window-status? completed”? ?,然后在ajax 完成回調(diào)時(shí) ,也將document 的window.status = "completed",這樣的話,就會(huì)完全支持異步調(diào)用。有兩點(diǎn)需要注意:1.每個(gè)參數(shù)之間必須有空格,不然一定會(huì)出現(xiàn)你想到的問(wèn)題。2.window.status 的值必須與傳入的參數(shù)值一樣,否則的話,就會(huì)一直處于等待狀態(tài)。
No3. 空白頁(yè)面,網(wǎng)頁(yè)顯示完好無(wú)損,但打印出來(lái)的卻是空白頁(yè)面。? ? ??
? ? ?這是最大的一個(gè)坑,我研究了一天才踩平了。到現(xiàn)在還有一些疑問(wèn)的地方,等到時(shí)候我在去重新踩 。說(shuō)一下坑在哪里哈.
? ? ? wkhtmltopdf 的工具是基于qt webkit 的。所以基本上目前的流行玩法都是支持的。但特么的也有例外,由于官網(wǎng)已經(jīng)很久沒(méi)有更新,我去github上看到的更新也是很久之前的。
? ? ?如果是普通的mvc 和html 頁(yè)面是完全沒(méi)有問(wèn)題的。但單頁(yè)面應(yīng)用程序的坑就大了。
? ? 我當(dāng)時(shí)用的版本是angular js ,在頁(yè)面顯示完美,但在pdf 打印出來(lái)確實(shí)空白的。
? ? ?起初我認(rèn)為問(wèn)題出現(xiàn)在wkhtmltopdf ,它并不支持單頁(yè)面應(yīng)用程序。但我用vue 測(cè)試的沒(méi)有問(wèn)題。于是我重新測(cè)試angular js ,我在github 看了每一個(gè)提問(wèn)者的問(wèn)題。發(fā)現(xiàn)一個(gè)提問(wèn)者講到,他用的angular js? 1.4的版本出現(xiàn)了問(wèn)題,回撤到1.3.5 則正常。于是我發(fā)現(xiàn)新大陸一樣,將angular js?的版本也回車到了1.3.5 ,發(fā)現(xiàn)打印出來(lái)的頁(yè)面不在是空白頁(yè)面,是有內(nèi)容的頁(yè)面。由于我頭一次接觸angluar js ,我問(wèn)同事才得知,angluar js 1.4版本跨度比較大,改變了好多的內(nèi)容,包括請(qǐng)求方式都發(fā)生了很大的變化。這也就解釋了,為啥使用angular js 打印的是空白頁(yè),因?yàn)閍ngular js 1.4以上的版本,你用wkhtmltopdf 根本就調(diào)用不到后臺(tái)的內(nèi)容,壓根就不會(huì)發(fā)起請(qǐng)求。
? ? ? 別急,到這里,坑還沒(méi)結(jié)束,雖然能請(qǐng)求后端了,但是我發(fā)現(xiàn),打印出來(lái)的內(nèi)容卻缺少了很多東西,這時(shí)候就尷尬了,angular js 1.4 以上的 渲染的內(nèi)容沒(méi)有問(wèn)題,但不能向后臺(tái)發(fā)起請(qǐng)求,angular js 1.3.5能發(fā)起請(qǐng)求,但問(wèn)題是打印的時(shí)候渲染不出內(nèi)容。 經(jīng)過(guò)我和同事的一步步調(diào)試,發(fā)現(xiàn)問(wèn)題竟然在css ,一個(gè)叫overflow 的標(biāo)簽直接影響內(nèi)容。 具體詳情請(qǐng)參考前輩的:http://www.itdecent.cn/p/57c897cfaa27
? ? 周六折騰了一天,總算是搞定了。希望對(duì)大家能有所幫助,如果有什么問(wèn)題,大家及時(shí)留言。我會(huì)盡快的幫助大家解決。