【无标题】

web、H5、vue等预览pdf文件(Pdf.js)

Pdf.js官方文档:文档地址

1. 使用场景

  • 在浏览器中展示PDF文件内容:使用Html5的canvas元素来展示pdf文件。
  • 支持基本的浏览功能:PDF.js提供了一套用户界面,包括缩放、滚动、翻页等浏览功能,使用户能够方便地导航和浏览PDF文件。

2. 使用方法

  • web浏览器中使用

    1. 引入pdf.js文件.需要使用pdf.js文件和pdf.worker.js文件。

      // 引入 pdf.js 文件
      <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.js"></script>
      
    2. 编码示例(2.x版本示例)

      <!DOCTYPE html>
      <html>
      <head>
        <title>PDF.js Example</title>
        <style> #pdf-container { width: 800px; height: 600px; overflow: scroll; } </style>
      </head>
      <body>
        <div id="pdf-container"></div>
        <button id="prev-btn">Previous</button>
        <button id="next-btn">Next</button>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.js"></script>
        <script>
          // 指定工作线程脚本的路径
          pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.worker.js'
          var container = document.getElementById('pdf-container')
          // 放入pdf文件链接地址
          pdfjsLib.getDocument('https://oss.xxxxxxxxxxxxx.pdf').promise.then(function (pdf) {
            var currentPage = 1
            function renderPage(pageNumber) {
              container.innerHTML = '' // 清空容器
              pdf.getPage(pageNumber).then(function (page) {
                var scale = 1.2
                var viewport = page.getViewport({ scale: scale })
                var canvas = document.createElement('canvas')
                var context = canvas.getContext('2d')
                canvas.width = viewport.width
                canvas.height = viewport.height
                page.render({
                  canvasContext: context,
                  viewport: viewport
                })
                container.appendChild(canvas)
                currentPage = pageNumber
              })
            }
            // 监听翻页按钮点击事件
            document.getElementById('prev-btn').addEventListener('click', function () {
              if (currentPage > 1) { renderPage(currentPage - 1) }
            })
            document.getElementById('next-btn').addEventListener('click', function () {
              if (currentPage < pdf.numPages) { renderPage(currentPage + 1) }
            })
            renderPage(1)
          })
        </script>
      </body>
      </html>
      
    3. 最新版本(4.x)示例

      <!DOCTYPE html>
      <html>
      <head>
        <meta charset="UTF-8">
        <title>pdf example</title>
      </head>
      <body>
      <canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.1.392/pdf.min.mjs" type="module"></script>
      <script id="script" type="module">
        // url是pdf文件的链接地址
        const url = 'https://oss.xxxxxxxxxxx.pdf'
        pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.1.392/pdf.worker.mjs'
        const loadingTask = pdfjsLib.getDocument(url)
        const pdf = await loadingTask.promise
        const page = await pdf.getPage(1)
        const scale = 1.5
        const viewport = page.getViewport({ scale })
        const outputScale = window.devicePixelRatio || 1
        const canvas = document.getElementById("the-canvas")
        const context = canvas.getContext("2d")
        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"
        const transform = outputScale !== 1
          ? [outputScale, 0, 0, outputScale, 0, 0]
          : null
        const renderContext = {
          canvasContext: context,
          transform,
          viewport,
        }
        page.render(renderContext)
      </script>
      
      <pre id="code"></pre>
      </body>
      </html>
      
  • vue3组件中使用(直接上代码)

    <template>
      <div class="pdf-container" v-loading="loading">
        <canvas id="the-canvas"></canvas>
        <div class="change-page-btns">
          <el-button type="primary" @click="changePage('prev')">上一页</el-button>
          &nbsp;&nbsp;<span> {{ currPageNum }} / {{ pageTotal }} </span>&nbsp;&nbsp;
          <el-button type="primary" @click="changePage('next')">下一页</el-button>
        </div>
      </div>
    </template>
    
    <script setup lang="ts">
    /**
     * 在npm.org modules 市场没有找到对应的 pdf.js 应用,所以这里继续使用cdn网络,或者把代码下载到本地调用
     * https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.1.392/pdf.worker.mjs
     * https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.1.392/pdf.mjs
     */
    import * as pdfjsLib from 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.1.392/pdf.mjs'
    import { ref, onMounted, reactive} from 'vue'
    
    import { ElMessage } from 'element-plus'
    
    const filePath = ref('https://oss.xxxxx.pdf') // 要展示的pdf文件链接地址
    const loading = ref(false)
    let CurrPdfInfo:any = reactive({})
    const pageTotal = ref(1)
    const currPageNum = ref(1) // 默认展示pdf文件的第一页
    
    onMounted(() => {
      init()
    })
    
    const init = async () => {
      currPageNum.value = 1
      loading.value = true
      pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/4.1.392/pdf.worker.mjs'
      const loadingTask = pdfjsLib.getDocument(filePath.value)
      CurrPdfInfo = await loadingTask.promise
      pageTotal.value = CurrPdfInfo.numPages || 0
      loading.value = false
      RenderPage()
    }
    
    const RenderPage = async () => {
      const page = await CurrPdfInfo.getPage(currPageNum.value)
      const scale = 1
      const viewport = page.getViewport({ scale })
      const outputScale = window.devicePixelRatio || 1
      const canvas:any = document.getElementById("the-canvas") || null
      const context:any = canvas.getContext("2d")
      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"
      const transform = outputScale !== 1
        ? [outputScale, 0, 0, outputScale, 0, 0]
        : null
      const renderContext = {
        canvasContext: context,
        transform,
        viewport,
      }
      page.render(renderContext)
    }
    
    const changePage = (type:string) => {
      if (currPageNum.value === 1 && type === 'prev') {
        ElMessage.info('您已经操作到第一页!')
      } else if (currPageNum.value === pageTotal.value  && type === 'next') {
        ElMessage.info('您已经操作到最后一页!')
      } else {
        if (type === 'prev') { // 上一页
          currPageNum.value > 1 ? currPageNum.value-- : currPageNum.value = 1
        } else if (type === 'next') { // 下一页 CurrPdfInfo
          currPageNum.value < pageTotal.value ? currPageNum.value++ : currPageNum.value = pageTotal.value
        }
        RenderPage()
      }
    }
    
    </script>
    
    <style scoped>
    .pdf-container {
      width: 100%;
      height: 800px;
      border: 1px solid red;
      overflow: scroll;
    }
    </style>
    
    
  • uni-app H5中使用(新版本参考vue实现方式),以下是 **@dcloudio/uni-app-plus -v2.0.0 **为例来实现。---uniapp其他打包方式有原生api支持:uni.openDocument(OBJECT)

    // 此代码仅使用与uniapp打包成H5适用, 其他打包方式uni.openDocument(OBJECT)原生方法即可实现。
    
    // 项目入口index.html文件中要引入 js 文件
    // <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.js"></script>
    
    <template>
      <scroll-view class="scroll-container" @scrolltoupper="loadPerPage" @scrolltolower="loadNextPage" scroll-y="true" scroll-x="true">
        <view id="pdf-container"></view>
      </scroll-view>
    </template>
    
    <script>
    export default {
      name: 'scanPdf',
      data () {
        return {
          infoData: '',
          container: null, // 渲染pdf的canvas容器
          currPageNum: 1, // 默认渲染第一页
          pageTotal: 1,
          loadPageCount: 1,
          CurrPdfInfo: null,
          url: 'https://oss.xxxx/demo-ui.pdf'
        }
      },
      mounted () {
        this.initPdfViewer()
      },
      methods: {
        initPdfViewer () {
          this.currPageNum = 1
          this.loading = true
          uni.showLoading({title: '文件加载中...'})
          pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.worker.js'
          this.container = document.getElementById('pdf-container')
          pdfjsLib.getDocument(this.url).promise.then(pdf => {
            uni.hideLoading()
            this.pageTotal = pdf.numPages || 0 // pdf文件共有多少页
            this.CurrPdfInfo = pdf
            this.renderPage() // 初始化完成数据默认渲染第一页
          })
        },
        renderPage () {
          // this.container.innerHTML = '' // 清空容器
          this.CurrPdfInfo.getPage(this.currPageNum).then(page => {
            const scale = 1
            const viewport = page.getViewport({ scale: scale })
            const canvas = document.createElement('canvas')
            const context = canvas.getContext('2d')
            canvas.width = viewport.width
            canvas.height = viewport.height
            page.render({
              canvasContext: context,
              viewport: viewport
            })
            this.container.appendChild(canvas)
          })
        },
        loadNextPage () {
          if (this.loadPageCount <= this.currPageNum) {
            if (this.currPageNum < this.pageTotal) {
              this.currPageNum++
              this.loadPageCount = this.currPageNum
              this.renderPage()
            } else {
              this.currPageNum = this.pageTotal
              uni.showToast({
                title: '已经浏览到最后一页啦!',
                icon: 'none',
                mask: false
              })
            }
          }
        },
        loadPerPage () {
          uni.showToast({
            title: '已经浏览到第一页啦!',
            icon: 'none',
            mask: false
          })
        }
      }
    }
    </script>
    
    <style scoped>
    .scroll-container {
      width: 100%;
      height: 100%;
    }
    </style>
    


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值