Hi I’m Shendi

最近做转换工具,需要将图片转pdf,这里记录下来


JS将图片转pdf,jspdf的使用




简介

A library to generate PDFs in JavaScript.

一个用JavaScript生成PDF的库。



下载

在网站或github下载

https://parall.ax/products/jspdf

https://github.com/parallax/jsPDF

解压后在在页面内引入 dist 下的 jspdf.umd.min.js 文件



使用

官方文档是通过以下方式获取 jsPDF

import { jsPDF } from "jspdf";

但是我使用的是原生,找不到办法就只能自己摸索,首先是在控制台看有什么全局变量,发现有一个名称为 jspdf 的变量,这个变量下有一个名为 jsPDF 的函数,经过尝试,使用这个函数就可以获取到实例了

在这里插入图片描述



然后可以看官方文档说的进行尝试

在这里插入图片描述


var doc = jspdf.jsPDF();
doc.text("Hello world", 10, 10);
doc.save("生成.pdf");

执行后,会自动下载pdf文件,文件打开后内容效果如下

在这里插入图片描述



API文档: http://raw.githack.com/MrRio/jsPDF/master/docs/index.html

这个API文档比较详细,但是网站有时候不稳定…可能因为墙的原因



添加图片

我的目的是将图片转pdf,找到了addImage函数,将图片写入pdf

api文档定义如下

(inner) addImage(imageData, format, x, y, width, height, alias, compression, rotation)

第一个参数为图片,可以为链接、字节等,第二个参数为图片格式,第三和第四代表图片编写到当前页的哪个位置,第五和第六代表绘制图片的宽高,更多的参考api文档


例如我将用户上传的图片加入pdf,file为上传的文件,sw.getObjectURL将文件转链接

var pdf = jspdf.jsPDF();
pdf.addImage(sw.getObjectURL(file), "jpeg", 0, 0);

效果如下

在这里插入图片描述



添加页

当内容超出pdf页的高度就需要新增一个页了

在api文档中可以轻易的找到一个名为 addPage 的函数,执行后保存,发现增加了一个pdf页面

在这里插入图片描述


添加页后默认当前页为添加的页面,定义如下

addPage(format, orientation)

其中format代表新建页的格式,默认为A4,还可以为

  • a0 - a10
  • b0 - b10
  • c0 - c10
  • dl
  • letter
  • government-letter
  • legal
  • junior-legal
  • ledger
  • tabloid
  • credit-card

如果需要自定义大小的话直接传递数组就可以了,例如宽200高500

addPage([200,500]);

第二个参数为方向,portrait(纵向),landscape(landscape),或缩写p,l


页面操作

有多页的话就需要有与之对应的操作,例如页面总数,切换页面等

在控制台中查看

在这里插入图片描述


其中 getNumberOfPages 是总页数,setPage 是设置当前操作哪一页,从1开始

还有 getPageWidth,getPageHeight 获取页宽高

setPageWidth,setPageHeight设置页面宽高,第一个参数为页下标,同setPage,从1开始,第二个参数为设置的值

要获取当前选择的是哪一页可以通过 getCurrentPageInfo 来得到当前页的信息,其中有一个 pageNumber 代表当前页数

知道了这些,就可以实现我的目的了



图片自适应

当图片过大会被遮住,所以直接将图片宽度设置为100%,高度根据图片宽高比来进行调整

这样只有高度超出的问题了


高度超过的话就将剩余部分放到第二页,比如一页的高度为100,图片的高度为220,那么总共有三页,第一页是展示图片的上100像素,第二页展示100-200的像素,第三页展示200-220的像素


这部分比较烧脑,只能做根据效果来调整,最终思路如下

记录两个信息,一个图片占用页面的高度(可能多页面),一个当前页面还剩多少高度(用于后面图片在其后位置添加)

计算图片可以占多少页,根据此来循环,代码如下

var pdf = jspdf.jsPDF();
var splitY = 0, splitHeight = 0,
    pageWidth = 210,
    pageHeight = 297;

pdf.setPageWidth(1, pageWidth);
pdf.setPageHeight(1, pageHeight);

// file是上传的文件files[0],有多个文件需要多次处理,这里只做示例
// 这个地方是我自己封装的读取图片文件的库(ShendiWeb),可以自己通过FileReader去读取
sw.readImg(file, function (img) {
    // 获取宽高比. 调整宽度让高度除以宽高比即可
    var ratio = img.width / img.height;
    var height = pageWidth / ratio;

    // 计算图片占多少页
    var num = parseInt((height + splitY) / pageHeight);
    for (var z = 0; z <= num; z++) {
        pdf.addImage(img, "jpeg", 0, splitY - splitHeight, pageWidth, height);
        if (height + splitY - splitHeight >= pageHeight) {
            pdf.addPage([pageWidth,pageHeight]);
            splitHeight += pageHeight - splitY;
            splitY = 0;
        } else {
            splitY = height % pageHeight;
            splitHeight = 0;
        }
    }
});

pdf.save();

我制作了两张图,宽度都为210,一张橙色高度400,一张灰色高度600,效果如下

在这里插入图片描述


这样我的目的就实现了




END

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐