欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue實(shí)現(xiàn)pdf在線預(yù)覽功能的示例代碼

 更新時(shí)間:2025年03月07日 10:32:24   作者:cypking  
這篇文章主要為大家詳細(xì)介紹了如何使用Vue實(shí)現(xiàn)pdf在線預(yù)覽功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

一、文件預(yù)覽

1、安裝依賴包

這里安裝了disjs-dist@2.16版本,安裝過程中報(bào)錯(cuò)缺少worker-loader

npm i pdfjs-dist@2.16.105 worker-loader@3.0.8

2、模板部分

<template>
  <div id="pdf-view">
    <canvas v-for="page in pdfPages" :key="page" :id="pdfCanvas" />
    <div id="text-view"></div>
  </div>
</template>

3、js部分(核心)

核心代碼如下:

  • 利用 PDF.getDocument獲取pdf基礎(chǔ)數(shù)據(jù)
  • 通過canvas將pdf渲染到canvas畫布上
  import * as pdfjsViewer from "pdfjs-dist/web/pdf_viewer.js";
  import "pdfjs-dist/web/pdf_viewer.css";
  import * as PDF from "pdfjs-dist/webpack";

  export default {
    name: "",
    components: {},
    data() {
      return {
        pdfPages: 1,
        pdfPath: "http://localhost:8080/qfnext.pdf",
        // 總頁數(shù)
        pdfPages: 1,
        // 頁面縮放
        pdfScale: 1,
        pdfDoc: null,
      };
    },
    mounted() {
      this.loadFile(this.pdfPath);
    },
    methods: {
      loadFile(url) {
        PDF.getDocument({
          url,
          cMapUrl: "https://cdn.jsdelivr.net/npm/pdfjs-dist@2.16.105/cmaps/",
          cMapPacked: true,
        }).promise.then((pdf) => {
          this.pdfDoc = pdf;
          // 獲取pdf文件總頁數(shù)
          this.pdfPages = pdf.numPages;
          this.$nextTick(() => {
            this.renderPage(1); // 從第一頁開始渲染
          });
        });
      },
      renderPage(num) {
        this.pdfDoc.getPage(num).then((page) => {
          const canvas = document.getElementById(`pdfCanvas`);
          const ctx = canvas.getContext("2d");
          const viewport = page.getViewport({ scale: this.pdfScale });
          canvas.width = viewport.width;
          canvas.height = viewport.height;
          const renderContext = {
            canvasContext: ctx,
            viewport,
          };
            page.render(renderContext);
        });
      },
    },
  };

可能出現(xiàn)的問題:

(1) 頁面文字可選中,但文本不可見

通過測試發(fā)現(xiàn),將 pdfjs-dist/web/pdf_viewer.css 路徑下的 color 屬性注釋后可顯示文本。

.textLayer span,
.textLayer br {
  /* color: transparent; */
  position: absolute;
  white-space: pre;
  cursor: text;
  transform-origin: 0% 0%;
}

pdf多頁面處理

模板處理id作為唯一標(biāo)識(shí)

 <canvas v-for="page in pdfPages" :key="page" :id="`page-${page}`" />

修改canvas渲染邏輯,主要通過遞歸的方式逐一渲染

 renderPage(num) {
        this.pdfDoc.getPage(num).then((page) => {
          const canvas = document.getElementById(`page-${num}`);
          const ctx = canvas.getContext("2d");
          const viewport = page.getViewport({ scale: this.pdfScale });
          canvas.width = viewport.width;
          canvas.height = viewport.height;
          const renderContext = {
            canvasContext: ctx,
            viewport,
          };
            page.render(renderContext);
             if (num < this.pdfPages) {
                this.renderPage(num + 1);
              }
        });
  },

二、文本選中與彈窗(核心代碼)

   Promise.all([getTextContentPromise, renderPagePromise])
            .then(([textContent]) => {
              const textLayerDiv = document.createElement("div");
              // 注意:此處不要修改該元素的class名稱,該元素的樣式通過外部導(dǎo)入,名稱是固定的
              textLayerDiv.setAttribute("class", "textLayer");
              // 設(shè)置容器樣式
              textLayerDiv.setAttribute(
                "style",
                `
                  z-index: 1;
                  opacity: .2;
                  // background-color:#fff;
                  // transform: scale(1.1);
                  width: 100%,
                  height: 100%,
              `,
              );
              // 設(shè)置容器的位置和寬高
              textLayerDiv.style.left = canvas.offsetLeft + "px";
              textLayerDiv.style.top = canvas.offsetTop + "px";
              textLayerDiv.style.height = canvas.offsetHeight + "px";
              textLayerDiv.style.width = canvas.offsetWidth + "px";

              const textView = document.querySelector("#text-view");
              textView.appendChild(textLayerDiv);

              const textLayer = new TextLayerBuilder({
                // container: ,
                textLayerDiv: textLayerDiv,
                pageIndex: page.pageIndex,
                viewport: viewport,
                eventBus,
                // textDivs: []
              });

              textLayer.setTextContent(textContent);
              textLayer.render();
              // 當(dāng)選擇文本后鼠標(biāo)取消點(diǎn)擊時(shí)觸發(fā)
              textLayerDiv.addEventListener("mouseup", () => {
                // // 隱藏文本層
                // textLayerDiv.style.display = 'none';
                // 是否選擇了文本
                const isTextSelected =
                  window.getSelection().toString().trim() !== "";
                if (isTextSelected) {
                  //選擇的文本內(nèi)容
                  const selectedText = window.getSelection().toString();
                  console.log("Selected text:", selectedText);
                  if (selectedText) {
                    alert(selectedText);
                  }
                }
              });
            })
            .catch((error) => {
              console.error("Error rendering page:", error);
            });

三、完整代碼如下

<template>
  <div id="pdf-view">
    <canvas v-for="page in pdfPages" :key="page" :id="`page-${page}`" />
    <div id="text-view"></div>
  </div>
</template>

<script>
  import * as pdfjsViewer from "pdfjs-dist/web/pdf_viewer.js";
  import "pdfjs-dist/web/pdf_viewer.css";
  import * as PDF from "pdfjs-dist/webpack";
  // import { getDocument } from 'pdfjs-dist/webpack';
  import { TextLayerBuilder } from "pdfjs-dist/web/pdf_viewer.js";
  const pdfjsWorker = import("pdfjs-dist/build/pdf.worker.entry");
  PDF.GlobalWorkerOptions.workerSrc = pdfjsWorker;
  const eventBus = new pdfjsViewer.EventBus();
  export default {
    name: "",
    components: {},
    data() {
      return {
        pdfPages: 1,
        pdfPath: "http://localhost:8080/qfnext.pdf",
        // 總頁數(shù)
        pdfPages: 1,
        // 頁面縮放
        pdfScale: 1,
        pdfDoc: null,
      };
    },
    mounted() {
      this.loadFile(this.pdfPath);
    },
    methods: {
      loadFile(url) {
        PDF.getDocument({
          url,
          cMapUrl: "https://cdn.jsdelivr.net/npm/pdfjs-dist@2.16.105/cmaps/",
          cMapPacked: true,
        }).promise.then((pdf) => {
          this.pdfDoc = pdf;
          // 獲取pdf文件總頁數(shù)
          this.pdfPages = pdf.numPages;
          this.$nextTick(() => {
            this.renderPage(1); // 從第一頁開始渲染
          });
        });
      },
      renderPage(num) {
        this.pdfDoc.getPage(num).then((page) => {
          const canvas = document.getElementById(`page-${num}`);
          const ctx = canvas.getContext("2d");
          const viewport = page.getViewport({ scale: this.pdfScale });
          canvas.width = viewport.width;
          canvas.height = viewport.height;
          const renderContext = {
            canvasContext: ctx,
            viewport,
          };

          // 獲取文本內(nèi)容和渲染頁面的 Promise
          const getTextContentPromise = page.getTextContent();
          const renderPagePromise = page.render(renderContext);
          if (num < this.pdfPages) {
            this.renderPage(num + 1);
          }
          Promise.all([getTextContentPromise, renderPagePromise])
            .then(([textContent]) => {
              const textLayerDiv = document.createElement("div");
              // 注意:此處不要修改該元素的class名稱,該元素的樣式通過外部導(dǎo)入,名稱是固定的
              textLayerDiv.setAttribute("class", "textLayer");
              // 設(shè)置容器樣式
              textLayerDiv.setAttribute(
                "style",
                `
                  z-index: 1;
                  opacity: .2;
                  // background-color:#fff;
                  // transform: scale(1.1);
                  width: 100%,
                  height: 100%,
              `,
              );
              // 設(shè)置容器的位置和寬高
              textLayerDiv.style.left = canvas.offsetLeft + "px";
              textLayerDiv.style.top = canvas.offsetTop + "px";
              textLayerDiv.style.height = canvas.offsetHeight + "px";
              textLayerDiv.style.width = canvas.offsetWidth + "px";

              const textView = document.querySelector("#text-view");
              textView.appendChild(textLayerDiv);

              const textLayer = new TextLayerBuilder({
                // container: ,
                textLayerDiv: textLayerDiv,
                pageIndex: page.pageIndex,
                viewport: viewport,
                eventBus,
                // textDivs: []
              });

              textLayer.setTextContent(textContent);
              textLayer.render();
              // 當(dāng)選擇文本后鼠標(biāo)取消點(diǎn)擊時(shí)觸發(fā)
              textLayerDiv.addEventListener("mouseup", () => {
                // // 隱藏文本層
                // textLayerDiv.style.display = 'none';
                // 是否選擇了文本
                const isTextSelected =
                  window.getSelection().toString().trim() !== "";
                if (isTextSelected) {
                  //選擇的文本內(nèi)容
                  const selectedText = window.getSelection().toString();
                  console.log("Selected text:", selectedText);
                  if (selectedText) {
                    alert(selectedText);
                  }
                }
              });
            })
            .catch((error) => {
              console.error("Error rendering page:", error);
            });
        });
      },
    },
  };
</script>
<style lang="scss" scoped>
  .pdf-con {
    border: 2px solid #ccc;
    width: 80%;
    margin: auto;
    height: 800px;
    overflow: auto;
    // display: none;
  }
</style>

到此這篇關(guān)于Vue實(shí)現(xiàn)pdf在線預(yù)覽功能的示例代碼的文章就介紹到這了,更多相關(guān)Vue pdf在線預(yù)覽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue實(shí)現(xiàn)二維碼數(shù)組的全選與反選功能

    Vue實(shí)現(xiàn)二維碼數(shù)組的全選與反選功能

    在開發(fā)Web應(yīng)用程序時(shí),表格數(shù)據(jù)的展示和操作是非常常見的需求之一,特別是在處理表格中的復(fù)選框選擇時(shí),我們經(jīng)常需要實(shí)現(xiàn)全選、反選等功能,這篇文章將帶你深入了解如何在Vue.js中實(shí)現(xiàn)對(duì)二維數(shù)組數(shù)據(jù)的全選和反選功能,需要的朋友可以參考下
    2024-09-09
  • vue前臺(tái)顯示500和405錯(cuò)誤的解決(springboot為后臺(tái))

    vue前臺(tái)顯示500和405錯(cuò)誤的解決(springboot為后臺(tái))

    這篇文章主要介紹了vue前臺(tái)顯示500和405錯(cuò)誤的解決(springboot為后臺(tái)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • Mac下安裝vue

    Mac下安裝vue

    本文給大家詳細(xì)介紹了Mac下安裝vue的方法,本文圖文并茂給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2018-04-04
  • vue實(shí)現(xiàn)界面滑動(dòng)效果

    vue實(shí)現(xiàn)界面滑動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)界面滑動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • vue項(xiàng)目搭建以及全家桶的使用詳細(xì)教程(小結(jié))

    vue項(xiàng)目搭建以及全家桶的使用詳細(xì)教程(小結(jié))

    這篇文章主要介紹了vue項(xiàng)目搭建以及全家桶的使用詳細(xì)教程(小結(jié)),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-12-12
  • ElementUI 修改默認(rèn)樣式的幾種辦法(小結(jié))

    ElementUI 修改默認(rèn)樣式的幾種辦法(小結(jié))

    這篇文章主要介紹了ElementUI 修改默認(rèn)樣式的幾種辦法(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 詳解vue-cli 腳手架項(xiàng)目-package.json

    詳解vue-cli 腳手架項(xiàng)目-package.json

    本篇文章主要介紹了詳解vue-cli 腳手架項(xiàng)目-package.json,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-07-07
  • vue可拖拽的瀑布流布局組件實(shí)現(xiàn)詳解

    vue可拖拽的瀑布流布局組件實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了vue的可拖拽的瀑布流布局組件有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • 在vue中完美使用ueditor組件(cdn)解讀

    在vue中完美使用ueditor組件(cdn)解讀

    這篇文章主要介紹了在vue中完美使用ueditor組件(cdn)解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • 如何在Vue項(xiàng)目中使用axios請(qǐng)求

    如何在Vue項(xiàng)目中使用axios請(qǐng)求

    這篇文章主要介紹了如何在Vue項(xiàng)目中使用axios請(qǐng)求,對(duì)Vue感興趣的同學(xué),可以參考下
    2021-05-05

最新評(píng)論