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

简介: 原文:JS导出PDF插件(支持中文、图片使用路径)在WEB上想做一个导出PDF的功能,发现jsPDF比较多人推荐,遗憾的是不支持中文,最后找到pdfmake,很好地解决了此问题。它的效果可以先到http://pdfmake.org/playground.html查看。
原文: 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>

参考

目录
相关文章
|
6月前
|
存储 JSON API
如何将 Swagger 文档导出为 PDF 文件
你会发现自己可能需要将 Swagger 文档导出为 PDF 或文件,以便于共享和存档。在这篇博文中,我们将指导你完成将 Swagger 文档导出为 PDF 格式的过程。
|
3月前
|
缓存 测试技术 网络安全
05百融云策略引擎项目交付-laravel实战完整交付定义常量分文件配置-独立建立lib类处理-成功导出pdf-优雅草卓伊凡
05百融云策略引擎项目交付-laravel实战完整交付定义常量分文件配置-独立建立lib类处理-成功导出pdf-优雅草卓伊凡
68 0
05百融云策略引擎项目交付-laravel实战完整交付定义常量分文件配置-独立建立lib类处理-成功导出pdf-优雅草卓伊凡
|
4月前
|
前端开发 JavaScript 容器
制作b超单生成器, 假怀孕b超单图片制作, p图医院证明【css+html+js装逼恶搞神器】
本资源提供一个适合用于熟人之间恶搞的工具,效果逼真,仅供学习参考与娱乐。包含前端技术学习要点:语义化布局、响应式设计、Flexbox、图片自适应
|
6月前
|
API PHP 索引
这插件太危险了!PDFParser自动扒取PDF每天躺赚300+的暴利搬运术
本文介绍了如何使用PHP提取PDF文档中的文字内容。为解决PDF文档“不可编辑”或“文本无法复制”的问题,推荐使用免费的PHP库——PDFParser。通过Composer安装后,可利用其简单强大的API解析PDF文件,提取文本内容。文章详细演示了获取PDF基本信息、全文内容、指定页内容及循环输出每页文本的方法,并附带中英文PDF示例,操作简便实用。
186 3
这插件太危险了!PDFParser自动扒取PDF每天躺赚300+的暴利搬运术
|
8月前
|
文字识别
【PDF提取全自动改名】如何批量提取PDF指定区域的文字内容,用内容批量给PDF命名或者导出表格,学会全自动解放双手
在生活和工作中,我们常需处理大量PDF文件,如银行单据、税收单据等。手动处理效率低下,而使用“咕嘎批量PDF多区域内容提取重命名导表格系统”可快速完成数千份文档的处理,大幅提高效率。该工具通过获取PDF各区域内容坐标,导入并处理文件,最终将信息提取至表格,并根据关键信息对PDF进行重命名,方便管理和查找。
1022 2
|
8月前
|
人工智能 JSON 搜索推荐
猫步简历 - 开源免费AI简历生成器 | 一键导出PDF/JSON
猫步简历是一款免费开源的AI简历生成器,帮助用户轻松创建独特、专业的简历。支持导出超高清PDF、图片、JSON等多种格式,并提供AI智能创作、润色和多语种切换等功能。拥有海量模板、高度定制化模块及完善的后台管理系统,助力求职者脱颖而出。官网:https://maobucv.com,GitHub开源地址:https://github.com/Hacker233/resume-design。
1683 10
|
8月前
|
文字识别 BI
【图片型PDF】批量识别扫描件PDF指定区域局部位置内容,将识别内容导出Excel表格或批量改名文件,基于阿里云OCR对图片型PDF识别改名案例实现
在医疗和政务等领域,图片型PDF文件(如病历、报告、公文扫描件)的处理需求广泛。通过OCR技术识别这些文件中的文字信息,提取关键内容并保存为表格,极大提高了信息管理和利用效率。本文介绍一款工具——咕嘎批量OCR系统,帮助用户快速处理图片型PDF文件,支持区域识别、内容提取、导出表格及批量改名等功能。下载工具后,按步骤选择处理模式、进行区域采样、批量处理文件,几分钟内即可高效完成数百个文件的处理。
824 8
|
9月前
|
移动开发 JavaScript 前端开发
【Html.js——图片折叠效果】折叠手风琴(蓝桥杯真题-1763)【合集】
本项目实现了一个图片折叠手风琴效果,使用jQuery完成。主要包括以下部分: - **介绍**:任务是通过点击图片实现折叠和展开的效果。 - **准备**:内置初始代码,包含 `css/style.css`、`images/` 文件夹、`js/` 文件夹及 `index.html` 等文件。启动 Web Server 服务可运行项目。 - **目标**:完善 `index.js` 文件,使页面达到预期的折叠效果。 - **规定**:严格按步骤操作,保持默认文件结构不变,并在完成后保持 Web 服务正常访问状态。 - **通关代码**:使用 jQuery 实现点击事件,为选中元素添加 `act
124 19
|
10月前
|
JavaScript 容器
带方向感知功能的js图片遮罩层插件
带方向感知功能的js图片遮罩层插件