PDF预览完整解决方案及各种兼容(VUE版)

news2025/8/8 15:33:41

PDF预览完整解决方案及各种兼容(VUE版)

PDF预览完整解决方案及各种兼容(VUE版) - 掘金

前端学习使者正在上传…重新上传取消

2021年11月12日 16:57 ·  阅读 2547

一、利用iframe

就一行代码就够了,只能满足最基本的浏览,且会出现很多问题。

<iframe src="Url" style="width:100%;height:100%" frameborder="0"></iframe>
复制代码

**问题一缓存问题:**利用iframe打开pdf后,当再次利用iframe打开另一个pdf时会显示第一份pdf,原因是浏览器对url的缓存处理。

**解决办法:**给url加时间戳或随机数,这样就没有缓存问题了。

    const fresh=new Date().getTime();//时间戳    this.url = this.url+'?'+ fresh; // 初始化查看pdf应用地址
复制代码

**问题二使用base64url问题:**有些pdf的url采用base64格式,直接将base64格式url放进src中可能会报错导致显示不了。原因是base64地址太长,浏览器不支持。

**解决办法:**利用Blob转base64url成文件路径.

  var bstr = window.atob(_this.baseUrl); //解码  var n = bstr.length;  var u8arr = new Uint8Array(n);  while (n--) {  u8arr[n] = bstr.charCodeAt(n); //转二进制  }  let blob = new Blob([u8arr], { type: 'application/pdf' }); //用blob生成pdf文件,返回PDF文件  this.url = window.URL.createObjectURL(blob); //得到的文件路径url
复制代码

**问题三特殊字体和水印无法显示:**这里采用插件的形式解决

二、利用vue-pdf插件

这里以VUE框架为例。vue-pdf是基于pdfjs-dist插件的vue封装。不是vue框架可以去找pdfjs-dist对应的封装或者直接用pdfjs-dist,不过pdfjs-dist使用稍微复杂些。

第一步 安装 npm install --save vue-pdf
第二部引入注册 
import VuePdf from "vue-pdf";
export default {
components: {
VuePdf,
},
第三步 使用
<VuePdf  src="PDFurl" : />
上面是最简单的使用方式,只能显示第一页的pdf,满足不了大部分需求,现在增加功能

模板里
<VuePdf  v-for="i in numPages" :key="i" :src="url" :page="i" />
下面方法在mounted里面使用
    // PDF初始化    getNumPages() {      let loadingTask = VuePdf.createLoadingTask(this.url,      );      loadingTask.promise.then(pdf => {        this.numPages = pdf.numPages;      }).catch(err => {        console.error('pdf 加载失败', err);      })    },numPages、url在data里面定义为空,在getNumPages()调用前将路径赋值给this.url
复制代码

这样就可以得到一个可以pdf的全部内容,pdf放大缩小翻页就不赘述了百度很多

PDF下载

<div @click="down(pdfName)">下载</div>
//需要两个参数 pdfName 和 pdf的base64地址。
在调用方法前将pdf的base64地址赋值给this.baseUrl就可以调用方法下载。
    down(pdfName){      
const fileName = pdfName;      
let byteCharacters = atob(this.baseUrl);      
let byteNumbers = new Array (byteCharacters.length);      
for (var i = 0; i < byteCharacters.length; i++) {        
byteNumbers[i] = byteCharacters.charCodeAt(i);      
}      
let byteArray = new Uint8Array ( byteNumbers);       
let blob = new Blob([byteArray], { type:"application/pdf"});      
if (navigator.msSaveOrOpenBlob) {         
navigator.msSaveBlob(blob,fileName);      
}else{        
let link = document.createElement("a");        
link.href = window.URL.createObjectURL(blob);        
link.download = fileName;        
document.body.appendChild(link);        
link.click();        
document.body.removeChild(link);        
window.URL.revokeObjectURL(link.href);      
}    
},
复制代码

VUE-PDF出现问题一:部分pdf水印不显示

解决办法
+ 步骤一 在node_modules/pdfjs-dist/build/pdf.worker.js注释掉一行代码
+ if (data.fieldType === "Sig") {
+      data.fieldValue = null;+      // 注释掉底下这行 就可以显示电子签章
+      // this.setFlags(_util.AnnotationFlag.HIDDEN);+ }
+ 步骤二 在node_modules/pdfjs-dist/es5/build/pdf.worker.js注释掉一行代码
+ if (data.fieldType === "Sig") {+    data.fieldValue = null;
+      // 注释掉底下这行 就可以显示电子签章+      // _this4.setFlags(_util.AnnotationFlag.HIDDEN);
+  }
复制代码

问题又来了,在node_modules里面改动文件下一次打包或者项目上线就行不通了。

这里采用把vue-pdf项目文件放在服务器tomcat的一个文件夹下。项目里用iframe来直接跳转的形式来显示

<iframe  :src="iframeUrl" frameborder="0"></iframe>    
const fresh=new Date().getTime();//时间戳    
this.iframeUrl = location.origin + "/pdf/index.html"+'?'+ fresh; // 初始化查看pdf应用地址
复制代码

那么在服务器下的vue-pdf文件如何得到项目上传过来的PDF信息呢,这里采用indexDB数据库。这里不推荐使用cookies和localStorage的形式存储数据,因为PDF数据可能会很大,另外两种形式容量不够。

IndexDB存储PDF需要的信息

     在上线项目里使用
 /**          *@param url pdf地址          
*@param baseUrl pdfbase64地址          
* @param fileName 文件名          
**/        
setIndexDB(url,baseUrl,fileName){            
// 创建indexDB数据库          //pdfDB          
var request = window.indexedDB.open('pdfData');          
request.onerror = function() {                  
console.log('数据库打开失败');          };            
request.onsuccess = function(e) {              
var pdfDB= e.target.result;              
var store = pdfDB.transaction('workers','readwrite').objectStore('workers');               
store.put({ id: 1, pdfUrl: url,baseUrl:baseUrl,pdfName:fileName});            
};            
request.onupgradeneeded =  function(e){                
// 在数据库中创建该对象空间,workers相当于表的名字                
e.target.result.createObjectStore('workers', {keyPath:'id'});            
}          
},
复制代码

在vue-pdf里面获取存储的数据

    getPdfUrl() {      const _this = this;      const request = window.indexedDB.open("pdfData");      request.onerror = function () {        console.log("数据库打开失败");      };      request.onsuccess = function (e) {        //  var store = e.target.result.transaction('workers','readwrite').objectStore('workers');        //  store.put({id:1,pdfUrl:"2.pdf",pdfName:"",baseUrl:"",pathType:"路径形式"})       const readPDF = e.target.result          .transaction(["workers"])          .objectStore("workers")          .get(1);        readPDF.onsuccess = () => {          if (readPDF.result) {            _this.url = readPDF.result.pdfUrl;            _this.baseUrl = readPDF.result.baseUrl;            _this.pdfName = readPDF.result.pdfName;              var bstr = window.atob(_this.baseUrl); //解码              var n = bstr.length;              var u8arr = new Uint8Array(n);              while (n--) {              u8arr[n] = bstr.charCodeAt(n); //转二进制              }              let blob = new Blob([u8arr], { type: 'application/pdf' }); //用blob生成pdf文件,返回PDF文件              let path = window.URL.createObjectURL(blob);              _this.iframeUrl = path; // 初始化查看pdf应用地址              _this.getNumPages();                      } else {            console.log("未获得数据记录");          }        };      };      request.onupgradeneeded = function (e) {        // 在数据库中创建该对象空间,workers相当于表的名字,表名不可随意更改        e.target.result.createObjectStore("workers", { keyPath: "id" });      };    },
复制代码

具体indexDB看文档www.ruanyifeng.com/blog/2018/0…

vue-pdf项目例子看gitee.com/tianguai/vu…

问题二:字体缺失

VUE-PDF会有一些特殊字体显示不了,这是由于node_modules/pdfjs-dist/cmaps路径下没有对应的字体文件

解决方法:在vue-pdf项目例子中加入以下代码,这里引入外部字体库。

    computed: {
           pdfSrc(){
            //处理pdfUrl返回
             let src =  pdf.createLoadingTask({
               url: this.pdfUrl,
               //引入pdf.js字体,templ
               cMapUrl: 'https://cdn.jsdelivr.net/npm/pdfjs-dist@2.5.207/cmaps/',
               cMapPacked: true
             })
               return src ;
           }
         }
复制代码

但我们公司项目包含了非常多的不同字体,还是满足不了需求,我采用了浏览器默认查看pdf方式和插件方式两种同时使用,可以解决99%的需求啦。不过使用插件形式的pdf不要超过200页,不然会加载时间过长导致打不开。

效果图,哈哈有跟没有一样

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/34291.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】vector的使用与题目练习

文章目录一、前言二、构造函数三、遍历四、增删查改1.常用接口2.增删查改五、经典题目一、前言 学习完string类之后&#xff0c;我们在来学习vector难度并没有之前那么高&#xff0c;更加容易理解一些接口 vector是表示可变大小数组的序列容器 &#xff0c;本质讲&#xff0c;v…

【基于stm32 FreeRtos的智能台灯】

基于stm32 FreeRtos的智能台灯控制 之前做了一个裸机版本的智能台灯&#xff0c;最近刚好复习一下FreeRto的一些基础知识&#xff0c;朋友发给了我一个功能需求刚好用来实践一下&#xff0c;需要的朋友可以自行下载。 链接&#xff1a;https://pan.baidu.com/s/1Ovn1ILgvDWWzeC…

Java项目:JSP会议-会议室管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目包含两个角色&#xff0c;管理员与用户角色&#xff1b; 管理员角色包含以下功能&#xff1a; 查看预订,查看会议,部门管理,员工注册,添…

Driud数据库连接池的使用

Driud数据库连接池的使用 简介&#xff1a;本文通过简洁的代码&#xff0c;让大家快速熟悉Driud数据库连接池的使用。 数据库连接池简介 数据库连接池是个容器&#xff0c;负责分配、管理数据库连接(Connection) 它允许应用程序重复使用一个现有的数据库连接&#xff0c;而不…

ROS-Unity连接教程

本篇文章主要介绍基于ROS-TCP-Connector、ROS-TCP-Endpoint两个Unity接口与ROS进行通信的环境配置&#xff0c;并对官方给出的Unity和ROS相互通信示例中的消息部分做了说明 一、环境配置 参考&#xff1a;Unity-Robotics-Hub/setup.md at main Unity-Technologies/Unity-Rob…

【机器学习】拟合优度度量和梯度下降(红酒数据集的线性回归模型sklearnRidge)

文章目录一.拟合优度度量&#xff08;可决系数&#xff09;1.1总离差平方和的分解1.2 TSSESSRSS1.3 红酒数据集实例R2_score实现代码二. 梯度下降2.1 损失函数直观图(单特征/变量举例)2.2 梯度下降和正规方程的区别2.3 线性回归模型——梯度下降 &#xff08;红酒数据集&#x…

天宇优配|混动车将告别上海免费绿牌 新能源多种技术路

现在订车还来得及吗&#xff1f;这是上海购置混动新能源车群体当下最关怀的问题。根据方针要求&#xff0c;上海关于混动车的免费绿牌支持将于本年年底结束。这意味着&#xff0c;再过一个多月&#xff0c;在上海购买插电式混合动力&#xff08;含增程式&#xff09;轿车将依照…

同事问我为什么上级喊他把js实现改成css

文章目录页面绘制流程CSS3动画优点缺点JS动画优点缺点总结本人不是专门写前端的&#xff0c;所以可能有不合理的地方&#xff0c;建议您多搜几篇博客看一下。页面绘制流程 渲染流程主要有4个步骤 解析 HTML 生成DOM 树解析 CSS 样式生成 CSSOM 树&#xff0c;CSSOM 树与 DOM …

Verilog 条件语句

link 我用的是 vivado 21 秒学会 vivado 仿真 关键词&#xff1a;if&#xff0c;选择器 条件语句 条件&#xff08;if&#xff09;语句用于控制执行语句要根据条件判断来确定是否执行。 条件语句用关键字 if 和 else 来声明&#xff0c;条件表达式必须在圆括号中。 条件语句使…

【网络篇】第十六篇——再谈端口号

再谈端口号 端口号范围划分 认识知名端口号 两个问题 netstat pidof 再谈端口号 端口号(Port)标识了一个主机上进行通信的不同的应用程序&#xff1b; 从网络中获取的数据在进行向上交付时&#xff0c;在传输层就会提取出该数据对应的目的端口号&#xff0c;进而确定该数据…

159-170-Hadoop-调优-hdfs-yran-综合

159-Hadoop-调优-hdfs故障排查&#xff1a; HDFS**—故障排除**&#xff08;此处了解&#xff0c;一般使用HA&#xff09; NameNode 故障处理 1&#xff09;需求&#xff1a; NameNode 进程挂了并且存储的数据也丢失了&#xff0c;如何恢复 NameNode 2&#xff09;故障模拟…

42、集合的第一大类:List

一、基本介绍&#xff1a; 1、List接口和常用方法 &#xff08;1&#xff09;List接口基本介绍&#xff1a; List接口是Collection接口的子接口 1&#xff09;List集合类中元素有序&#xff08;即添加顺序和取出顺序一致&#xff09;&#xff0c;且可重复 2&#xff09;Li…

第五章TCP/IP 我们网络在我们身边

个人简介&#xff1a;云计算网络运维专业人员&#xff0c;了解运维知识&#xff0c;掌握TCP/IP协议&#xff0c;每天分享网络运维知识与技能。个人爱好: 编程&#xff0c;打篮球&#xff0c;计算机知识个人名言&#xff1a;海不辞水&#xff0c;故能成其大&#xff1b;山不辞石…

GOT Online For Unreal | 支持GPU Counter、DrawCall和Triangle、功率

UWA GOT Online For Unreal 新功能上线&#xff0c;马上分享&#xff1a; 在GOT Online - Overview模式中&#xff0c;新增了GPU Counter、DrawCall、Triangle和功率数据采集等&#xff0c;同时也对新增了便于报告上传和查看的API接口&#xff0c;以便开发者在查看报告时可以更…

计算机组成原理4小时速成:存储器容量扩展:位扩展,字扩展,存储器与cpu链接,地址线,数据线,片选线,控制线,汉明码编码,奇偶校验

计算机组成原理4小时速成&#xff1a;存储器容量扩展&#xff1a;位扩展&#xff0c;字扩展&#xff0c;存储器与cpu链接&#xff0c;地址线&#xff0c;数据线&#xff0c;片选线&#xff0c;控制线&#xff0c;汉明码编码&#xff0c;奇偶校验 2022找工作是学历、能力和运气…

[附源码]java毕业设计游戏装备交易网站论文2022

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

项目管理中,如何应对需求蔓延?

项目管理中&#xff0c;需求蔓延几乎难以避免&#xff0c;控制不好所产生的后果不言而喻&#xff0c;轻则增加工作量&#xff0c;造成项目延期&#xff1b;重则导致方案不完善&#xff0c;导致交付质量难以保证&#xff0c;使项目失败&#xff0c;因此我们要做好充分的准备。 …

硬盘分区管理软件,硬盘分区软件哪个好用

磁盘分区是很高频的磁盘管理方式&#xff0c;但是&#xff0c;很多的用户又不知道磁盘分区&#xff0c;只能借助于专业的磁盘分区大师。那么&#xff0c;在本文中&#xff0c;易我小编将讲解磁盘分区的知识&#xff0c;并且为大家介绍一款超实用的硬盘分区管理软件。 一、电脑磁…

基于fastai 1.0.61的SSD目标检测算法 代码详解 (一)

基于fastai的目标检测算法&#xff0c;主要是2018年course ① 2018 coursev2 : https://nbviewer.org/github/fastai/fastai1/tree/master/courses/ pascal.ipynb pacal_multi.ipynb SSD② jav fastai1.x SSD 没有mAP&#xff1a; https://github/jav0927/course-v3/blob/…

41、集合

一、基本介绍&#xff1a; 1、引入&#xff1a; &#xff08;1&#xff09;前面我们保存多个数据使用的是数组&#xff0c;但数组不足的地方有&#xff1a; 1&#xff09;长度开始时必须指定&#xff0c;而且一旦指定&#xff0c;不能更改 2&#xff09;保存的必须为同一类…