使用pdfjs获取pdf目录以及预览pdf,点击目录滚动到对应的位置

页面的最终效果,

根据静态的pdf自动生成左侧pdf目录,右侧使用pdfjs预览,点击左侧目录,右侧滚动到pdf对应的页面,
(注意:pdf必须包含目录页面,否则无法生成目录)
在这里插入图片描述

然后我们放一下页面的代码

以下代码为vue实现,react的话需要做一下修改,主要在于jspdf中api的调用,pdfjs几乎没有文档

当前使用的pdfjs-dist版本为 2.16.105
“pdfjs-dist”: “^2.16.105”,

<template>
  <div class="margin-box" v-loading="loading">
    <div class="document-directory">
      <span class="directory-title"> 目录 </span>
      <div class="directory-tree">
        <!-- 目录渲染 -->
        <el-tree 
        :data="treeData.outline" 
        :default-expand-all="true" 
        :expand-on-click-node="false"
        :props="treeData.defaultProps" @node-click="data=>navigateTo(data.dest)">
        </el-tree>
      </div>
    </div>
    <!-- pdf渲染 -->
    <div class="PDF-content pdf-container" ref="pdfContainer">
    </div>
  </div>
</template>

<script>
import * as PdfJs from "pdfjs-dist/legacy/build/pdf.js";
import { getDocument } from "pdfjs-dist";
PdfJs.GlobalWorkerOptions.workerSrc = require("pdfjs-dist/build/pdf.worker.entry");

async function getPdf(src) {
  const loadingTask = getDocument({
  url: src,
  disableFontFace: true,   //禁用文本抗锯齿 ,提高渲染性能
});
  const pdf = await loadingTask.promise;
  return pdf;
}

export default {
  name: "PdfViewer",
  props: {
    src: String,
  },
  data() {
    return {
      pdf: null,
      numPages: 0,
      treeData:{
        outline:[],
        defaultProps:{
          children: 'items',
          label: 'title'
        }
      },
      loading:false,
      fragment: document.createDocumentFragment()
    };
  },
  mounted() {
    this.loadPdf(this.src);
  },
  methods: {
    async loadPdf(src) {
      this.loading = true

      // 注意,此处接受的src必须是浏览器可以直接访问pdf的路径
      const pdf = await getPdf(src);
      this.pdf = pdf;

      // 获取pdf的也页数
      this.numPages = pdf.numPages;

      this.renderAllPages();

      this.renderOutline(pdf);
    },
    //渲染整个pdf
    async renderAllPages() {
      for (let i = 1; i <= this.numPages; i++) {
        // 通过文档碎片统一渲染提高性能

        // 插入每一页的pdf渲染
        this.fragment.appendChild(await this.renderPage(i));
      }
      this.$refs.pdfContainer.appendChild(this.fragment);

      this.loading = false
    },
    // 获取目录树
    async renderOutline(pdf) {
      const outline = await pdf.getOutline();
      this.treeData.outline = outline
    },
    // 渲染某页页pdf
    async renderPage(pageNumber) {
      if (!this.pdf) {
        return;
      }

      const page = await this.pdf.getPage(pageNumber);

      // 设置清晰度
      const viewport = page.getViewport({ scale: 2 });

      const canvas = document.createElement("canvas");
      canvas.id = `page-${pageNumber}`;
      canvas.width = viewport.width;
      canvas.height = viewport.height;

      const ctx = canvas.getContext("2d");
      const renderContext = {
        canvasContext: ctx,
        viewport: viewport,
      };

      await page.render(renderContext).promise;

      return canvas
    },
    // 点击跳转到某页
    async navigateTo(dest) {
      if (!this.pdf || !dest) {
        return;
      }

      // 获取目标页面的页码
      const pageNumber = (await this.pdf.getPageIndex(dest[0])) + 1;

      // 滚动到目标页面
      const pageElement = document.getElementById(`page-${pageNumber}`);
      if (pageElement) {
        pageElement.scrollIntoView({ behavior: "smooth" });
      }
    },
  },
};
</script>

<style scoped>
.margin-box {
  box-sizing: border-box;
  margin: 10px;
  height: 95%;
  display: flex;
}
.document-directory {
  width: 400px;
  background-color: #fff;
  height: 100%;
  padding: 20px;
  overflow: auto;
}
.directory-title {
  display: inline-block;
  font-size: 18px;
  margin-bottom: 20px;
}
.PDF-content {
  flex: 1;
  height: 100%;
  overflow: auto;
  background: #eff;
  display: flex;
  flex-direction: column;
  margin:0 10px;
}
/deep/.el-tree-node.is-current > .el-tree-node__content {
    color: #cc2722 !important;
    font-weight: 600;
}
/deep/.el-tree-node:focus>.el-tree-node__content{
  background-color:#fff !important;
}
/deep/.el-tree-node__content:hover{
  background-color:#fff !important;
}
/deep/.el-icon-caret-right:before {
    content: "";
}
/deep/.el-tree-node__content{
  height: 40px;
}
/deep/.el-tree-node__label{
  line-height: 40px;
}
</style>


  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
你可以使用pdf.js库来获取PDF目录预览PDF。下面是一个使用pdf.js库的示例代码: 首先,你需要引入pdf.js库的脚本文件。你可以从pdf.js的官方GitHub仓库中获取最新版本的脚本文件。 ```html <script src="path/to/pdf.js"></script> ``` 接下来,你可以使用以下代码获取PDF目录: ```javascript PDFJS.getDocument('path/to/pdf').then(function(pdf) { pdf.getOutline().then(function(outline) { // 处理目录 console.log(outline); }); }); ``` 上述代码通过`getDocument`方法打开PDF文件,并使用`getOutline`方法获取PDF目录信息。获取目录信息将作为参数传递给回调函数中的`outline`参数。你可以根据需要对目录进行处理。 要预览PDF,你可以使用以下代码: ```javascript PDFJS.getDocument('path/to/pdf').then(function(pdf) { // 获取第一页 pdf.getPage(1).then(function(page) { var canvas = document.getElementById('pdf-canvas'); var context = canvas.getContext('2d'); // 设置缩放比例 var viewport = page.getViewport({ scale: 1 }); // 设置画布尺寸 canvas.width = viewport.width; canvas.height = viewport.height; // 渲染页面 page.render({ canvasContext: context, viewport: viewport }); }); }); ``` 上述代码通过`getDocument`方法打开PDF文件,并使用`getPage`方法获取指定页码的页面。获取的页面对象将作为参数传递给回调函数中的`page`参数。你可以将页面渲染到指定的canvas元素上,从而预览PDF。 注意:以上代码仅为示例,具体实现可能需要根据你的应用场景进行调整。另外,pdf.js库还有更多功能和选项可供使用,你可以查阅官方文档以获取更详细的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值