移动端PDF预览
微信内置浏览器预览pdf文件,不同操作系统的表现不同:
- IPhone:基本可以预览各式各样的文件格式。微信自带的预览功能(不能分享,页面是微信自己的,改不了),可以直接预览PDF文件。如果图文复杂的word,微信预览也会有点错乱。
- Android:打开
PDF
文件,会跳转到浏览器下载页面。
解决方案
通过PDF.JS
来实现PDF文件的在线预览(无需下载其他插件)。其原理是将PDF文件转换成canvas/svg,在html页面上展示。
即自己开发一个页面,调用PDF.JS提供的接口,以PDF文件的地址为参数,接收接口返回的canvas或svg数据。这种自己开发的页面,还可以自行增加微信转发功能。
word文件的预览:服务端将word转成PDF文件,当然,也可以直接转换成图片。
前端我暂时没找到好的将word转换成PDF办法。服务端用linux转的话,如果图文比较复杂,会出现图文错乱的问题。
可以通过购买Window系统的服务器来转换(坑),也可以在阿里云市场购买服务(👀不太推荐,还是有点小贵的)
PDF.JS
pdf.js
是基于HTML5技术构建的,用于展示可移植文档格式的文件(PDF),它可以在现代浏览器中使用且无需安装任何第三方插件。
有以下两种实现方法:
script标签引入方式
<script src="//cdn.bootcss.com/pdf.js/1.8.510/pdf.js"></script>
<script>
PDFJS.getDocument('PDF文件路径').then(pdf => {
this.renderPageAsync(pdf, pdf.numPages)
})
async function renderPageAsync(pdf, numPages) {
for (let i = 1; i <= numPages; i++) {
let page = await pdf.getPage(i);
let scale = 1.5;
let viewport = page.getViewport(scale);
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
document.getElementById('pdf_viewer').appendChild(canvas);
canvas.height = viewport.height;
canvas.width = viewport.width;
let renderContext = {
canvasContext: context,
viewport: viewport,
};
page.render(renderContext);
}
}
</script>
使用npm的方式
安装:npm install pdfjs-dist -S
import PDFJS from 'pdfjs-dist';
PDFJS.GlobalWorkerOptions.workerSrc = 'pdfjs-dist/build/pdf.worker.js';
这两个文件包含了获取、解析和展示PDF文档的方法,但是解析和渲染PDF需要较长的时间,可能会阻塞其它JS代码的运行。
为解决该问题,pdf.js依赖了HTML5引入的Web Workers——通过从主线程中移除大量CPU操作(如解析和渲染)来提升性能。
PDF.js
的API都会返回一个Promise,使得我们可以优雅的处理异步操作。数据返回后的渲染方法,与上方renderPageAsync
方法类似。
PDFh5
pdfh5.js
是基于pdf.js
和jQuery
,在移动端预览PDF的插件。
支持手势捏合缩放、支持canvas、svg
两种渲染模式、支持ajax、fetch
两种请求方式、支持懒加载。
web/h5/移动端PDF预览手势缩放插件。支持canvas、svg
两种渲染模式,支持ajax、fetch
两种请求方式。支持懒加载。
有以下两种实现方法:
script标签引入方式
需下载pdfh5项目下所有文件,包css、js、bcmap等。
<link rel="stylesheet" type="text/css" href="//www.gjtool.cn/pdfh5/css/pdfh5.css">
<script src="https://cdn.bootcss.com/jquery/3.4.1/core.js"></script>
<!--pdf.js会动态加载pdf.worker.js-->
<script src="//res.winbaoxian.com/autoUpload/planbook/pdf_2.3.200.min_00cbdf4292bae80.js"></script>
<script src="//res.winbaoxian.com/autoUpload/planbook/pdf.worker_2.3.200.min_6a5c7ecbf25a64c.js"></script>
<script src="//res.winbaoxian.com/autoUpload/planbook/pdfh5_45706e34292db60.js"></script>
<script>
new window.Pdfh5('#pdf_viewer', {
pdfurl: 'pdf文件路径',
cMapUrl: '//res.winbaoxian.com/pdfjs/web/cmaps/',
renderType: 'svg'
})
</script>
使用npm的方式
安装:npm install pdfh5 -S
<template>
<div id="pdf_viewer"></div>
</template>
<script>
import Pdfh5 from "pdfh5";
export default {
...
data: {
return {
pdfh5: null
}
},
mounted() {
this.pdfh5 = new Pdfh5("#pdf_viewer", {
pdfurl: "" //pdf文件路径
});
this.pdfh5.on("complete", function (status, msg, time) { //监听完成事件
})
}
}
</script>
<style>
@import "pdfh5/css/pdfh5.css";
</style>
手机兼容性
机型 | 编号 | 系统版本 | 备注 |
---|---|---|---|
lenovo(白色) | 08-201600-021 | 4.3 | 异常。页面一直在加载状态 |
oppo(深蓝) | 08-201600-034 | 4.4.4 | 正常 |
vivo X27 | - | 9 | 正常 |
iphone 8 | - | 12.4 | 正常 |
小米 note3 | 08-201703-191 | 5.1.1 | 正常 |
注意问题
跨域问题
本地开发:webpack中添加代理
devServer: { open: false, port: 8080, // 自定义修改8080端口 proxy: { // 代理跨域 '[/pdf文件存储目录]': { target: 'https://img.xxxxx.com', changeOrigin: true } } }
修改服务器(nginx)配置
后端提供api,将pdf文件转成byte[],然后用
pdf.js
解析data
版本问题
引入1.8.**版本,采用svg模式,部分手机会(如:小米 note3)有bug。
引用最新pdf.js版本
乱码问题
pdf文件因字体、编码的问题,可能出会现乱码问题,需引入一些资源文件。
//缺少GBK-EUC-H.bcmap,加载错误
https://pbf.winbaoxian.com/planBook/planbookAccessories/pdf-viewer/index.html?file=https://img.winbaoxian.com/static/app-zx-rule-pdf/allrule/tempDir/%E5%85%89%E5%A4%A7%E6%B0%B8%E6%98%8E%E4%BA%BA%E5%AF%BF%E4%BF%9D%E9%99%A9%E6%9C%89%E9%99%90%E5%85%AC%E5%8F%B8%E5%85%89%E5%A4%A7%E6%B0%B8%E6%98%8E%E5%85%89%E6%98%8E%E8%B4%A2%E5%AF%8C%E9%87%8D%E5%A4%A7%E7%96%BE%E7%97%85%E4%BF%9D%E9%99%A9%E6%9D%A1%E6%AC%BE_20170622064151.pdf
//解决方法
new window.Pdfh5('#pdf_viewer', {
pdfurl: 'pdf文件路径',
cMapUrl: '资源文件夹', //默认是相对路径'./js/cmaps/'
//为减少本地项目体积,已上传到cdn:'//res.winbaoxian.com/pdfjs/web/cmaps/'
})
bcmap
一词代表二进制cmap
。
CMaps
(字符映射)是PostScript
和其他Adobe产品中使用的文本文件,用于将字符代码映射到CID字体中的字符字形。请参阅Adobe的此文档了解哪些CID字体适合使用。它们主要用于处理东亚书写系统。(此技术是一项传统技术,因此不应在现代工具创建的pdf中使用)。pdfjs想要显示这样的CID字体时,它需要CMap文件。
CDN 跨域问题
跨域配置在某些节点没有启效
运维强制推送一遍,目前问题已解决。
由于CDN的特性会缓存源站的响应
阿里云已帮忙解决
建议:上传PDF文件后,先在链接中预览下
内容不满一页
svg
模式下,字体大小的原因,在pc端,内容显示可能会不满一页。
改用canvas
模式