今年开年的时候,一位客户想要将pdf.js完美的融入到他们的系统当中去,并因此委托我对pdf.js做一个二次开发。我花了大约二十天的时间熟悉并完成了对这个框架一定程度上的二次开发。随后,我将自己对这个框架的分析和改造的思路,写成了大约几万字的博客并分享了出来。同时,我修改过的源代码也一并分享了出来。起初我只是简单的做了一个分享,但是后来有不少朋友来问我各种各样的关于pdf.js的问题,还有一些朋友对我二次开发的代码进行了调试和使用。于是,我又对这个框架仔细的做了一番更详细的了解。发现pdf.js这个框架还是有很大的挖掘空间的。因为pdf.js本身设计只是一个PDF阅读器,一个能够集成到浏览器中的阅读器。其主要目的并不是让开发者能够较好的集成到业务系统中,成为用户系统的一部分。一旦当我们想要将其集成到业务系统当中去,就会遇到各种各样的问题。并且由于文档和资料的缺乏,这些问题往往难以得到解决。因此,我打算来解决这些问题,这也就是我要做这个开源项目的原因。
现在的pdf.js源码,本身提供了一个PDF阅读器。但是只方便通过iframe和window.open这样的方式来调用。pdf.js本身虽然具备了跳转、检索、下载、打印等功能,但却没有提供一个很好的API来让我们来操作这个PDF阅读器。开发者想要操作这个阅读器,可以倒是可以,但是非常的麻烦。因为文档比较欠缺,所以很多时候,只能通过扒源代码、调试源代码的方式,来确定一些问题的逻辑。事实上,我就是通过这些方法来解决一些问题的。不仅是操作不太好操作,其实想根据一定的配置来初始化阅读器,也是难以做到的。
在我心目中,要在web中初始化PDF阅读器,应该只需要给被初始化的dom的id以及一系列的参数配置项,应该就可以将这个PDF的阅读器给显示出来了。而无需其它繁琐的配置,也不应有这样那样的限制。只有这样的、符合迪米特法则的初始化配置方法,对于一个嵌入了web系统中的PDF阅读器来说,才是一个较好的配置方法。因此我会对pdf.js做二次开发,使其能够像下面一样初始化:
const reader = Pdfer.init({
// 容器id
container: '#container-id',
// 打开的首页
firstPage: ...,
// 是否允许跨域读取
crossOrigin: ...,
// 操作的权限
permission: ...,
....
})
并且它最好不要依赖于iframe和window.open这样的打开方式,而是应该以常规dom元素的形式和其它的元素共存。这样开发者在使用这个库的时候,会更加丝滑和顺畅。
除了初始化要比较丝滑之外,有一套好用的API也是非常重要的。现在PDF.js,功能和界面是较为耦合的。即要想跳转到某个页面,就必须在页面上输入页码编号,要想检索PDF里面的内容,就必须要打开搜索框,输入关键词才能进行检索。这对开发者来说,还是不够友好的,开发者如果想按照自己的方式跳转页码或跳转到指定的关键词处,就即为不方便了。与此同时,因为界面和功能一定程度的耦合,即使开发者想设计出一个具有独特样式的翻页按钮、跳转按钮,也较为困难。因此,我想要再将功能和界面彻底解耦了,暴露出一批独立于界面和按钮的API,供开发者调用。这样让开发者能够更加灵活的使用PDF阅读器。在我心中,初始化了reader对象之后,应该可以通过reader对象获取一个操作的API,我们在这里就假设叫它controlApi好了。通过这个controlApi,我们就应当能够较好的控制这个PDF阅读器。
假设我们要实现这个目标,那么我们首先要定义好一个具备操作功能的API:
declare interface ControlApi {
// 跳转到指定页
jumpPage(page:number);
// 高亮某些关键词
highlight(keywords:string[])
// 隐藏所有批注
hideEditor();
....
}
然后我们能够通过一开始初始化的reader对象,获取到这个controlApi:
const api = reader.controlApi();
最后能够通过调用API,来实现我们自己的逻辑:
// 跳转到20页
api.jumpPage(20);
通过对初始化和API的改造,pdf.js就能够由一个独立运行的阅读器转变成了能够支撑我们业务开发的PDF库了。当然,在这个过程中,我们可能还要写很多文档。本身的pdf.js文档匮乏,使得我们在使用pdf.js的时候,有一些力不从心,因此大量的编写和翻译文档,也将是我要去做的一件事。
在完成对pdf.js的改造之后,能做的事情其实还有很多。比如优化现有的一些功能,比如跨域加载、分页加载,比如拓展更多的功能,比如增加一系列的批注、权限控制等。除此之外,还可以对PDF的样式和阅读器进行各式各样的优化,比如有的开发者希望PDF是由上到下下拉的,有的开发者希望PDF是翻页的,有的则希望是从左到右来进行排布的。总而言之,还是有很多工作等待着我去完成的。
目前刚开始做,估计第一阶段还是先做一些整理工作,将官网的一些示例先能够调整调整,让想要学习PDF.js的同学可以很轻易的跑起来、调试起来。
紧接着下一步,再开始将阅读器进行改造,将原来的viewer.html彻底的拆分,将功能和代码抽离出来,让pdf的开发者能够通过Pdfer.init轻而易举的在自己的页面中创建PDF阅读器,而不再依赖于别iframe。
第三阶段则是对功能进行API化,让功能的调用不再难以调用,让开发者能够自由地对API进行组合和使用。
第四阶段则针对性的开发更多更复杂的功能,满足各种场景下对PDF阅读器的使用需求。
之前对PDF.js二次开发的草稿代码:gitee.com/gu_yongqian…