明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

js完成html轉(zhuǎn)換pdf

[摘要]在項(xiàng)目開(kāi)發(fā)的時(shí)候,我們偶爾或者是經(jīng)常會(huì)遇到一些難題,關(guān)于用js吧html頁(yè)面轉(zhuǎn)換成pdf也是一個(gè)難題,意思是說(shuō)相當(dāng)于把整個(gè)頁(yè)面截下來(lái),然后保存成pdf。其實(shí),能夠?qū)崿F(xiàn)html轉(zhuǎn)pdf的方法還是挺多的,大概有以下幾種:1、大部分瀏覽器就有這個(gè)功能。然而我們客戶要的可不是這個(gè),人家要的是能夠在系統(tǒng)中主...
在項(xiàng)目開(kāi)發(fā)的時(shí)候,我們偶爾或者是經(jīng)常會(huì)遇到一些難題,關(guān)于用js吧html頁(yè)面轉(zhuǎn)換成pdf也是一個(gè)難題,意思是說(shuō)相當(dāng)于把整個(gè)頁(yè)面截下來(lái),然后保存成pdf。

其實(shí),能夠?qū)崿F(xiàn)html轉(zhuǎn)pdf的方法還是挺多的,大概有以下幾種:

1、大部分瀏覽器就有這個(gè)功能。然而我們客戶要的可不是這個(gè),人家要的是能夠在系統(tǒng)中主動(dòng)觸發(fā)的導(dǎo)出為pdf功能,所以這種方案pass。

2、利用第三方工具。我找到了一種利用wkhtmltopdf這種工具來(lái)導(dǎo)出的方案,自己在我們的項(xiàng)目中試了一下,效果不好,而且對(duì)svg圖片的支持也不行。pass。

3、還有一種是利用iText類(lèi)后臺(tái)生成java文件。但因?yàn)樾枰獙?dǎo)出的這個(gè)頁(yè)面是動(dòng)態(tài)頁(yè)面,而且直接把頁(yè)面?zhèn)鹘o后臺(tái)會(huì)丟失大量樣式,所以還是pass。

最后沒(méi)什么好的辦法,只能退而求其次,想著要不先把html頁(yè)面轉(zhuǎn)成圖片,再把圖片導(dǎo)出為pdf。因?yàn)橐С钟脩魧?dǎo)出下載,而且要保留樣式,所以最好是純js前端實(shí)現(xiàn)。

html轉(zhuǎn)canvas的話,就用html2canvas這個(gè)js,這個(gè)網(wǎng)上介紹比較多了,這里就不廢話了。

比較麻煩的是svg圖片,直接用html2canvas無(wú)法把svg標(biāo)簽的內(nèi)容轉(zhuǎn)成canvas,最后查了一圈資料后,鎖定了canvg這個(gè)js。canvg是谷歌的一個(gè)插件,可以將svg標(biāo)簽內(nèi)容轉(zhuǎn)成canvas。具體到我們的項(xiàng)目,還有一個(gè)難點(diǎn),就是如何把glyphicons這種字體圖標(biāo)也轉(zhuǎn)成canvas,因?yàn)樵诓煌瑸g覽器下對(duì)這種字體圖標(biāo)的支持是完全不一樣的。最后找到的方法是用char code來(lái)替換這些字體圖標(biāo),重新繪制成canvas。由canvas生成圖片不用廢話。由圖片生成pdf用jsPDF實(shí)現(xiàn)。 折騰了大半天,總算把整個(gè)流程打通了,接下來(lái)一步一步貼上代碼。

第一步:把對(duì)應(yīng)dom節(jié)點(diǎn)里所有的svg元素替換成canvas

svg2canvas: function(targetElem) {
  var svgElem = targetElem.find('svg');
  svgElem.each(function(index, node) {
    var parentNode = node.parentNode;
    //由于現(xiàn)在的IE不支持直接對(duì)svg標(biāo)簽node取內(nèi)容,所以需要在當(dāng)前標(biāo)簽外面套一層div,通過(guò)外層div的innerHTML屬性來(lái)獲取
    var tempNode = document.createElement('div');
    tempNode.appendChild(node);
    var svg = tempNode.innerHTML;
    var canvas = document.createElement('canvas');
    //轉(zhuǎn)換
    canvg(canvas, svg);
    parentNode.appendChild(canvas);
  });
}

第二步:把glyphicons字體轉(zhuǎn)成canvas。如果項(xiàng)目中沒(méi)有用到glyphicons字體圖標(biāo),可忽略這一步

glyphicons2canvas: function(targetElem, fontClassName, fontFamilyName) {
  var iconElems = targetElem.find('.' + fontClassName);
  iconElems.each(function(index, inconNode) {
    var fontSize = $(inconNode).css("font-size");
    var iconColor = $(inconNode).css("color");
    var styleContent = $(inconNode).attr('style');
    //去掉"px"
    fontSize = fontSize.replace("px", "");
    var charCode = getCharCodeByGlyphiconsName(iconName);
    var myCanvas = document.createElement('canvas');
    //把canva寬高各增加2是為了顯示圖標(biāo)完整
    myCanvas.width = parseInt(fontSize) + 2;
    myCanvas.height = parseInt(fontSize) + 2;
    myCanvas.style = styleContent;
    var ctx = myCanvas.getContext('2d');
    //設(shè)置繪圖內(nèi)容的顏色
    ctx.fillStyle = iconColor;
    //設(shè)置繪圖的字體大小以及font-family的名字
    ctx.font = fontSize + 'px ' + fontFamilyName;
    ctx.fillText(String.fromCharCode(charCode), 1, parseInt(fontSize) + 1);
    $(inconNode).replaceWith(myCanvas);
  });
}
//根據(jù)glyphicons/glyphicon圖標(biāo)的類(lèi)名獲取到對(duì)應(yīng)的char code
getCharCodeByGlyphiconsName: function(iconName) {
  switch (iconName) {
  case("glyphicons-resize-full"):
    return "0xE216";
  case ("glyphicons-chevron-left"):
    return "0xE225";
  default:
    return "";
  }
  }

第三步:html轉(zhuǎn)canvas轉(zhuǎn)圖片再轉(zhuǎn)pdf。

html2canvas($("#myExportArea"), {
  onrendered: function(canvas) {
    var imgData = canvas.toDataURL('image/jpeg');
    var img = new Image();
    img.src = imgData;
    //根據(jù)圖片的尺寸設(shè)置pdf的規(guī)格,要在圖片加載成功時(shí)執(zhí)行,之所以要*0.225是因?yàn)楸壤龁?wèn)題
    img.onload = function() {
      //此處需要注意,pdf橫置和豎置兩個(gè)屬性,需要根據(jù)寬高的比例來(lái)調(diào)整,不然會(huì)出現(xiàn)顯示不完全的問(wèn)題
      if (this.width > this.height) {
        var doc = new jsPDF('l', 'mm', [this.width * 0.225, this.height * 0.225]);
      } else {
        var doc = new jsPDF('p', 'mm', [this.width * 0.225, this.height * 0.225]);
      }
      doc.addImage(imgData, 'jpeg', 0, 0, this.width * 0.225, this.height * 0.225);
      //根據(jù)下載保存成不同的文件名
      doc.save('report_pdf_' + new Date().getTime() + '.pdf');
    }
  },
  background: "#fff",
  //這里給生成的圖片默認(rèn)背景,不然的話,如果你的html根節(jié)點(diǎn)沒(méi)設(shè)置背景的話,會(huì)用黑色填充。
  allowTaint: true //避免一些不識(shí)別的圖片干擾,默認(rèn)為false,遇到不識(shí)別的圖片干擾則會(huì)停止處理html2canvas
});

雖然這種方法可以將html頁(yè)面轉(zhuǎn)換成pdf樣式,但是生成的pdf效果明顯不如正常截圖來(lái)的清晰,如果大家有更好的辦法,歡迎指點(diǎn)。

相關(guān)推薦:

C#怎么將 HTML轉(zhuǎn)換為圖片或 PDF?

關(guān)于C#如何將Word轉(zhuǎn)換成PDF的方法匯總

使用HTML生成一個(gè)PDF實(shí)例代碼

以上就是js實(shí)現(xiàn)html轉(zhuǎn)成pdf的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!


網(wǎng)站建設(shè)是一個(gè)廣義的術(shù)語(yǔ),涵蓋了許多不同的技能和學(xué)科中所使用的生產(chǎn)和維護(hù)的網(wǎng)站。