整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaScript將HTML頁面生成PDF并下載

          近碰到個需求,需要把當前頁面生成 pdf,并下載。弄了幾天,自己整理整理,記錄下來,我覺得應該會有人需要 :)

          項目源碼地址:https://github.com/linwalker/render-html-to-pdf


          簡介

          我們可以直接在瀏覽器端使用html2canvas,對整個或局部頁面進行“截圖”。但這并不是真的截圖,而是通過遍歷頁面DOM結構,收集所有元素信息及相應樣式,渲染出canvas image。

          由于html2canvas只能將它能處理的生成canvas image,因此渲染出來的結果并不是100%與原來一致。但它不需要服務器參與,整個圖片都由客戶端瀏覽器生成,使用很方便。

          使用

          使用的API也很簡潔,下面代碼可以將某個元素渲染成canvas:

          html2canvas(element, {
           onrendered: function(canvas) {
           // canvas is the final rendered <canvas> element
           }
          });
          

          通過onrendered方法,可以將生成的canvas進行回調,比如插入到頁面中:

          html2canvas(element, {
           onrendered: function(canvas) {
           document.body.appendChild(canvas);
           }
          });
          

          做個小例子(demo1)代碼如下:

          這個例子將頁面body中的元素渲染成canvas,并插入到body中。

          jsPDF

          jsPDF庫可以用于瀏覽器端生成PDF。

          文字生成PDF

          使用方法如下:

          // 默認a4大小,豎直方向,mm單位的PDF
          var doc = new jsPDF();
          // 添加文本‘Download PDF’
          doc.text('Download PDF!', 10, 10);
          doc.save('a4.pdf');
          

          文字與圖片生成PDF

          // 三個參數,第一個方向,第二個尺寸,第三個尺寸格式
          var doc = new jsPDF('landscape','pt',[205, 155])
          // 將圖片轉化為dataUrl
          var imageData = ‘data:image/png;base64,iVBORw0KGgo...’;
          //設置字體大小
          doc.setFontSize(20);
          //10,20這兩參數控制文字距離左邊,與上邊的距離
          doc.text('Stone', 10, 20);
          // 0, 40, 控制文字距離左邊,與上邊的距離
          doc.addImage(imageData, 'PNG', 0, 40, 205, 115);
          doc.save('a4.pdf')
          

          生成pdf需要把轉化的元素添加到jsPDF實例中,也有添加html的功能,但某些元素無法生成在pdf中,因此可以使用html2canvas + jsPDF的方式將頁面轉成pdf。通過html2canvas將遍歷頁面元素,并渲染生成canvas,然后將canvas圖片格式添加到jsPDF實例,生成pdf。

          html2canvas + jsPDF

          單頁

          將demo1的例子修改下:

          如果頁面內容根據a4比例轉化后高度超過a4紙高度呢,生成的pdf會怎么樣?會分頁嗎?

          你可以試試,驗證一下自己的想法。

          jsPDF提供了一個很有用的API, addPage(),我們可以通過 pdf.addPage(),來添加一頁pdf,然后通過 pdf.addImage(...),將圖片賦予這頁pdf來顯示。

          那么我們如何確定哪里分頁?

          這個問題好回答,我們可以設置一個 pageHeight,超過這個高度的內容放入下一頁pdf。

          來捋一下思路,將html頁面內容生成canvas圖片,通過 addImage將第一頁圖片添加到pdf中,超過一頁內容,通過 addPage()添加pdf頁數,然后再通過 addImage將下一頁圖片添加到pdf中。

          嗯~,很好!巴特,難道沒有發現問題嗎?

          這個方法實現的前提是 — — 我們能根據 pageHeight先將整頁內容生成的canvas圖片分割成對應的小圖片,然后一個蘿卜一個坑,一頁一頁 addImage進去。

          What? 想一想我們的canvas是腫么來的,不用拉上去,直接看下面:

          html2canvas(document.body, {
           onrendered:function(canvas) {
           //it is here we handle the canvas
           }
          })
          

          這里的 body就是要生成canvas的元素對象,一個元素生成一個canvas;那么我們需要一頁一頁的canvas,也就是說。。。

          你覺得可能嗎? 我覺得不太現實,按這思路要獲取頁面上不同位置的DOM元素,然后通過 htnl2canvas(element,option)來處理,先不說能不能剛好在每個 pageHeight的位置剛好找到一個DOM元素,就算找到了,這樣做累不累。

          累的話 :)可以看看下面這種方法。

          多頁

          我提供的思路是我們只生成一個canvas,對就一個,轉化元素就是你要轉成pdf內容的母元素,在這篇demo里就是 body了;其他不變,也是超過一頁內容就 addPage,然后 addImage,只不過這里添加的是同一個canvas。

          當然這樣做只會出現多頁重復的pdf,那到底怎么實現正確分頁顯示。其實主要利用了jsPDF的兩點:

          • 超過jsPDF實例格式尺寸的內容不顯示( varpdf=newjsPDF('','pt','a4');demo中就是a4紙的尺寸)
          • addImage有兩個參數可以控制圖片在pdf中的位置

          雖然每一頁pdf上顯示的圖片是相同的,但我們通過調整圖片的位置,產生了分頁的錯覺。以第二頁為例,將豎直方向上的偏移設置為 -841.89即一張a4紙的高度,又因為超過a4紙高度范圍的圖片不顯示,所以第二頁顯示了圖片豎直方向上[841.89,1682.78]范圍內的內容,這就得到了分頁的效果,以此類推。

          還是看代碼吧:

          兩邊留邊距

          修改imgWidth,并且在addImage時x方向參數設置你要的邊距,具體代碼如下:

          作者:linwalkerhttps://segmentfault.com/a/1190000009211079

          信息加速發展的互聯網時代,越來越多的科技公司為了專注核心競爭力業務以及降低軟件項目成本,開始將項目中的部分業務模塊分發給第三方外包公司來完成。而這樣是否就意味著大幅度地降低成本了?

          事實告訴我們,并沒有。

          本文作者作為一名外包商,以自身的經歷告訴我們本可以在3天之內完成了的一個報價僅為 1500 美元的靜態 HTML 頁面,是如何被大型企業硬是拖成了一個為期 7 周且需要耗費 18000 美元(約為人民幣12萬)項目的。

          不久前,我作為承包商工作,經常從一個項目跳到另一個項目。有些是短期的,工作一周左右,可很快提交我的工作成果。也有的項目會持續幾個月,這期間我會攢一些錢用以休息一段時間。

          我更喜歡短期工作,因為這樣的工作使我可以在單位時間內收取更高的費用。這樣不僅我感覺是在為自己打工,而且我覺得我不需要太努力工作就能過上還算體面的生活了。我的最高費率仍然在合理的范圍之內,而且我總是提供高質量的服務。這就是我和一家大公司定下這個項目之前我的工作狀態。

          這家公司聯系我的時候顯得很著急,經理告訴我他們現在就需要一個人來搞定這件事。需要一個不怎么需要公司培訓就能馬上上手,而且能交付最大性能的人。不管怎么說,這剛好是我的座右銘。這個項目正是我喜歡的工作類型。它內容簡短,很快就能做好,而且報酬很高。

          在談判確定好合適的費率后,我收到了一封包含說明的電子郵件。他們給了我更多關于這個項目的背景。他們的開發人員在沒有事先告知的情況下就離開了,并且從未跟任何其他人匯報過項目的進展。

          我們需要您毫不分心地完成此項目。在合同期限內,您將只與我們合作,并及時交付成果。我們會對給您造成的麻煩進行補償。

          任務說明很簡單:閱讀這些需求然后估計完成這個項目需要多長時間。這是我職業生涯中遇到的一個那類比較容易的項目之一。這是一個HTML頁面,包含一些簡單的動畫和幾個嵌入的視頻。我花了一個晚上研究需求并在腦中模擬實施。這些年來,我已經學會了在能確定收到報酬之前不為客戶寫任何代碼。

          我確定了這個項目充其量也就是一天的活兒。但為了保持謹慎,我上報了20個小時,總計1500美元。畢竟這只是一個HTML頁面而已,我也只能收取這么多費用。他們讓我到25英里外的衛星辦公室去。在為他們工作的那三天里我必須天天開車去那兒。

          第二天,我到了衛星辦公室。在一個購物中心,然后通過一扇秘密的門進入了一個秘密的世界,一些工作人員在他們的小隔間里安靜地工作著。接待員給我看了一個我將用它來工作的全新MacBook Pro,我必須從零開始設置環境。我的確更偏向于使用公司的筆記本電腦,因為他們經常要求承包商安裝一些可疑的軟件。(我可不想裝到自己電腦上。)

          我花了一天時間下載我的工具包,設置電子郵件、SSH密鑰和請求服務的授權。換句話說,我什么都沒做。這就是為什么我上報了20個小時,還沒開始寫代碼呢,光前期設置就耗費了8個小時。



          第二天,我準備開始真正地干活了。有了MacBook Pro,我用它發了一封電子郵件給經理。我告訴他我已經準備好工作了,正在等待上述的資源。那天,我在我柔和燈光下的工位上待著,玩著手指,直到太陽落山。

          我再次計算了一下。根據我的估計,我還只剩4個小時的時間來完成這項工作,這對單個HTML頁面來說也不是不可能。但不用說,第二天,我把這剩下的4個小時花在了吃公司贊助的午餐上,伙食很不錯,而且我與其他員工玩得很開心。

          當預計的20小時到期時,我確保向經理發送了另一封電子郵件,讓他知道我確實人一直在公司,但我沒有收到我需要的資源。當然,那封電子郵件被無視了。

          接下來的星期一,我猶豫地開過了這25英里。令我驚訝的是,經理已經來到衛星辦公室,并熱情地問候了我。他是個三十來歲,很隨和很不錯的人。我很不解,他并不像當初要雇我的那時候那么著急了。我們進行了友好的交談,沒有提到任何工作。后來,我們去吃午餐,他付了錢。這是美好的一天。完全沒工作。

          好吧你可以說我很容易形成習慣,但如果你供我吃喝并每天呵護我,我會習慣這一切。這變成了一個例程。

          我來上班,花一些時間在網上閱讀以及看視頻。我每天發一封電子郵件,所以他們知道我確實去了公司。

          然后,我會去吃午飯并和碰見的有趣的人一起玩耍。在一天結束時,我站起來,伸個懶腰,打一個當之無愧的哈欠,然后開車回家。

          我習慣了。事實上,我在期待這些。當我終于收到一封帶有指向我需要的資源的鏈接的電子郵件時,我反而有點失望。我重新開始腳踏實地,變回自己工作時的嚴肅臉。但是,在花了幾分鐘查看Zip文件后,我才注意到它缺少了我需要的大部分內容。設計師給我發了一些Adobe Illustrator文件,我無法在MacBook上打開它。

          我回復了電子郵件來解釋我的疑慮,而且一并問了一些其他問題以節省時間。那時,我當初上報的20個小時時間早都已經過了。我現在真的想要完成這項工作了。

          點擊發送后不久,我收到了一封電子郵件。只有一句:“轉發給Alex”,然后Alex得到了這封電子郵件的抄送。

          Alex回答說他轉發給了Steve。Steve回答說Michelle是設計師,她會了解得更多一些。

          Michelle的自動回復稱她正在度假,所有詢問都應該直接告訴她的經理。

          她的經理回復說“誰是Ibrahim?(我的名字)”我的經理回復說他很抱歉還沒有向大家介紹我。



          作為承包商,在人們注意到我在那里工作之前,我通常就已經完成我的工作并離開那家公司了。但這次,我收到了大量歡迎的電子郵件。這樣的郵件持續了一段時間,而我被迫回復那些友好地過了頭的郵件。有些人很想跟我本人見面。當我說我在加利福尼亞州,離得遠著呢,他們有點失望。以及羨慕,他們說他們羨慕加州美好的天氣。

          他們很有禮貌地無視我的電子郵件,用抄送來轉移我的問題,把我問過的任何事情歸為垃圾郵件。我花了很多時間,像一位考古學家在深深的電子郵件之溝內挖掘,希望找到我問題的答案。

          你可以想象每當我想起我唯一的任務是構建一個靜態HTML頁面時,我感覺到的冒名頂替綜合癥(心虛,懷疑自己的回報不是理所應得的)的程度之深。原本虛報了的20個小時的項目變成了為期7周的冒險,期間我享受免費午餐,每天開車50英里,并翻看電子郵件。

          當我最終完成項目時,我在GitHub上將它發送給了團隊。

          在不久之后,我收到了邀請,整個團隊會用Google Hangout開視頻會議對我的代碼進行Code Review。

          我花了一個多月的時間來寫一個靜態HTML頁面,而現在整個團隊都要評價我的工作?

          那個什么,我要為自己說句話,這個頁面也包含一些JavaScript交互,是響應式的,還包括CSS動畫......好吧我真的覺得自己像個來冒名頂替的。

          當然,視頻會議的時間又重新安排了幾次。當它終于發生時,我和我的工作已經不是會議的主題了。他們都坐在紐約某個地方的同一個房間里,像一個緊密團結的團體一樣聊了一會兒。事實上,他們所說的關于我做的項目的所有內容只有:

          • 人1:嘿,有人在做這個贊助頁面嗎?
          • 人2:是的,我認為已經完成了。
          • 人1:太好了,我今晚合并吧。

          那天晚上回家的時候,我意識到自己正面臨另一個挑戰。我在這家公司工作了7個星期,而我的原始報價為1,500美元。這相當于每年11,100美元或每周214美元。或者直接說,每小時5.35美元。

          這幾乎還不夠我付油錢的。所以,我給他們發了一張發票,我按照原來的每小時費率給他們報了7個星期,總額達18,000美元。我當然感到羞恥,但我還能怎么辦呢?

          就像我預期的那樣,我沒有收到回復。如果所有大公司都有什么相同之處,那就是他們并不急于按時支付賬單。這么簡單的工作要價這么多,我覺得自己像一個騙子,但話又說回來了,我又不是來做慈善的。我每天開車50英里來做這項工作,如果工作沒有完成,那不是因為我不想。這是因為他們回復太緩慢了。

          接下來的一周我得到了回復。這是一封來自經理的冷郵件,他把我每天的工作日分成不同的時間段。然后他把我工作的那部分時間高亮了,每天標記一個小時的午休時間。最后他用我們商定的小時費率做了一些計算。

          顯然,我算錯了。我錯誤估算了總數。調整后,他們欠我的總金額是21,000美元。

          請確認重新調整后的小時數,以便財務可以給您寫個支票。

          我很快回復了確認。

          原文:https://idiallo.com/blog/18000-dollars-static-web-page

          作者簡介:Ibrahim Diallo,具有多年開發經驗的軟件工程師。

          本文為 CSDN 翻譯

          們在搜索資料的時候會看到一些非常有用的資料,但往往這些資料都是付費資料。只能看一部分,不能直接復制下來。如果要直接下載,那只能付費下載。今天就教大家一個方法,可以免費復制付費文檔資料。一分鐘學會,看懂能讓你少花很多錢。這個小技巧建議大家收藏,以免找不到。下面大家跟著我一步步做吧!

          如何免費復制付費文檔資料

          這里我們以谷歌瀏覽器為例來進行手把手的操作:

          首先我們打開某度文檔,在里面搜索到了一篇文章,文檔顯示需要VIP專享才可以下載。在這里如果我們直接復制這里的文字,就是彈出一個對話框,顯示文檔復制為VIP權益,開通VIP可繼續復制。

          彈出的vip窗口

          重點來了,我們在頁面的空白處點擊右鍵,并打開檢查選項。這檢查功能太重要了,里面我們可以看到該網頁的源代碼。這個一般是前端開發人員經常用到的功能,不僅可以調試各種樣式參數,還可以看數據傳遞性能。

          檢查選項

          我們找到設置按鈕(如下圖的紅色圈標注的地方),對頁面的首選項(preferences)進行設置。

          設置按鈕

          下拉找到調試程序(Debugger)選項,將禁用Javascript(Disable Javascript)進行勾選。

          勾選禁止JavaScript按鈕

          不要關閉檢查窗口,我們發現原來我們打開的頁面文章選中后已經可以復制了。大功告成。是不是很簡單。大家學會了嗎?

          大功告成

          這個免費復制的原理就是禁用網頁的頁面Javascript代碼。缺點也是非常明顯,就是不能直接復制圖片或者特殊文字代碼等。所以,如果大家需要完整的文檔最好還是付費購買吧。

          應該注意的情況:

          1.如果用這個辦法不能復制,可能就是原來資料本身就是不可編輯的資料,比如別人就是以圖片形式上傳的資料。
          2.尊重別人的勞動成果,不可將別人的資料直接應用到自己的作品中。只可用于個人學習之用。
          3.由于平臺打擊各種第三方工具下載,以前的很多工具(網站)已經失效,如果有購買的需謹慎。

          注:我是秦韻莞香,和你聊聊日常的數碼科技、互聯網趣聞,每天一更,歡迎關注。原創文章,未經授權不得轉載,侵權必究。


          主站蜘蛛池模板: 精品人妻一区二区三区毛片| 国产福利91精品一区二区三区| 黄桃AV无码免费一区二区三区| 国模私拍福利一区二区| 国产精品成人99一区无码| 三上悠亚精品一区二区久久| 相泽南亚洲一区二区在线播放 | 精品国产一区二区22| 人妻无码一区二区三区免费| 日韩综合无码一区二区| 亚洲国产一区明星换脸| 免费视频精品一区二区| 成人精品一区久久久久| 春暖花开亚洲性无区一区二区 | 日本精品一区二区三区在线观看| 国产成人精品一区二三区 | 精品国产乱码一区二区三区| 久久久久久综合一区中文字幕| 波多野结衣一区二区三区aV高清| 美女视频黄a视频全免费网站一区| 女人18毛片a级毛片一区二区| 国产精品无码亚洲一区二区三区 | 国产成人高清亚洲一区91| 在线免费观看一区二区三区| 韩国女主播一区二区| 精品一区二区三区在线观看l | 好吊视频一区二区三区| 亚洲一区精品伊人久久伊人| 国产一区二区精品尤物| 国产精品va无码一区二区| 国偷自产一区二区免费视频| 久久精品国产一区二区三| 人妻aⅴ无码一区二区三区| 乱精品一区字幕二区| 亚洲AV无码一区二区三区牲色| 国产一区二区草草影院| 人成精品视频三区二区一区 | 国产经典一区二区三区蜜芽| 亚洲无码一区二区三区| 在线视频一区二区三区四区| 精品乱码一区二区三区在线|