Vue實(shí)現(xiàn)pdf在線預(yù)覽功能的示例代碼
一、文件預(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)文章希望大家以后多多支持腳本之家!
- Vue3實(shí)現(xiàn)pdf在線預(yù)覽的三種方式
- Vue移動(dòng)端實(shí)現(xiàn)pdf/excel/圖片在線預(yù)覽
- vue2.0如何借用vue-pdf實(shí)現(xiàn)在線預(yù)覽pdf文件
- vue在線預(yù)覽word、excel、pdf、txt、圖片的方法實(shí)例
- Vue實(shí)現(xiàn)docx、pdf格式文件在線預(yù)覽功能
- Vue-pdf實(shí)現(xiàn)在線預(yù)覽PDF文件
- vue 使用 vue-pdf 實(shí)現(xiàn)pdf在線預(yù)覽的示例代碼
- vue實(shí)現(xiàn)pdf文檔在線預(yù)覽功能
相關(guān)文章
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-09vue前臺(tái)顯示500和405錯(cuò)誤的解決(springboot為后臺(tái))
這篇文章主要介紹了vue前臺(tái)顯示500和405錯(cuò)誤的解決(springboot為后臺(tái)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07vue項(xiàng)目搭建以及全家桶的使用詳細(xì)教程(小結(jié))
這篇文章主要介紹了vue項(xiàng)目搭建以及全家桶的使用詳細(xì)教程(小結(jié)),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-12-12ElementUI 修改默認(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,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07如何在Vue項(xiàng)目中使用axios請(qǐng)求
這篇文章主要介紹了如何在Vue項(xiàng)目中使用axios請(qǐng)求,對(duì)Vue感興趣的同學(xué),可以參考下2021-05-05