前言

关于前端预览pdf,最简单的方式是使用window.open() 直接在浏览器的新窗口打开就好,浏览器本身也是提供了非常多的功能

但是因为客户的某些需求,不能使用浏览器自身的功能。后来又使用了 https://github.com/gjTool/pdfh5,也挺好用的,操作比较简单。使用了一段时间吧,但是还是由于客户的某些需求,最终还是放弃了。

百度查询了一下可以使用 https://github.com/mozilla/pdf.js 来实现功能自定义。

pdfjs

官方文档、examples、API

https://mozilla.github.io/pdf.js/

安装

npm install pdfjs-dist

我的版本是3.0.279,不同版本可能有些不同。如果你是vue2加webpack的项目建议用2.6.347,因为我在老项目中用新版本遇到了各种各样的问题。

加载

<script setup lang="ts">
import { onMounted } from 'vue';
onMounted(async() => {const pdfjs = await import('pdfjs-dist/build/pdf.js');const pdfjsWorker = await import('pdfjs-dist/build/pdf.worker.entry');pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;console.log('pdf', pdfjs);// 加载pdf文件,本地文件会有跨域问题,使用线上文件const url = 'http://....2022-11-07/69c075093c9942dea7dcf86ac691ff9d.pdf';pdfjs.getDocument(url).promise.then(pdfDoc => {console.log('内容:', pdfDoc, pdfDoc.numPages);});
});
</script>

必须异步加载,不然会报错。解决方案来源于:https://github.com/mozilla/pdf.js/issues/10478

渲染

每个PDF页面都有自己的视口,它定义了以像素为单位的大小(72DPI)和初始旋转。默认情况下,视口缩放为PDF 的原始大小,但这可以通过修改视口来更改。创建视口时,还将创建一个初始变换矩阵,该矩阵考虑了所需的比例、旋转,并变换坐标系(PDF中的 0,0 点记录在左下角,而画布 0,0 在左上角)。

<template><div><div class="tool-bar"><div>{{ pdfParams.pageNumber }} / {{ pdfParams.total }}</div><el-button type="primary" :disabled="pdfParams.pageNumber == pdfParams.total" @click="nextPage">下一页</el-button><el-button type="primary" :disabled="pdfParams.pageNumber == 1" @click="prevPage">上一页</el-button><el-button type="primary" @click="rotatePage">旋转</el-button><el-button type="primary" :disabled="pdfParams.scale==5" @click="toBig">放大</el-button><el-button type="primary" :disabled="pdfParams.scale==1" @click="toSmall">缩小</el-button></div><canvas id="pdf-render"></canvas></div>
</template><script setup lang="ts">
import { onMounted, reactive } from 'vue';const pdfParams = reactive({pageNumber: 1, // 当前页total: 0, // 总页数scale: 1, // 缩放rotate: 0 // 旋转角度
});// 不要定义为ref或reactive格式,就定义为普通的变量
let pdfDoc = null;onMounted(async() => {const pdfjs = await import('pdfjs-dist/build/pdf.js');const pdfjsWorker = await import('pdfjs-dist/build/pdf.worker.entry');pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker;// 加载pdf文件,本地文件会有跨域问题,下面这个地址是不对的,自行更换const url = 'http://y2/2022-11-07/69c075093c9942dea7dcf86ac691ff9d.pdf';pdfjs.getDocument(url).promise.then(doc => {pdfDoc = doc;console.log('内容:', doc, doc.numPages);pdfParams.total = doc.numPages;getPdfPage(1);});
});// 加载pdf的某一页
const getPdfPage = (number) => {pdfDoc.getPage(number).then((page) => {console.log('page:', page);// 获取视图,并设置缩放const viewport = page.getViewport({scale: pdfParams.scale, // 缩放rotation: pdfParams.rotate // 旋转});console.log('视图:', viewport);const outputScale = window.devicePixelRatio || 1;// 获取canvasconst canvas = document.getElementById('pdf-render');const context = canvas.getContext('2d');// 设置canvas的宽高canvas.width = Math.floor(viewport.width * outputScale);canvas.height = Math.floor(viewport.height * outputScale);canvas.style.width = Math.floor(viewport.width) + 'px';canvas.style.height = Math.floor(viewport.height) + 'px';// 渲染pdfvar renderContext = {canvasContext: context,viewport: viewport};page.render(renderContext);});
};
// 前一页
const prevPage = () => {if (pdfParams.pageNumber > 1) {pdfParams.pageNumber -= 1;} else {pdfParams.pageNumber = 1;}// 重新渲染getPdfPage(pdfParams.pageNumber);
};
// 下一页
const nextPage = () => {if (pdfParams.pageNumber < pdfParams.total) {pdfParams.pageNumber += 1;} else {pdfParams.pageNumber = pdfParams.total;}// 重新渲染getPdfPage(pdfParams.pageNumber);
};// 旋转
const rotatePage = () => {pdfParams.rotate += 90;// 重新渲染getPdfPage(pdfParams.pageNumber);
};
// 放大
const toBig = () => {if (pdfParams.scale < 5) {pdfParams.scale += 0.5;} else {pdfParams.scale = 5;}// 重新渲染getPdfPage(pdfParams.pageNumber);
};
// 缩小
const toSmall = () => {if (pdfParams.scale > 1) {pdfParams.scale -= 0.5;} else {pdfParams.scale = 1;}// 重新渲染getPdfPage(pdfParams.pageNumber);
};
</script><style lang="scss" scoped>
.tool-bar {position: fixed;z-index: 200;left: 200px;
}
</style>

效果

补充

注意:

可以修改的属性如下图:

1、其他属性都比较好理解,transformviewBox 暂时没有弄明白,不建议修改
2、旋转属性:rotation ,如果使用pdfjs提供的方式进行旋转的话要注意旋转的角度必须是90的整数倍。
3、放大的最大倍数是5被

下载
关于下载的功能我没有写,有需要的可以使用FileSaver.js,基本使用见我的这篇文章:FileSaver.js的简单使用

打印
打印功能有需要的话可以看我的这篇文章:前端使用print.js实现打印

前端pdf预览、pdfjs的使用相关推荐

  1. 前端实现 PDF 预览的常见方案

    前端实现 PDF 预览的常见方案 由于在搭建个人博客时,想实现在线预览 pdf 格式的个人简历,经过查阅大致有三大类实现方案:本文共涉及以下 5 种实现方案,如下所示: 使用 HTML 标签 ifra ...

  2. PDF.js + Vue 浏览器以只读方式打开PDF,后台返回文件流,前端实现预览pdf

    如果你想光前端完成 office(xls,doc,ppt) 文件的预览,只能提供你这些库来使用 PDF http://mozilla.github.com/pdf.js/ XLS https://gi ...

  3. 前端在线预览PDF文件

    如何在vue项目中预览PDF格式的文件 需求:在vue3.x项目中预览pdf文件 提供以下三种方案: 1.Vue-pdf:适用于vue2.x版本,vue3.x需要改一些源码(vue2.x项目极力推荐, ...

  4. vue中前端实现pdf预览(含vue-pdf插件用法)

    场景:前端需要根据后端返回的线上pdf的地址,实现pdf的预览功能. 情况一:后端返回的pdf地址,粘贴到浏览器的url框中,是可以在浏览器中直接进行预览的. 方法(1)可以直接使用window.op ...

  5. 前端在线预览word,excel,pdf

    前端在线预览word,excel,pdf 预览Word 预览pdf 预览Excel 预览Word 微软的在线预览功能,可以预览word.ppt.Excel.PDF 局限: 需要外网能访问文件,如果是只 ...

  6. Vue前端JavaScript实现PDF预览与图片预览

    Vue前端JavaScript实现PDF预览与图片预览 说明 PDF.JS 代码实现 预览测试 embed与iframe标签 `<embed>` `<iframe>` 浏览器预 ...

  7. vueCli3.0文件上传后,后端返回流,前端转换成pdf预览的3种方式

    第一种是用: <iframe> 嵌套显示 先上效果图: 注:这种还带样式的是我后面修改源码的 js添加的 :   customToolbar.js //创建一个新样式 let sheet ...

  8. 通过pdfjs实现在VUE-CLI中进行PDF预览,并禁用打印及下载功能

    pdfjs 官网:PDF.js 官方demo:PDF.js viewer 安装使用 下载 点击下载 选择稳定版本 项目引入 本文主要针对vue-cli4版本的文件 在public文件夹下新建pdfjs ...

  9. PDF 预览和下载你是怎么实现的?

    在开发过程中要求对 PDF 类型的发票提供 预览 和 下载 功能,**PDF** 类型文件的来源又包括 H5 移动端 和 **PC 端**,而针对这两个不同端的处理会有些许不同,下文会有所提及. 针对 ...

最新文章

  1. 搭建一个VUE+Express前后端分离的开发环境
  2. MVC5 数据注解和验证
  3. Hadoop/Spark相关面试问题总结
  4. android config.mk,android编译分析之10—config.mk
  5. java邮件实例_java邮件小实例
  6. php redis与me m,Redis(十) —— 为php增加redis扩展
  7. debian9为什么默认是pip2_VirtualBox内刚刚安装完Debian9系统,也无法设置共享文件夹。解决的方法就是安装VirtualBox客户端增强包。...
  8. 唤醒屏幕_小度在家VS天猫精灵CC 屏幕正在让智能音箱进入下一版本
  9. MOS管及MOS管的驱动电路设计
  10. c++ 插入排序算法
  11. Python Shutil模块
  12. Java编程:排序算法——插入排序
  13. BN、LN、IN、GN和SN
  14. 【随笔】hi3531D 音频
  15. 鸟哥linux私房菜读后,鸟哥的Linux私房菜读书笔记(1)
  16. 世界第4疯狂的科学家,在103岁生日那天去世了
  17. 为什么桌面上的计算机打不开怎么办,怎么解决电脑桌面图标打不开
  18. Python 中文数字对照表 输入一个数字,转换成中文数字。比如:1234567890 -> 壹贰叁肆伍陆柒捌玖零。【简单易懂,代码可以直接运行】
  19. 群晖emby服务端下载(弃坑,官网已经能顺畅访问)
  20. Hydra(九头蛇)弱口令

热门文章

  1. 基于Spring Boot+Shiro+Thymeleaf+MyBatis支付系统+微信商城 源码
  2. springboot集成Hutool工具类库-hutool-core
  3. Mall整合RabbitMQ
  4. 网络与串口调试工具TCPCOM
  5. 分享几个精美的个人简历模板,非常不错的简历,docx格式的可直接修改。
  6. 成都中考生专门学计算机哪个学校好,「计算机网络技术专业」2021年成都哪所计算机网络技术专业学校好_学校推荐...
  7. ai推理_人工智能推理
  8. Linux下安装EPSON L310打印机驱动
  9. 【web前端特效源码】使用 HTMLCSSJavaScript实现各种跳跃浮动慢跑翻转旋转坠落的魔幻文字动画效果~太上头了~/动画效果|前端开发|IT软件开发基础入门教程|网页制作|网站开发定制
  10. springCloud euraka配置