生产上的查看pdf功能一直好好的,使用的是pdfh5插件实现。 但是某天查看发票pdf显示不全面,于是找了后端看数据的返回,在浏览器上可以正常打开,证明返回的资源没问题,那么一定是前端部分出现了问题。
排查后发现,pdfh5在请求https://www.gjtool.cn/cmaps/UniGB-UCS2-H.bcmap的资源时超时了。上了pdfh5的github上查看,发现已经两年没维护了,同时issue里也有很多人遇到类似的问题,初步排查可能是pdfh5请求该字体资源的证书过期了。
解决方案:直接配置新的cmapurl链接就好了:
this.pdfh5 = new Pdfh5('#pdf-contain', {
pdfurl: url,
cMapUrl: 'https://unpkg.com/pdfjs-dist@2.0.943/cmaps/'
})
如果配置了如上cmapurl但是某些字体显示不了可以使用如下cMapUrl
cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.5.207/cmaps/'
但即使配置了cMapUrl依然在请求该资源的时候还是有点慢,为了优化,尝试采用另外一个pdf插件vue-pdf解决问题。
在使用vue-pdf的过程又遇到了各种坑,如下:
在按照官方文档配置完后,打包发现报如下错误:
ERROR in ./node_modules/vue-pdf/src/vuePdfNoSss.vue 1:0 Module parse failed: Unexpected token (1:0) You may need an appropriate loader to handle this file type.<style src="./annotationLayer.css"></style>
原因: webpack配置中,未对node_modules文件里的vue文件进行解析
解决: webpack配置中去掉exclude /node_modules/
//更改前
{
test: /\.vue$/,
use: 'vue-loader',
exclude: /node_modules/
},
//更改后
{
test: /\.vue$/,
use: 'vue-loader'
},
配置完上述问题后继续报错:
Uncaught ReferenceError: window is not defined at 6d606e3033914f6a1fb5.worker.js:2:20 at 6d606e3033914f6a1fb5.worker.js:2:8086
解决: webpack需配置globalObject:this
//更改前
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash:8].js',
chunkFilename: '[name].[contenthash:8].js'
},
//更改后
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash:8].js',
chunkFilename: '[name].[contenthash:8].js',
globalObject: 'this' //加了这行
},
配置完上述问题后继续继续报错:
TypeError: Cannot read properties of undefined (reading 'catch')
解决: 版本问题 锁定版本
npm i pdfjs-dist@2.5.207
npm i vue-pdf@4.2.0
终于把报错解决完后,可以打开pdf了,但是,上上签的合同盖章以及签名不显示
原因: vue-pdf的依赖pdfjs-dist中的pdf.worker.js中某行代码所导致
解决:
网上很多文章说,直接在node_modules/pdfjs-dist/build/pdf.worker.js注释掉如下代码就解决了。
if (data.fieldType === “Sig”) {
data.fieldValue = null;
// 注释掉底下这行 就可以显示电子签章
// this.setFlags(_util.AnnotationFlag.HIDDEN);
}
我一脸懵逼,这难道只在本地运行不发到线上吗,发到线上重新加载依赖包还是会报错呀。
第一时间想到的办法是把vue-pdf的源码fork一下,注释相关代码后自己使用,后面搜了一下,发现有大佬已经做了这个工作了,就是vue-pdf-signature。
直接引入,其他不变:
//更改前
import Pdfh5 from 'pdfh5',
//更改后
// import pdf from 'vue-pdf'
import pdf from 'vue-pdf-signature'
解决完签章问题,发现某些特殊字体不显示了
解决: 配置cMapUrl,字体资源文件链接
pdf.createLoadingTask({
url,
cMapPacked: true,
cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.5.207/cmaps/'
})
配置完后发现,字体是显示了,但是盖章没了,于是采取另外一种引入资源的方式
import CMapReaderFactory from 'vue-pdf-signature/src/CMapReaderFactory'
pdf.createLoadingTask({
url,
cMapPacked: true,
// cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.5.207/cmaps/'
CMapReaderFactory //改为这行
})
终于完美解决问题,资源加载也很快。
朋友们如果文章对你有用,欢迎点赞,码字不容易。
看到这相信很多朋友会选择方法1吧,方法1就是响应速度慢了点,能接受的话方法1还是很方便的