pdf浏览器预览 {#h_pdf浏览器预览}
近期工作上需要在浏览器上展示pdf格式的文件,经过查找,pdf.js最为合适。
由于是大屏的预览,并没有一次性全部展示出来,只是展示第一页,通过上一页下一页的控制,来浏览pdf。
效果如下:
代码如下,没有粘贴css,canvas需要指定宽高:
<body>
<div class="pdf-container">
<canvas id="the-canvas"></canvas>
<div class="arrow-btns">
<button onclick="pdfViews.setPageIndex(pdfViews.pageIndex-1)" class="prev-btn btn"><img src="./assets/images/arrow-right.svg" class="arrow-img"></button>
<button onclick="pdfViews.setPageIndex(pdfViews.pageIndex+1)" class="next-btn btn"><img src="./assets/images/arrow-right.svg" class="arrow-img"></button>
</div>
</div>
</body>
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.3.122/pdf.min.js" integrity="sha512-CGtesFWoCAxW8xV1S4wdev6uWmGhkEBtTGJsQLkT75ab0eVyx0RTOdGxHk9hFVV/OlF6ZyCoukfPdiZPpAiUtw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> -->
<script src="./assets/js/pdf.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.3.122/pdf.worker.min.js"
integrity="sha512-Am3j2LUWSl4PsujPgLgHi4kztn5rVozTiX9YkaSuwzYCOIumNISgFBRh5Ux6ZWFB5+Cu5buNtbNwmaWLteyB9w=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
let params = parseQueryString(window.location.search)
let pdfViews, pdfPath='./assets/data/0927.pdf'
class PDFViews{
scale = 1
pageIndex = 2
pageSize=0
pdf=null
canvasW=0
canvasH=0
dom={
prevBtn: document.querySelector('.prev-btn'),
nextBtn: document.querySelector('.next-btn'),
pageSize: document.querySelector('.pageSize'),
pageIndex: document.querySelector('.pageIndex'),
container: document.querySelector('.pdf-container'),
canvas: document.querySelector('#the-canvas')
}
constructor(pdf, params){
this.pdf = pdf
this.canvasH = params.h
this.canvasW = params.w
this.setPageSize(pdf.numPages)
}
setPageSize(val){
this.pageSize = val
if(this.dom.pageSize){
this.dom.pageSize.innerHTML = this.pageSize
}
}
setPageIndex(val=1){
if(val>0 && val<= this.pageSize){
this.pageIndex = val
if(this.dom.pageIndex){
this.dom.pageIndex.innerHTML = this.pageIndex
}
this.randerPdf(this.pdf, this.scale, this.pageIndex)
}
if(val>=this.pageSize){
this.dom.nextBtn.disabled = true
}else if(val <= 1){
this.dom.prevBtn.disabled = true
}else{
if(this.dom.nextBtn.disabled == true){
this.dom.nextBtn.disabled = false
}
if(this.dom.prevBtn.disabled == true){
this.dom.prevBtn.disabled = false
}
}
}
async randerPdf(pdf, scale, pageIndex) {
let page = await pdf.getPage(pageIndex)
var viewport = page.getViewport({ scale: 1, });
let scaleX = this.canvasW/viewport.width
let scaleY = this.canvasH/viewport.height
let scaledViewport = page.getViewport({ scale: Math.min(scaleX,scaleY), })
// var outputScale = window.devicePixelRatio || 1;
var outputScale = 1;
var canvas = this.dom.canvas;
var context = canvas.getContext('2d');
// canvas.width = Math.floor(viewport.width * outputScale);
// canvas.height = Math.floor(viewport.height * outputScale);
canvas.width = this.canvasW
canvas.height = this.canvasH
var transform = outputScale !== 1
? [outputScale, 0, 0, outputScale, 0, 0]
: null;
var renderContext = {
canvasContext: context,
transform: transform,
viewport: scaledViewport
};
page.render(renderContext);
}
}
(async () => {
let loadingTask = pdfjsLib.getDocument(pdfPath)
const pdf = await loadingTask.promise
pdfViews = new PDFViews(pdf, params)
pdfViews.setPageIndex()
})()
function parseQueryString(url) {
url = url == null ? window.location.href : url
let search = url.substring(url.lastIndexOf('?') + 1)
if (!search) {
return {}
}
return JSON.parse('{"' + decodeURIComponent(search).replace(/"/g, '\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}')
}
</script>
每次点击上一页或者下一页,都会在canvas重新渲染。
当然也可以根据 pdf.numPages
总页数创建多个canvas,一次性加载(最好懒加载的方式)。