Vue+pdfjs+turn.Js实现pdf翻页预览效果

  • 项目新需求要求实现预览用户上传的pdf文件并且要有翻书效果。 找了很多文章参考,最终使用pdfjs+turn.Js实现。
  1. 安装pdfjs插件
sql 复制代码
npm install pdfjs-dist@2.2.228 --legacy-peer-deps

2.在需要使用的页面引入

javascript 复制代码
import * as pdfjs from 'pdfjs-dist'
import * as pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry' 
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker
  1. 由于turn.js依赖JQ,所我们先安装JQ
css 复制代码
npm install jquery --save
  1. 配置JQ
  • 在vue.config.js中找到module.exports加入代码
css 复制代码
plugins: [
    new webpack.ProvidePlugin({
        jQuery: "jquery",
        $: "jquery"
    })],

结果如图:

5. 在需要使用的页面引用JQ(如果$报错可以试试在main.js中引入)

javascript 复制代码
import $ from 'jquery'
  1. 去官网下载turn.Js
  • 官网地址:www.turnjs.com/
  • 下载成功后解压包,将文件夹里的turn.js和turn.min.js引入项目。(我是放在utils文件夹里面,下图)
  1. 同样,在需要使用的页面中引入
arduino 复制代码
import turn from '@/utils/turn.js'
  1. 东西都准备好后,准备一个pdf文件(一般由后端接口返回,这里我使用的是本地文件)
  • 本地文件要放进public文件夹中,访问的时候使用"/static/xxx/xxx"的方式(如下图)
  1. 准备一个id为flipbook的盒子用来渲染pdf书(相当于一个书壳)里的的div盒子用来循环渲染这本书的每一页
ini 复制代码
<div id="flipbook">
    <div v-for="(item, index) in pdfPicturePath" :key="index" class="page" v-show="show">
        <img style="width: 100%; height: 100%" :src="item" />
    </div>
</div>

10.handlePdf函数。

  • 主要用来下载pdf。
  • 然后将pdf的每一页都转换成一张图片并将每一张图片放进一个数组中(pdfPicturePath)
  • 数据都准备好后就可以初始化turn.js生成一本书
ini 复制代码
// fileUrl = "/static/pdf/test.pdf" 这里是本地文件的地址
async handlePdf(fileUrl) {
        let that = this
        // 下载pdf文件
        const pdf = await pdfjs.getDocument(fileUrl); 
        const canvas = document.createElement('canvas');
        const context = canvas.getContext('2d');
        // 循环将pdf每一页转成图片后放入图片列表
        for (let i = 1; i <= pdf._pdfInfo.numPages; i++) {
            const page = await pdf.getPage(i);
            const viewport = page.getViewport({scale: 1});
            canvas.width = viewport.width;
            canvas.height = viewport.height;
            let renderContext = {
                canvasContext: context,
                viewport: viewport,
            };
            await page.render(renderContext).promise;
            let imgUrl = canvas.toDataURL('image/png')
            that.pdfPicturePath.push(imgUrl) 
        }
        this.show = true
        // 初始化turn.js生成一本书
        $("#flipbook").turn({
            acceleration: true, //启用硬件加速,移动端有效
            display: 'double', //显示:single=单页,double=双页,默认双页
            width: 375, // 书的宽度
            height: 627, // 书的高度
            autoCenter: true,
            turnCorners: 'bl,br', // 设置可翻页的页脚
        });
    },
  1. 最后在钩子函数里调用就好了。
  2. 如果想要点击"下一页""上一页"来翻页,那就直接放两个按钮分别添加点击事件。
javascript 复制代码
// 上一页
next() {
    $("#flipbook").turn("next");
},
// 下一页
previous() {
    $("#flipbook").turn("previous");
},
  1. 最终效果
  1. 附上整体代码
xml 复制代码
<template>
    <div>
        <div id="flipbook">
            <div v-for="(item, index) in pdfPicturePath" :key="index" class="page" v-show="show">
                <img style="width: 100%; height: 100%" :src="item" />
            </div>
        </div>
        <div style="margin-top: 2rem">
            <el-button type="" @click="next">下一页</el-button>
            <el-button type="" @click="previous">上一页</el-button>
        </div>
    </div>
</template>

<script>
import * as pdfjs from 'pdfjs-dist'
import * as pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry' 
pdfjs.GlobalWorkerOptions.workerSrc = pdfjsWorker
import $ from 'jquery'
import turn from '@/utils/turn.js'
export default {
  name: 'test_box1',
  data() {
    return {
        pdfPicturePath: [],
        fileUrl: '/static/pdf/test.pdf',
        show: false
    }
  },
  mounted() {   
    this.handlePdf(this.fileUrl)
  },
  methods:{
    next() {
        $("#flipbook").turn("next");
    },
    previous() {
        $("#flipbook").turn("previous");
    },
    async handlePdf(fileUrl) {
        let that = this
        const pdf = await pdfjs.getDocument(fileUrl);
        const canvas = document.createElement('canvas');
        const context = canvas.getContext('2d');
        for (let i = 1; i <= pdf._pdfInfo.numPages; i++) {
        const page = await pdf.getPage(i);
        const viewport = page.getViewport({scale: 1});
        canvas.width = viewport.width;
        canvas.height = viewport.height;
        let renderContext = {
            canvasContext: context,
            viewport: viewport,
        };
        await page.render(renderContext).promise;
        let imgUrl = canvas.toDataURL('image/png')
        that.pdfPicturePath.push(imgUrl)
        }
        this.show = true
        $("#flipbook").turn({
            width: 375,
            height: 627,
            display: 'single',
            autoCenter: true,
            turnCorners: 'bl,br',
        });
    }
  }
};
</script>
<style lang="scss" scoped="scoped">
    .hard{
        text-align: center;
    }
    .page {
        background: pink;
        text-align: center;
    }
</style>
相关推荐
Csvn2 小时前
OpenSpec 详细使用教程
前端
之歆2 小时前
Day19_LESS 完全指南——从入门到工程实践
前端·css·less
云水一下3 小时前
HTML5 从入门到精通:实战收官——从零搭建完整静态网站,综合运用所有知识
前端·html5
不总是3 小时前
Windows 系统 Node.js 免安装版(zip)安装与配置教程(2026 最新)
前端·windows·node.js
冬奇Lab3 小时前
每日一个开源项目(第105篇):Twenty - 跳出 Salesforce 的圈套,定义现代开源 CRM
前端·后端·开源
zhangyao9403304 小时前
开发pc端时,表格的高度怎么设置才能铺满页面
前端·javascript·elementui
XinZong5 小时前
实测OpenClaw虾淘:全民工具AI时代,冷门非工具类的Skill还能出圈吗?
javascript
kjs--5 小时前
浏览器书签执行脚本
前端
烛衔溟5 小时前
TypeScript 类的类型 —— 作为类型使用
javascript·ubuntu·typescript
之歆5 小时前
Day16_JavaScript 轮播图与事件工程实战(下篇)
服务器·开发语言·前端·javascript·网络·性能优化