需求:实现点击左侧pdf文件时,右侧可以实时预览内容。
可以实现点击预览;但不能按住ctrl进行缩放;清晰度的问题;不能固定左侧对右侧加滚轮;
package.js:
在"dependencies"里加一行"jspdf": “^2.3.1”,然后npm install 重新下载需要的依赖;
main.js:
import * as pdfjsLib from ‘pdfjs-dist’;
import “pdfjs-dist/build/pdf.worker.entry.js”;
pdfjsLib.GlobalWorkerOptions.workerSrc = window.pdfjsWorker;
window.pdfjsLib = pdfjsLib;
展示的页面.vue:
<div class="pages" style="height:auto;overflow-y: auto;">
<el-col :span="8">
<el-menu
class="el-menu-vertical-demo"
>
<el-submenu index="1">
<template slot="title">
<span style="color: black;line-height: 30px;font-size: 15px">目录</span>
</template>
<el-menu-item-group>
<div style="width:auto;height:40px;text-overflow:ellipsis;white-space:nowrap;overflow: hidden;" @click="viewfFile()">
<el-menu-item style="color: black;line-height: 30px;font-size: 15px">{{this.你的pdfName}}</el-menu-item>
</div>
</el-menu-item-group>
</el-submenu>
</el-menu>
</el-col>
<el-col :span="16">
<div class="page" v-for="page in pageTotal" :style="{'width':pageWidth+'px'}">
<canvas :id="`pdfCanvas${page}`"></canvas>
</div>
</el-col>
</div>
//预览pdf
viewFile() {
let data = {
csId: this.csId,
}
let url = '/**/***'//点击这个文件拿它id去后端取它的url地址
this.$request.post(url, data).then(data => {
if (data.data.obj==null||data.data.obj==''){
this.$message.info('pdf无')
}else{
let pdfUrl = *window*.location.origin + data.data.obj.url;//拼接出能直接点击访问pdf的链接赋给pdfUrl
this.loadPdf(pdfUrl);
}
})
},
loadPdf(pdfUrl){
this.clearPage();
let loadingTask = window.pdfjsLib.getDocument(pdfUrl);
loadingTask.promise.then((pdf) =>{
let total = pdf.numPages;
this.pageTotal = total;
this.pdfDoc = pdf;
this.$nextTick(() => {
this.pageNum = 1;
this.renderPage(1) // 表示渲染第 1 页
})
});
},
// 渲染指定页面的内容
renderPage(num){
let pdfDoc = this.pdfDoc;
if(pdfDoc){
pdfDoc.getPage(num).then((page)=>{
let canvas = document.getElementById(`pdfCanvas${num}`);
let scale = 1;
let viewport = page.getViewport({ scale: scale, });
let outputScale = window.devicePixelRatio || 1;
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";
this.pageWidth = Math.floor(viewport.width);
this.pageHeight = Math.floor(viewport.height);
this.pdfScale = scale;
let ctx = canvas.getContext("2d")
let transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
// 将 PDF 页面渲染到 canvas 上下文中
let renderContext = {
canvasContext: ctx,
transform: transform,
viewport: viewport
};
page.render(renderContext);
if (this.pageTotal > num) {
this.renderPage(num + 1);
}
})
}
},
当npm install后出现的bug:ERROR Failed to compile with 1 error;error in ./node_modules/pdfjs-dist/build/pdf.js
再次执行npm i pdfjs-dist@2.4.456(看你项目里pdf-dist的版本),单独下载pdfjs-dist依赖,然后再执行npm run serve;
参考与感谢:
①原文链接:https://blog.csdn.net/forward_xx/article/details/126915088;
②原文链接:https://blog.csdn.net/weixin_64310738/article/details/129073031;
第三方插件:pdf.js(基于Promise 对象而实现的,渲染 pdf 时底层还使用了Web Worker),一款开源的 pdf 文档读取解析插件,实现在 html 下直接浏览 pdf 文档。
在项目中使用pdfjs,主要包括以下内容:
- 单页pdf加载
- 多页pdf加载(本文)
- pdf放大/缩小/大小重置
- pdf分页展示以及上下翻页
- pdf添加水印
- 动态添加pdf
- 从服务端获取pdf文件
我选择用以图片形式来展示 PDF 文档,这种方法不能选中文本或复制文本。
pdfjs展示pdf文档的原理:实际上是将pdf中的内容渲染到解析,然后渲染到 canvas
中进行展示,因此我们使用pdfjs渲染出来的pdf文件,实际上是一张张canvas图片。
具体步骤:
一、首先 npm i pdfjs-dist 下载 pdf.js 的 Prebuilt 包
百度搜索 npm pdfjs-dist,进入npm官方网站,即可查看pdfjs的安装方法,安装命令:npm i pdfjs-dist:
二、设置 PDFJS.GlobalWorkerOptions.workerSrc 的地址
三、通过 PDFJS.getDocument(pdf 文件的 url) 处理 pdf 数据,返回一个 PDFDocumentLoadingTask
四、通过 pdfDoc.getPage(i) 单独获取第 i 页的数据
五、创建一个 canvas 元素,并设置元素的画布属性
六、通过 page.render 方法,将数据渲染到画布上