JS導(dǎo)出PDF插件的方法(支持中文、圖片使用路徑)
來(lái)源:易賢網(wǎng) 閱讀:1672 次 日期:2016-07-28 15:26:28
溫馨提示:易賢網(wǎng)小編為您整理了“JS導(dǎo)出PDF插件的方法(支持中文、圖片使用路徑)”,方便廣大網(wǎng)友查閱!

在WEB上想做一個(gè)導(dǎo)出PDF的功能,發(fā)現(xiàn)jsPDF比較多人推薦,遺憾的是不支持中文,最后找到pdfmake,很好地解決了此問(wèn)題。它的效果可以先到http://pdfmake.org/playground.html查看。在使用過(guò)程中,還發(fā)現(xiàn)圖片的插入是相對(duì)繁瑣的一件事。

針對(duì)這些問(wèn)題,本文的主要內(nèi)容可分為三部分:

•pdfmake的基本使用方法;

•如何解決中文問(wèn)題;

•如何通過(guò)指定圖片地址插入圖片。

pdfmake的基本使用方法

1.包含以下兩個(gè)文件

<script src="build/pdfmake.min.js"></script>

 <script src="build/vfs_fonts.js"></script>

2.在JS代碼中聲明一個(gè)Document-definition對(duì)象,這個(gè)是pdfmake自己的術(shù)語(yǔ)。簡(jiǎn)單點(diǎn)說(shuō),就是創(chuàng)建一個(gè)至少包含content屬性的對(duì)象。然后就可以調(diào)用pdfMake的方法導(dǎo)出PDF,具體見如下代碼:

<script type="text/javascript">

 //創(chuàng)建Document-definition對(duì)象 

 var dd = {

      content: [

       'One paragraph',

       'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'

       ]

    };

 //導(dǎo)出PDF

 pdfMake.createPdf(dd).download();

 </script>

按照上例操作,就可以看到提示文件下載了。關(guān)于pdfmake的完整教程請(qǐng)登陸pdfmake項(xiàng)目查看。

pdfmake支持中文

三個(gè)步驟:

1.到pdfmake項(xiàng)目網(wǎng)站,把工程都下載下來(lái),然后進(jìn)入工程目錄將字體文件(比如微軟雅黑.ttf)放到examples/fonts目錄下,然后使用grunt dump_dir生成新的vfs_fonts.js文件;

從上面描述可知該工程是通過(guò)grunt管理的,如果無(wú)相關(guān)知識(shí),請(qǐng)上網(wǎng)先補(bǔ)習(xí)下。

grunt dump_dir命令會(huì)將fonts目錄下所有文件都打包,因此無(wú)用文件請(qǐng)別放進(jìn)去。

微軟雅黑.ttf網(wǎng)上一搜一大把,WINDOWS電腦系統(tǒng)盤下存放字體的目錄也找得到。

2.回到自己的例子代碼中,JS代碼中修改pdfMake的fonts對(duì)象,聲明當(dāng)前要用到字體:

pdfMake.fonts = {

     Roboto: {

       normal: 'Roboto-Regular.ttf',

       bold: 'Roboto-Medium.ttf',

       italics: 'Roboto-Italic.ttf',

       bolditalics: 'Roboto-Italic.ttf'

     },

     微軟雅黑: {

       normal: '微軟雅黑.ttf',

       bold: '微軟雅黑.ttf',

       italics: '微軟雅黑.ttf',

       bolditalics: '微軟雅黑.ttf',

     }

   };

3.Document-definition對(duì)象中聲明默認(rèn)要使用的字體,具體來(lái)說(shuō):就是聲明一個(gè)對(duì)象,除了content屬性,還要有一個(gè)defaultStyle屬性,該defaultStyle下面還有再有一個(gè)font屬性:

var dd = {

      content: [

       '中英文測(cè)試',

       'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'

       ],

       defaultStyle: {

         font: '微軟雅黑'

       }

    };

以下為根據(jù)如上步驟做的一個(gè)完整例子源碼:

<!DOCTYPE html>

<html lang="zh-CN">

  <head>

  <meta charset="utf-8">

  <title>my first export PDF</title>

  <script src="build/pdfmake.min.js"></script>

  <script src="build/vfs_fonts.js"></script>

  <script>

  function down() {

    var dd = {

      content: [

       '中英文測(cè)試',

       'Another paragraph, this time a little bit longer to make sure, this line will be divided into at least two lines'

       ],

       defaultStyle: {

         font: '微軟雅黑'

       }

    };

    pdfMake.fonts = {

      Roboto: {

        normal: 'Roboto-Regular.ttf',

        bold: 'Roboto-Medium.ttf',

        italics: 'Roboto-Italic.ttf',

        bolditalics: 'Roboto-Italic.ttf'

      },

      微軟雅黑: {

        normal: '微軟雅黑.ttf',

        bold: '微軟雅黑.ttf',

        italics: '微軟雅黑.ttf',

        bolditalics: '微軟雅黑.ttf',

      }

    };

    pdfMake.createPdf(dd).download();

  }

  </script>

  </head>

  <body>

  <button onclick="down()">下載</button>

  </body>

</html>

插入圖片

在插入圖片方面,jsPDF要求先將圖片轉(zhuǎn)換成Data URL才行,而pdfmake允許直接指定路徑,看起來(lái)是很方便,但這是有條件的,必須是以node.js作為服務(wù)器,或者將圖片放到vfs_fonts.js中,所以總的來(lái)說(shuō),用處不大,還是一樣得將圖片轉(zhuǎn)換成Data URL形式才行。

為解決此問(wèn)題,我寫了一個(gè)ImageDataURL的函數(shù)對(duì)象,可同時(shí)傳入多個(gè)圖片地址。在圖片都加載完成后,ImageDataURL.oncomplete將被觸發(fā),在回調(diào)中通過(guò)this.imgdata取出各個(gè)圖片的Data URL,根據(jù)pdfmake的要求組織下,就可正確生成pdf了。

ImageDataURL的原理是通過(guò)H5的canvas標(biāo)簽,將圖片繪制在canvas上,然后通過(guò)canvas的toDataURL得到圖像的Data URL。使用時(shí)請(qǐng)注意瀏覽器兼容性問(wèn)題。

以下為將sampleImage.jpg, sampleage.jpg, sampleImage.jpg依次寫入PDF的例子,測(cè)試時(shí)sampleage.jpg不存在,PDF直接忽略。

<!DOCTYPE html>

<html lang="zh-CN">

  <head>

  <meta charset="utf-8">

  <title>my second export PDF</title>

  <script src="build/pdfmake.min.js"></script>

  <script src="build/vfs_fonts.js"></script>

  <script>

  function down() {

    var x = new ImageDataURL(["sampleImage.jpg", "samplage.jpg", "sampleImage.jpg"]);

    x.oncomplete = function() {

      var imgs = new Array();

      console.log("complete");

      for (key in this.imgdata) {

        if (this.imgdata[key] == this.emptyobj)//不存在的圖片直接忽略

          continue;

        imgs.push({image:this.imgdata[key]});//pdfmake的圖片格式{image:image dataurl}

      }

      var dd = {

        content: [

         'Title',

         imgs,

         ],

      };

      pdfMake.createPdf(dd).download();

    }

  }

  </script>

  </head>

  <body>

  <button onclick="down()">下載</button>

  <script>

  function ImageDataURL(urls) {//urls必須是字符串或字符串?dāng)?shù)組

    this.completenum = 0;

    this.totalnum = 0;

    this.imgdata = new Array();

    this.emptyobj = new Object();

    this.oncomplete = function(){};

    this.getDataURL = function(url, index) {

      var c = document.createElement("canvas");

      var cxt = c.getContext("2d");

      var img = new Image();

      var dataurl;

      var p;

      p = this;

      img.src = url;

      img.onload = function() {

        var i;

        var maxwidth = 500;

        var scale = 1.0;

        if (img.width > maxwidth) {

          scale = maxwidth / img.width;

          c.width = maxwidth;

          c.height = Math.floor(img.height * scale);

        } else {

          c.width= img.width;

          c.height= img.height;

        }

        cxt.drawImage(img, 0, 0, c.width, c.height);

        p.imgdata[index] = c.toDataURL('image/jpeg');

        for (i = 0; i < p.totalnum; ++i) {

          if (p.imgdata[i] == null)

            break;

        }

        if (i == p.totalnum) {

          p.oncomplete();

        }

      };

      img.onerror = function() {

        p.imgdata[index] = p.emptyobj;

        for (i = 0; i < p.totalnum; ++i) {

          if (p.imgdata[i] == null)

            break;

        }

        if (i == p.totalnum) {

          p.oncomplete();

        }

      };

    }

    if (urls instanceof Array) {

      this.totalnum = urls.length; 

      this.imgdata = new Array(this.totalnum);

      for (key in urls) {

        this.getDataURL(urls[key], key);

      }

    } else {

      this.imgdata = new Array(1);

      this.totalnum = 1;

      this.getDataURL(urls, 0);

    }

  }

  </script>

  </body>

</html>

以上這篇JS導(dǎo)出PDF插件的方法(支持中文、圖片使用路徑)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考

更多信息請(qǐng)查看網(wǎng)絡(luò)編程
易賢網(wǎng)手機(jī)網(wǎng)站地址:JS導(dǎo)出PDF插件的方法(支持中文、圖片使用路徑)
由于各方面情況的不斷調(diào)整與變化,易賢網(wǎng)提供的所有考試信息和咨詢回復(fù)僅供參考,敬請(qǐng)考生以權(quán)威部門公布的正式信息和咨詢?yōu)闇?zhǔn)!
關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡(jiǎn)要咨詢 | 簡(jiǎn)要咨詢須知 | 加入群交流 | 手機(jī)站點(diǎn) | 投訴建議
工業(yè)和信息化部備案號(hào):滇ICP備2023014141號(hào)-1 云南省教育廳備案號(hào):云教ICP備0901021 滇公網(wǎng)安備53010202001879號(hào) 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號(hào)
云南網(wǎng)警備案專用圖標(biāo)
聯(lián)系電話:0871-65317125(9:00—18:00) 獲取招聘考試信息及咨詢關(guān)注公眾號(hào):hfpxwx
咨詢QQ:526150442(9:00—18:00)版權(quán)所有:易賢網(wǎng)
云南網(wǎng)警報(bào)警專用圖標(biāo)