jsPDF:客戶端PDF生成利器,精細控制頁面元素
核心要點:
textAlign()
之類的函數,並使用setFontSize()
、setFont()
、setTextColor()
和setFontType()
方法更改文本屬性。 便攜式文檔格式(PDF)是桌面出版和辦公自動化領域的一項重大創新。
它也廣泛用於網絡出版,但不幸的是,很多時候使用方法不當——例如用它來替換本應使用HTML構建的內容。這會導致許多關於可用性、可訪問性、SEO等方面的問題。
但是,在某些情況下需要PDF文件:當需要存檔文檔並且必須在網絡外部使用(例如發票)時,或者當需要對打印進行深度控制時。
正是對打印控制的需求促使我去研究一種輕鬆生成PDF的方法。
本文的目的不僅僅是簡單地解釋如何創建PDF(有很多簡單的方法可以做到這一點),而且還要關注PDF文件可以解決問題的情況,以及像jsPDF這樣的簡單工具如何提供幫助。
打印處理
任何處理過CSS打印規則的人都了解實現體面的跨瀏覽器兼容性有多麼困難(例如,查看Can I Use中的分頁符支持表)。因此,當我需要構建必須打印的內容時,我總是嘗試避免使用CSS,最簡單的解決方案是使用PDF。
我這裡說的不是簡單的HTML到PDF轉換。 (我嘗試過幾種此類工具,但沒有一個完全令我滿意。)我的目標是完全控制元素的位置和大小、分頁符等等。
過去,我經常使用FPDF,這是一個PHP工具,可以輕鬆地為您提供這種控制,並且可以輕鬆地使用許多插件進行擴展。
不幸的是,該庫似乎已被放棄(其最後一個版本可以追溯到2011年)(更新:實際上,最新版本似乎是2015年12月發布的),但由於一些JavaScript庫,我們現在可以直接在客戶端構建PDF文件(從而使它們的生成速度更快)。
幾個月前,當我開始我的項目時,我搜索了一個JS庫,最終我找到了兩個候選者:jsPDF和pdfmake。 pdfmake似乎文檔齊全且易於使用,但由於它是測試版,所以我選擇了jsPDF。
使用jsPDF構建PDF
jsPDF文檔相當簡短,包括一個頁面以及一些演示,以及源文件(或其jsDoc頁面)中更多信息,因此請記住,將其用於復雜項目一開始可能會有點困難。
無論如何,jsPDF對於基本的PDF文件生成非常容易。讓我們來看一個簡單的“Hello World”示例:
var pdf = new jsPDF(); pdf.text(30, 30, 'Hello world!'); pdf.save('hello_world.pdf');
此HTML頁面生成一個單頁PDF文件並將其保存到您的計算機上。首先,您必須鏈接到jsPDF庫(在本例中,來自cdnjs.com),然後創建一個jsPDF實例,添加一行文本,並將結果保存為hello_world.pdf。
請注意,我使用了1.0.272版本,它不是最新的:在撰寫本文時,最新版本是1.1.135,但它有很多問題,所以我仍在使用之前的版本。
您可以看到構建基本PDF文件是多麼簡單(您可以在jsPDF網站上找到更多示例)。
讓我們嘗試構建更複雜的內容。
傳單項目
幾個月前,有人要求我構建一個用於創建一些簡單傳單的應用程序。它是處理旅行社服務的更大項目的一部分,真正的傳單部分由一些JSON數據填充。
傳單的主要目的是提供一種簡單的方法來顯示要在旅行社商店櫥窗中展示的特價優惠。
我已經為本文重新安排了該應用程序,刪除了所有服務器端功能,簡化了傳單設計,擺脫了舊版瀏覽器兼容性,並使用Bootstrap 3和jQuery構建了一個非常簡單的UI。
該演示與Firefox和Chrome配合良好,而Explorer(或Edge)不允許您顯示預覽,而只能下載生成的PDF。
這是一個使用該應用程序創建的PDF示例(照片來源:Rafael Leão / Unsplash)
可以在本文結尾或直接在CodePen中找到一個可運行的演示。請注意,由於CodePen在iframe中加載結果頁面,因此在iframe中加載的PDF預覽在Chrome和Safari中存在一些問題,阻止了預覽的顯示。 (如果可以,請使用Firefox,或者在我的個人網站上嘗試演示)。
傳單構建器
用戶界面允許用戶插入一些基本數據(標題、摘要和價格)。可以選擇添加圖像,否則將顯示灰框的“特價優惠”標題。
其他數據(代理名稱及其網站URL和徽標)嵌入到應用程序代碼中。
PDF可以在iframe中預覽(除了Explorer或Edge)或直接下載。
當單擊“更新預覽”或“下載”按鈕時,將使用jsPDF生成PDF,並將其作為data URI字符串傳遞到iframe或保存到磁盤,如上例所示。
PDF生成首先使用以下選項創建一個新的jsPDF對象實例:縱向方向(p)、毫米單位(mm)、“A4”格式。
var pdf = new jsPDF(); pdf.text(30, 30, 'Hello world!'); pdf.save('hello_world.pdf');
使用addImage函數添加圖像。請注意,放置在PDF頁面中的每個對像都必須精確定位。您必須使用聲明的單位來處理每個對象坐標。
var pdf = new jsPDF('p', 'mm', 'a4');
圖像必須進行Base64編碼:代理徽標以這種格式嵌入到腳本中,而用戶加載的圖像則使用$('#flyer-image').change偵聽器中的readAsDataURL方法進行編碼。
標題使用textAlign函數添加。請注意,此函數不是jsPDF核心的組成部分,但是,正如作者在他的示例中建議的那樣,可以使用其API輕鬆擴展該庫。您可以在傳單構建器腳本的頂部找到textAlign()函數:
// pdf.addImage(base64_source, image format, X, Y, width, height) pdf.addImage(agency_logo.src, 'PNG', logo_sizes.centered_x, _y, logo_sizes.w, logo_sizes.h);
此函數計算文本字符串的X坐標以使其居中,然後調用本機text()方法:
pdf.textAlign(flyer_title, {align: "center"}, 0, _y);
要更改文本屬性,可以使用setFontSize()
、setFont()
、setTextColor()
和setFontType()
方法。
例如,要設置一個20pt Times Bold紅色字符串,您需要鍵入以下內容:
pdf.text(text string, X, Y);
“特價優惠”灰色框和價格圓圈使用兩種類似的方法:roundedRect()
和circle()
。兩者都需要左上角坐標、大小值(第一種情況下的寬度和高度以及第二種情況下的半徑):
pdf.setFontSize(20); pdf.setFont("times"); pdf.setFontType("bold"); pdf.setTextColor(255, 0, 0); pdf.text(10,10, 'This is a 20pt Times Bold red string');
style參數指的是對象的填充和描邊屬性。有效的樣式包括:S [默認] 表示描邊,F 表示填充,DF(或FD)表示填充和描邊。
填充和描邊屬性必須使用setFillColor
和setDrawColor
預先設置,它們需要RGB值和setLineWidth
,後者需要在PDF文檔創建之初聲明的單位中的線寬值。
完整的代碼可在CodePen演示中找到:
(此處應插入CodePen鏈接,由於我無法訪問外部網站,無法提供)
結論
這個基本示例展示瞭如何使用jsPDF構建非常基本的傳單。
它的使用可能很簡單,但是缺乏完整的文檔使每一步都非常複雜。
我仍在尋找其他解決方案,關注pdfmake等其他解決方案。但最終,我認為唯一真正明確的解決方案是更好地支持打印CSS規則的瀏覽器!
(此處應包含FAQ部分,內容與原文相同,但格式可根據需要調整)
以上是使用JSPDF即時從網頁生成PDF的詳細內容。更多資訊請關注PHP中文網其他相關文章!