JS导出PDF插件的方法(支持中文、图片使用路径)

作者:小满时间:2026-10-30 10:17:07浏览:555

本文介绍使用pdfmake插件在Web端导出PDF的方法,重点解决中文显示与图片插入问题。通过配置字体文件生成vfs_fonts.js支持中文,并封装ImageDataURL函数将图片路径转换为Data URL以正确生成PDF。

JS导出PDF插件概述

在Web开发中实现导出PDF功能时,jsPDF虽然被广泛推荐,但存在不支持中文的局限。相比之下,pdfmake插件能更好地解决这一痛点。用户可访问http://pdfmake.org/playground.html预览其效果。此外,在实际应用中,图片插入操作相对复杂。

针对上述问题,本文内容主要涵盖以下三个方面:

• pdfmake的基本使用方法; • 中文显示问题的解决方案; • 通过指定图片地址插入图片的方法。

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支持中文配置

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的原理是利用HTML5的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插件的方法(支持中文、图片使用路径)的全部内容已分享完毕,希望能对大家有所帮助,也希望大家多多支持本站。

作者最新文章