JS导出PDF插件的方法(支持中文、图片使用路径)
本文介绍使用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插件的方法(支持中文、图片使用路径)的全部内容已分享完毕,希望能对大家有所帮助,也希望大家多多支持本站。
JS空字符串、null和undefined转数字的结果是什么
2026-11-05 14:49:16
CodePen、JSFiddle与StackBlitz:主流JS在线编辑器对比
2026-11-05 13:38:29
JS怎么将时间戳转换为“刚刚”、“几分钟前”等相对时间
2026-11-05 12:55:14
JavaScript将儒略日逆向还原为公历日期时间的实现方法
2026-11-04 23:51:05
能在我的世界手机版直接修改JS代码吗
2026-11-04 19:02:53
