JS导出PDF插件的方法(支持中文、图片使用路径)
来源: 阅读:1698 次 日期:2016-07-28 15:26:28
温馨提示: 小编为您整理了“JS导出PDF插件的方法(支持中文、图片使用路径)”,方便广大网友查阅!

在WEB上想做一个导出PDF的功能,发现jsPDF比较多人推荐,遗憾的是不支持中文,最后找到pdfmake,很好地解决了此问题。它的效果可以先到http://pdfmake.org/playground.html查看。在使用过程中,还发现图片的插入是相对繁琐的一件事。

针对这些问题,本文的主要内容可分为三部分:

•pdfmake的基本使用方法;

•如何解决中文问题;

•如何通过指定图片地址插入图片。

pdfmake的基本使用方法

1.包含以下两个文件

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

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

2.在JS代码中声明一个Document-definition对象,这个是pdfmake自己的术语。简单点说,就是创建一个至少包含content属性的对象。然后就可以调用pdfMake的方法导出PDF,具体见如下代码:

<script type="text/javascript">

 //创建Document-definition对象 

 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'

       ]

    };

 //导出PDF

 pdfMake.createPdf(dd).download();

 </script>

按照上例操作,就可以看到提示文件下载了。关于pdfmake的完整教程请登陆pdfmake项目查看。

pdfmake支持中文

三个步骤:

1.到pdfmake项目网站,把工程都下载下来,然后进入工程目录将字体文件(比如微软雅黑.ttf)放到examples/fonts目录下,然后使用grunt dump_dir生成新的vfs_fonts.js文件;

从上面描述可知该工程是通过grunt管理的,如果无相关知识,请上网先补习下。

grunt dump_dir命令会将fonts目录下所有文件都打包,因此无用文件请别放进去。

微软雅黑.ttf网上一搜一大把,WINDOWS电脑系统盘下存放字体的目录也找得到。

2.回到自己的例子代码中,JS代码中修改pdfMake的fonts对象,声明当前要用到字体:

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对象中声明默认要使用的字体,具体来说:就是声明一个对象,除了content属性,还要有一个defaultStyle属性,该defaultStyle下面还有再有一个font属性:

var dd = {

      content: [

       '中英文测试',

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

       ],

       defaultStyle: {

         font: '微软雅黑'

       }

    };

以下为根据如上步骤做的一个完整例子源码:

<!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: [

       '中英文测试',

       '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要求先将图片转换成Data URL才行,而pdfmake允许直接指定路径,看起来是很方便,但这是有条件的,必须是以node.js作为服务器,或者将图片放到vfs_fonts.js中,所以总的来说,用处不大,还是一样得将图片转换成Data URL形式才行。

为解决此问题,我写了一个ImageDataURL的函数对象,可同时传入多个图片地址。在图片都加载完成后,ImageDataURL.oncomplete将被触发,在回调中通过this.imgdata取出各个图片的Data URL,根据pdfmake的要求组织下,就可正确生成pdf了。

ImageDataURL的原理是通过H5的canvas标签,将图片绘制在canvas上,然后通过canvas的toDataURL得到图像的Data URL。使用时请注意浏览器兼容性问题。

以下为将sampleImage.jpg, sampleage.jpg, sampleImage.jpg依次写入PDF的例子,测试时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必须是字符串或字符串数组

    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导出PDF插件的方法(支持中文、图片使用路径)就是小编分享给大家的全部内容了,希望能给大家一个参考

更多信息请查看网络编程
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:hfpxwx
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map