vue3移动端实现pdf预览

第一种方式:使用vue-pdf-embed和vue3-pdfjs

使用的插件有:

npm i vue-pdf-embed
npm i vue3-pdfjs

html部分:

	  <div ref="preRef" v-loading="loading" class="pdf-preview"><div v-if="pdfState.source" class="pdf-wrap"><VuePdfEmbedv-for="item in pdfState.numPages":key="item":source="pdfState.source":style="pdfState.scale"class="vue-pdf-embed":page="item"/></div><van-empty v-if="loadError" image="error" description="PDF加载出错了..." /></div>

js部分:

// 引入两个插件相关的
import VuePdfEmbed from 'vue-pdf-embed';
import { createLoadingTask } from 'vue3-pdfjs';
// 以上涉及的参数
const pdfState = reactive({source: '', // 预览pdf文件地址pageNum: 1, // 当前页面scale: 1, // 缩放比例numPages: 0, // 总页数width: '400px', // 宽度
});
const preRef = ref();
const detail = ref({});//返回的数据
const loading = ref(true);
const loadError = ref(false);//  方法
//  接口返回的数据
function getDetail() {baseInfoGet({ id: route.currentRoute.value.query.id }).then((res) => {detail.value = res.data;const url = safeJSONParse(res.data.fileUrl)?.[0].url || '';pdfState.source = url;console.log('预览地址:', url);if (!url) return;setTimeout(() => {pdfState.width = getComputedStyle(preRef.value)?.width;console.log(pdfState.width);loadingPdf(url);}, 0.5 * 1000);});
}
// 加载pdf的方法
function loadingPdf(url) {const loadingTask = createLoadingTask(url);loadingTask.promise.then((pdf) => {pdfState.numPages = pdf.numPages;loading.value = false;}).catch(() => {loading.value = false;loadError.value = true;});
}

我一开始使用的时第一种方法,然后测试之后发现苹果手机会显示pdf加载出错了,安卓手机可以正常显示,于是换成了第二种方法。
在这里插入图片描述

第二种方式使用pdfjs-dist,苹果手机加载失败需使用版本2.2.228

npm i pdfjs-dist

html部分:

      <div class="pdf-viewer"><template v-for="item in pageNum" :key="item"><canvas :id="`pdf-canvas-${item}`" class="pdf-page" /></template><van-emptyv-if="loadError"image="error"description="PDF加载出错了..."/></div>

js部分:

// 引入插件相关的参数
import * as pdfjs from 'pdfjs-dist';
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry';
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;// html部分涉及的参数
const loadError = ref(false);
const detail = ref({});
let pdfDoc = null; // 一定不能使用响应式的数据,会报错Cannot read from private field---pdf.js
const pageNum = ref(0);
// 处理接口返回的pdf的url
function getDetail() {baseInfoGet({ id: route.currentRoute.value.query.id }).then((res) => {detail.value = res.data;const url = safeJSONParse(res.data.fileUrl)?.[0].url || '';showLoadingToast({message: '加载中...',forbidClick: true,});console.log('预览地址:', url);if (!url) return;loadingPdf(url);});
}
//加载pdf
function loadingPdf(url) {const loadingTask = pdfjs.getDocument(url);loadingTask.promise.then((pdf) => {pdfDoc = pdf;pageNum.value = pdf.numPages;nextTick(() => {renderPage();});}).catch(() => {closeToast();loadError.value = true;});
}
// 渲染pdf
function renderPage(num = 1) {pdfDoc.getPage(num).then((page) => {const canvas = document.getElementById(`pdf-canvas-${num}`);const ctx = canvas.getContext('2d');const scale = 1.5;const viewport = page.getViewport({ scale });// 画布大小,默认值是width:300px,height:150pxcanvas.height = viewport.height;canvas.width = viewport.width;// 画布的dom大小, 设置移动端,宽度设置铺满整个屏幕const { clientWidth } = document.body;// 减去2rem使用因为我的页面左右加了paddingcanvas.style.width = `calc(${clientWidth}px - 2rem)`;// 根据pdf每页的宽高比例设置canvas的高度canvas.style.height = `${clientWidth * (viewport.height / viewport.width)}px`;canvas.height = viewport.height;canvas.width = viewport.width;page.render({canvasContext: ctx,viewport,});if (num < pageNum.value) {renderPage(num + 1);} else {closeToast();}});
}

用了第二种插件后,苹果手机还是加载不出来,后面查到因为pdfjs-dist有时候会出现部分手机比如iphone6和iphone8渲染不出pdf问题

解决办法:
将pdfjs-dist版本改为2.2.228

npm i  pdfjs-dist@2.2.228

然后就加载出来了,最后在各个环境测试的时候又发现,微信小程序里面打开这个模块,pdf还是没加载出来,console之后发现请求401,报错信息是登陆访问超时,发现pdfjs加载pdf时没有携带token
遂,在加载url时添加token即可

pdfjs加载pdf时携带token

//加载pdf
function loadingPdf(url) {const afterUrl = {url,httpHeaders: {token: `Bearer-${localStorage.getItem('token')}`,},};const loadingTask = pdfjs.getDocument(afterUrl );loadingTask.promise.then((pdf) => {pdfDoc = pdf;pageNum.value = pdf.numPages;nextTick(() => {renderPage();});}).catch(() => {closeToast();loadError.value = true;});
}

添加之后就加载出来了

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++算法学习心得五.二叉树(3)

1.合并二叉树&#xff08;617题&#xff09; 题目要求&#xff1a; 给定两个二叉树&#xff0c;想象当你将它们中的一个覆盖到另一个上时&#xff0c;两个二叉树的一些节点便会重叠。 你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠&#xff0c;那么将他们…

Vue面试之组件通信的方式总结(下篇)

Vue面试之组件通信的方式总结 $refprovide&injectprovideinject EventBus事件总线vuex 最近在整理一些前端面试中经常被问到的问题&#xff0c;分为vue相关、react相关、js相关、react相关等等专题&#xff0c;可持续关注后续内容&#xff0c;会不断进行整理~ 在Vue框架中&…

CSS 选择器全攻略:从入门到精通(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

制造领域 基础概念快速入门介绍

1、基本背景知识 本定义结合国家标准文件有所发挥&#xff0c;仅供参考。 产品&#xff1a;是生产企业向用户或市场以商品形式提供的制成品&#xff1b; 成套设备&#xff1a;在生产企业一般不用装配工序连接&#xff0c;但用于完成相互联系的使用功能的两个或两个以上的产…

Redis面试篇

redis面试题主要内容 面试官在面试时主要会问以下这些方面的问题 下面是一些问题示例&#xff1a; redis-使用场景 缓存 缓存穿透 介绍 缓存穿透&#xff1a;查询一个不存在的数据&#xff0c;mysql查询不到数据也不会直接写入缓存&#xff0c;就会导致每次请求都会去查数…

Java填充Execl模板并返回前端下载

功能&#xff1a;后端使用Java POI填充Execl模板&#xff0c;并返回前端下载 Execl模板如下&#xff1a; 1. Java后端 功能&#xff1a;填充模板EXECL,并返回前端 controller层 package org.huan.controller;import org.huan.dto.ExcelData; import org.huan.util.ExcelT…

c++qt-基本组件

1. Designer 设计师&#xff08;掌握&#xff09; Qt包含了一个Designer程序&#xff0c;用于通过可视化界面设计开发界面&#xff0c;保存的文件格式为.ui&#xff08;界面文件&#xff09;。界面文件内部使用xml语法的标签式语言。 在Qt Creator中创建项目时&#xff0c;选中…

Elasticsearch倒排索引详解

倒排索引&#xff1a; 组成 term index(词项索引 &#xff0c;存放前后缀指针) Term Dictionary&#xff08;词项字典&#xff0c;所有词项经过文档与处理后按照字典顺序组成的一个字典&#xff08;相关度&#xff09;&#xff09; Posting List&#xff08;倒排表&#xf…

Logback框架基本认识

文章目录 一.什么是Logback1.1 初识Logbcak 二.Logbcak的结构三.日志的级别四.配置组件详解4.1 logger 日志记录器属性的介绍如何在配置文件里配置 4.2 appender 附加器 配合日志记录器的输出格式4.2.1 控制台附加器4.2.2 文件附加器4.3.3滚动文件附加器 4.3 Filter: 过滤器&am…

Python-基础语法

标识符 第一个字符必须是字母表中字母或下划线 _ 。标识符的其他的部分由字母、数字和下划线组成。标识符对大小写敏感。在 Python 3 中&#xff0c;可以用中文作为变量名&#xff0c;非 ASCII 标识符也是允许的了。 python保留字 保留字即关键字&#xff0c;我们不能把它们用…

【开源】基于JAVA+Vue+SpringBoot的大病保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统配置维护2.2 系统参保管理2.3 大病保险管理2.4 大病登记管理2.5 保险审核管理 三、系统详细设计3.1 系统整体配置功能设计3.2 大病人员模块设计3.3 大病保险模块设计3.4 大病登记模块设计3.5 保险审核模块设计 四、…

[嵌入式软件][入门篇] 搭建在线仿真平台(STM32)

文章目录 一、注册平台二、创建首个项目三、硬件介绍 一、注册平台 进入官方&#xff0c;进行注册&#xff1a; 在线仿真地址 二、创建首个项目 ① 新建项目 ② 搭建一个电路 ③ 用STM32F103搭建一个简单电路 ④ 进入编码界面 三、硬件介绍 红框是必看文档&#xff…