如何实现前端网页实时预览PDF文件功能?

2026-05-06 00:081阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1484个文字,预计阅读时间需要6分钟。

如何实现前端网页实时预览PDF文件功能?

前言:这里用到了vue-pdf插件,实现了预览PDF相关的操作基本都有实现;我们需要做的就是各种布局(因为需要兼容已有布局,有的地方可能需要修改),例如翻页按钮,页面展示等。

前言

这里用到了vue-pdf插件,预览PDF相关的操作基本都有实现;

我们需要做的就是各种布局(因为需兼容已有的布局,有的地方可能需要修改),比如翻页按钮,页码展示等等;

vue-pdf的GitHub地址:FranckFreiburger/vue-pdf: vue.js pdf viewer (github.com)

目录
  1. 入门例子
  2. 展示所有页码
  3. 翻页操作
  4. 封装组件
  5. 完整代码
正文 1. 入门例子

安装命令:yarn add vue-pdf

最简单的入门例子,如下所示:

<template> <pdf src="/pdf/1.pdf"></pdf> </template> <script> import pdf from 'vue-pdf' export default { components: { pdf } }

关于本地文件的路径问题:

这里需要注意一下,要把pdf放在public目录下,然后通过/进行引用;

比如你的pdf路径为:public/pdf/1.pdf,那么src就要写成:/pdf/1.pdf

如果是远程路径,则直接赋值;

2. 展示所有页码

上面的入门例子只是展示了第一页的内容,其他内容没有展示,如果需要展示其他页,则需要添加翻页功能;

但是现在我们先简化,不添加翻页功能,而是用v-for直接展示所有的页码;

<template> <div> <pdf v-for="i in numPages" :key="i" :src="src" :page="i" style="display: inline-block; width: 25%" ></pdf> </div> </template> <script> import pdf from 'vue-pdf' var loadingTask = pdf.createLoadingTask('/pdf/1.pdf'); export default { components: { pdf }, data() { return { src: loadingTask, numPages: undefined, } }, mounted() { this.src.promise.then(pdf => { this.numPages = pdf.numPages; }); } } </script>

展示效果如下所示:

当我们的页码不是很多时,可以采用这种简单粗暴的方式进行展示,很方便;

但是如果页码过多,则不仅看起来很费劲,而且加载也会很慢,这时就需要用到翻页功能;

3. 翻页操作

这里主要增加两个按钮,以及相关属性,下面是部分代码:

<a-list-item> <div @click="changePdfPage('pre')" :style="currentPage===1?'cursor: not-allowed;':''"> 上一页 </div> </a-list-item> <a-list-item> <div @click="changePdfPage('next')" :style="currentPage===pageCount?'cursor: not-allowed;':''"> 下一页 </div> </a-list-item> <pdf :src="srcPdf" :page="currentPage" @num-pages="pageCount=$event" style="display: inline-block;width:100%"></pdf>

  • @num-pages 事件:获取pdf的总页数,这里获取到之后传给了pageCount
  • page 属性:就是当前页码,这里通过点击上一页和下一页来修改来更新页码

效果如下所示:

完整代码见下面;

4. 封装组件

为了方便使用,我们可以将上面的预览代码封装成功一个单文件组件,然后在需要的地方进行引入即可;

如何实现前端网页实时预览PDF文件功能?

封装后的组件代码贴到文末了,因为有点长:

我们在展示pdf文件时,可以通过跳转到新标签页的方式进行展示,这样组件内的布局不会有太大的变化;

跳转代码如下所示:

let routeUrl = this.$router.resolve({ path: '/preview-pdf', query:{pdfPath} }) window.open(routeUrl.href, '_blank')

  • /preview-pdf:这个路径就是配置在路由里面的,预览pdf的路径

  • pdfPath:这里我们是通过query的方式进行传参,然后在预览组件内通过 this.srcPdf = decodeURIComponent(this.$route.query.pdfPath)进行获取;

    • 因为存在编码问题,所以这里需要加上解码操作;

      如果pdf路径是.../xxx.pdf' // src: srcPdf, // 当前页数 currentPage: 0, // 总页数 pageCount: 0, // 加载进度 loadedRatio: 0 } }, methods: { // 页面回到顶部 toTop () { document.getElementById('container').scrollTop = 0 }, // 输入页码时校验 inputEvent () { if (this.currentPage > this.pageCount) { // 1. 大于max this.currentPage = this.pageCount } else if (this.currentPage < 1) { // 2. 小于min this.currentPage = 1 } }, // 切换页数 changePdfPage (val) { if (val === 'pre' && this.currentPage > 1) { // 切换后页面回到顶部 this.currentPage-- this.toTop() } else if (val === 'next' && this.currentPage < this.pageCount) { this.currentPage++ this.toTop() } else if (val === 'first') { this.currentPage = 1 this.toTop() } else if (val === 'last' && this.currentPage < this.pageCount) { this.currentPage = this.pageCount this.toTop() } }, // pdf加载时 loadPdfHandler (e) { // 加载的时候先加载第一页 this.currentPage = 1 }, } } </script> <style scoped> #container { overflow: auto; font-family: PingFang SC; width: 100%; display: flex; position: relative; } /* 功能按钮区 */ .right-btn { right:4rem; position: fixed; display: flex; flex-wrap: wrap; justify-content: center; z-index: 99; } .pdfArea { width: 80%; } /*在谷歌下移除input[number]的上下箭头*/ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none !important; margin: 0; } /*在firefox下移除input[number]的上下箭头*/ input[type='number'] { -moz-appearance: textfield; } .inputNumber { border-radius: 8px; border: 1px solid #999999; font-size: 18px; width: 2rem; text-align: center; } .inputNumber:focus { border: 1px solid #00aeff; background-color: rgba(18, 163, 230, 0.096); outline: none; transition: 0.2s; } </style>

      如何使用?

      先注册路由:src/router/index.js

      import MyPdf from '../components/MyPdf' export default new VueRouter({ routes: [ { path: '/apply-contract-pdf', name: 'apply-contract-pdf', component: MyPdf }, ]})

      再通过如下方法进行预览:

      previewPdf(pdfPath){ let routeUrl = this.$router.resolve({ path: '/preview-pdf', query:{pdfPath} }) window.open(routeUrl.href, '_blank') }, 总结

      本篇介绍了vue-pdf的一些简单使用,包括首页展示、分页展示等;

      其实还有一些进度条展示这里没列出来,感兴趣的可以配合a-progress组件和progress 属性进行体验

本文共计1484个文字,预计阅读时间需要6分钟。

如何实现前端网页实时预览PDF文件功能?

前言:这里用到了vue-pdf插件,实现了预览PDF相关的操作基本都有实现;我们需要做的就是各种布局(因为需要兼容已有布局,有的地方可能需要修改),例如翻页按钮,页面展示等。

前言

这里用到了vue-pdf插件,预览PDF相关的操作基本都有实现;

我们需要做的就是各种布局(因为需兼容已有的布局,有的地方可能需要修改),比如翻页按钮,页码展示等等;

vue-pdf的GitHub地址:FranckFreiburger/vue-pdf: vue.js pdf viewer (github.com)

目录
  1. 入门例子
  2. 展示所有页码
  3. 翻页操作
  4. 封装组件
  5. 完整代码
正文 1. 入门例子

安装命令:yarn add vue-pdf

最简单的入门例子,如下所示:

<template> <pdf src="/pdf/1.pdf"></pdf> </template> <script> import pdf from 'vue-pdf' export default { components: { pdf } }

关于本地文件的路径问题:

这里需要注意一下,要把pdf放在public目录下,然后通过/进行引用;

比如你的pdf路径为:public/pdf/1.pdf,那么src就要写成:/pdf/1.pdf

如果是远程路径,则直接赋值;

2. 展示所有页码

上面的入门例子只是展示了第一页的内容,其他内容没有展示,如果需要展示其他页,则需要添加翻页功能;

但是现在我们先简化,不添加翻页功能,而是用v-for直接展示所有的页码;

<template> <div> <pdf v-for="i in numPages" :key="i" :src="src" :page="i" style="display: inline-block; width: 25%" ></pdf> </div> </template> <script> import pdf from 'vue-pdf' var loadingTask = pdf.createLoadingTask('/pdf/1.pdf'); export default { components: { pdf }, data() { return { src: loadingTask, numPages: undefined, } }, mounted() { this.src.promise.then(pdf => { this.numPages = pdf.numPages; }); } } </script>

展示效果如下所示:

当我们的页码不是很多时,可以采用这种简单粗暴的方式进行展示,很方便;

但是如果页码过多,则不仅看起来很费劲,而且加载也会很慢,这时就需要用到翻页功能;

3. 翻页操作

这里主要增加两个按钮,以及相关属性,下面是部分代码:

<a-list-item> <div @click="changePdfPage('pre')" :style="currentPage===1?'cursor: not-allowed;':''"> 上一页 </div> </a-list-item> <a-list-item> <div @click="changePdfPage('next')" :style="currentPage===pageCount?'cursor: not-allowed;':''"> 下一页 </div> </a-list-item> <pdf :src="srcPdf" :page="currentPage" @num-pages="pageCount=$event" style="display: inline-block;width:100%"></pdf>

  • @num-pages 事件:获取pdf的总页数,这里获取到之后传给了pageCount
  • page 属性:就是当前页码,这里通过点击上一页和下一页来修改来更新页码

效果如下所示:

完整代码见下面;

4. 封装组件

为了方便使用,我们可以将上面的预览代码封装成功一个单文件组件,然后在需要的地方进行引入即可;

如何实现前端网页实时预览PDF文件功能?

封装后的组件代码贴到文末了,因为有点长:

我们在展示pdf文件时,可以通过跳转到新标签页的方式进行展示,这样组件内的布局不会有太大的变化;

跳转代码如下所示:

let routeUrl = this.$router.resolve({ path: '/preview-pdf', query:{pdfPath} }) window.open(routeUrl.href, '_blank')

  • /preview-pdf:这个路径就是配置在路由里面的,预览pdf的路径

  • pdfPath:这里我们是通过query的方式进行传参,然后在预览组件内通过 this.srcPdf = decodeURIComponent(this.$route.query.pdfPath)进行获取;

    • 因为存在编码问题,所以这里需要加上解码操作;

      如果pdf路径是.../xxx.pdf' // src: srcPdf, // 当前页数 currentPage: 0, // 总页数 pageCount: 0, // 加载进度 loadedRatio: 0 } }, methods: { // 页面回到顶部 toTop () { document.getElementById('container').scrollTop = 0 }, // 输入页码时校验 inputEvent () { if (this.currentPage > this.pageCount) { // 1. 大于max this.currentPage = this.pageCount } else if (this.currentPage < 1) { // 2. 小于min this.currentPage = 1 } }, // 切换页数 changePdfPage (val) { if (val === 'pre' && this.currentPage > 1) { // 切换后页面回到顶部 this.currentPage-- this.toTop() } else if (val === 'next' && this.currentPage < this.pageCount) { this.currentPage++ this.toTop() } else if (val === 'first') { this.currentPage = 1 this.toTop() } else if (val === 'last' && this.currentPage < this.pageCount) { this.currentPage = this.pageCount this.toTop() } }, // pdf加载时 loadPdfHandler (e) { // 加载的时候先加载第一页 this.currentPage = 1 }, } } </script> <style scoped> #container { overflow: auto; font-family: PingFang SC; width: 100%; display: flex; position: relative; } /* 功能按钮区 */ .right-btn { right:4rem; position: fixed; display: flex; flex-wrap: wrap; justify-content: center; z-index: 99; } .pdfArea { width: 80%; } /*在谷歌下移除input[number]的上下箭头*/ input::-webkit-outer-spin-button, input::-webkit-inner-spin-button { -webkit-appearance: none !important; margin: 0; } /*在firefox下移除input[number]的上下箭头*/ input[type='number'] { -moz-appearance: textfield; } .inputNumber { border-radius: 8px; border: 1px solid #999999; font-size: 18px; width: 2rem; text-align: center; } .inputNumber:focus { border: 1px solid #00aeff; background-color: rgba(18, 163, 230, 0.096); outline: none; transition: 0.2s; } </style>

      如何使用?

      先注册路由:src/router/index.js

      import MyPdf from '../components/MyPdf' export default new VueRouter({ routes: [ { path: '/apply-contract-pdf', name: 'apply-contract-pdf', component: MyPdf }, ]})

      再通过如下方法进行预览:

      previewPdf(pdfPath){ let routeUrl = this.$router.resolve({ path: '/preview-pdf', query:{pdfPath} }) window.open(routeUrl.href, '_blank') }, 总结

      本篇介绍了vue-pdf的一些简单使用,包括首页展示、分页展示等;

      其实还有一些进度条展示这里没列出来,感兴趣的可以配合a-progress组件和progress 属性进行体验