关于pdf-h5和vue-pdf发票问题显示不全的那些坑

发布时间:2023年12月26日

1. 问题的发生:

生产上的查看pdf功能一直好好的,使用的是pdfh5插件实现。 但是某天查看发票pdf显示不全面,于是找了后端看数据的返回,在浏览器上可以正常打开,证明返回的资源没问题,那么一定是前端部分出现了问题。

2.解决方案

2.1 更换cMapUrl链接

在这里插入图片描述

排查后发现,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解决问题。

2.2 使用新插件vue-pdf提升体验

在使用vue-pdf的过程又遇到了各种坑,如下:

坑1: css资源解析报错

在按照官方文档配置完后,打包发现报如下错误:

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'
      },

坑2: webpcak配置问题

配置完上述问题后继续报错:

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' //加了这行
  },

坑3: 版本问题

配置完上述问题后继续继续报错:

TypeError: Cannot read properties of undefined (reading 'catch')

解决: 版本问题 锁定版本

  npm i pdfjs-dist@2.5.207 
  npm i vue-pdf@4.2.0

坑4: 签章不显示

终于把报错解决完后,可以打开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'

坑5: 特殊字体不显示

解决完签章问题,发现某些特殊字体不显示了

解决: 配置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还是很方便的

文章来源:https://blog.csdn.net/ppfxdj/article/details/135221208
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。