Artigo Diretório
前言:
npm
Sobre o PDF.js
pacote tem dois, pdf.js
e pdfjs-dist
; é usado neste artigo pdfjs-dist
; PDF.js fornece uma página de visualização viewer.html
para obter a visualização online do pdf; pdf.js pode ser baixado para o projeto como um recurso estático, basta alterar o endereço de o servidor onde o arquivo pdf está armazenado pode realizar a exibição online do pdf no projeto vue.
Use pdf.js no modo de instalação npm: você precisa escrever seus próprios estilos de acordo com suas necessidades para implementar funções relacionadas.
Formas de recursos estáticos: Baixe o pdf para um projeto local para a maneira de recursos estáticos, pdf.js
fornecido viewer.html
para mostrar o arquivo pdf no servidor de arquivos, sem necessidade de configurar seu próprio estilo (pdf.js existente conjunto completo de estilos e funções relacionadas, não Quando necessário, você pode removê-lo por conta própria alterando o código-fonte, etc.)
Um, instale o plug-in
yarn add pdfjs-dist
Em segundo lugar, teste se a introdução foi bem-sucedida no componente
const PDFJS = require("pdfjs-dist");
console.log("成功:",PDFJS )
Resultado da impressão:
Três, pise na coleta do fosso
1. WorkerSrc precisa ser configurado manualmente
A mensagem de erro é a seguinte: Uncaught SyntaxError: Unexpected token '<' Cannot read property 'WorkerMessageHandler' of undefined
注意:
Aqui, a versão do pdf.js aplicada no projeto é 2.5.207
"vue": "^2.6.11",
"pdfjs-dist": "^2.5.207",
Solução: é necessário definir o workerSrc manualmente :
const PDFJS = require("pdfjs-dist");
PDFJS.GlobalWorkerOptions.workerSrc =
"https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.5.207/pdf.worker.js";
2. Nota: Depois que a versão pdf.js é atualizada, seu getDocument
método retorna umpromise
Consulte o código original escrito no exemplo anterior:
loadFile(url) {
let loadingTask = PDFJS.getDocument(url);
loadingTask.then(pdf => {
// 老版本该处是正确写法
......
});
},
TypeError: loadingTask.then is not a function
Mensagem de erro ::
Solução: Nota promise
:
loadFile(url) {
let loadingTask = PDFJS.getDocument(url);
loadingTask.promise.then(pdf => {
// 注意该行的promise,版本升级后,getDocument方法返回promise
......
});
},
Quarto, visualize todo o exemplo de documento de arquivo PDF
<template>
<div class="preview-pdf">
<h1>PDF在线预览</h1>
<div :style="`margin:0 auto;width:${pdfWidth};`">
<canvas
v-for="page in pdfPages"
:key="page"
:id="'pdfCanvas' + page"
></canvas>
</div>
</div>
</template>
<script>
const PDFJS = require("pdfjs-dist");
PDFJS.GlobalWorkerOptions.workerSrc = "https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.5.207/pdf.worker.js";
export default {
data() {
return {
pdfPages: [], // 页数
pdfWidth: "", // 宽度
pdfSrc: "", // 地址
pdfDoc: "", // 文档内容
pdfScale: 1.0 // 放大倍数
};
},
mounted() {
this.getPdfUrl();
},
methods: {
getPdfUrl() {
// todo 请求后台,获取pdf的url,这里用的是线上的地址
this.pdfSrc =
"https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf";
this.loadFile(this.pdfSrc);
},
loadFile(url) {
let loadingTask = PDFJS.getDocument(url);
loadingTask.promise.then(pdf => {
this.pdfDoc = pdf;
this.pdfPages = pdf.numPages;
this.$nextTick(() => {
this.renderPage(1);
});
});
},
renderPage(num) {
const that = this;
this.pdfDoc.getPage(num).then(page => {
let canvas = document.getElementById("pdfCanvas" + num);
let ctx = canvas.getContext("2d");
let dpr = window.devicePixelRatio || 1;
let bsr =
ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||
1;
let ratio = dpr / bsr;
let viewport = page.getViewport({
scale: this.pdfScale });
canvas.width = viewport.width * ratio;
canvas.height = viewport.height * ratio;
canvas.style.width = viewport.width + "px";
that.pdfWidth = viewport.width + "px";
canvas.style.height = viewport.height + "px";
ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
// 将 PDF 页面渲染到 canvas 上下文中
let renderContext = {
canvasContext: ctx,
viewport: viewport
};
page.render(renderContext);
if (this.pdfPages > num) {
this.renderPage(num + 1);
}
});
}
}
};
</script>
<style lang="scss">
.preview-pdf {
h1 {
margin: 30px auto;
text-align: center;
font-family: "宋体";
letter-spacing: 2px;
}
}
</style>
O efeito do código acima é o seguinte (a parte em inglês é o conteúdo do arquivo pdf):
Cinco, página anterior próxima página, exemplo
<template>
<div class="preview-pdf">
<h1>PDF在线预览</h1>
<div style="text-align:center;">
<button id="prev" @click="onPrePage">
Previous
</button>
<button id="next" @click="onNextPage">Next</button>
<span>
Page:
<span id="page_num">{
{
currentPage }}</span>
/
<span id="page_count">{
{
totalPages }}</span></span
>
</div>
<div
:style="`margin:0 auto;width:${pdfWidth};`"
v-loading="isLoading"
element-loading-text="加载中..."
>
<canvas id="pdfCanvas"></canvas>
</div>
</div>
</template>
<script>
const PDFJS = require("pdfjs-dist");
PDFJS.GlobalWorkerOptions.workerSrc =
"https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.5.207/pdf.worker.js";
export default {
data() {
return {
totalPages: [], // 总页数
currentPage: 1, // 当前页
pageRendering: false, // 是否正在渲染
pageNumPending: null, // 待处理页码
pdfWidth: "", // 宽度
pdfSrc: "", // 地址
pdfDoc: null, // 文档内容
pdfScale: 1.0, // 放大倍数
isLoading: false // 文档是否正在加载
};
},
mounted() {
this.getPdfUrl();
},
watch: {
pageRendering(newVal, old) {
this.isLoading = newVal;
}
},
methods: {
getPdfUrl() {
// todo 请求后台,获取pdf的url,注意这里不能是本地的pdf文件
this.pdfSrc =
"https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf";
this.loadFile(this.pdfSrc);
},
loadFile(url) {
//通过promise获取页面
let loadingTask = PDFJS.getDocument(url);
this.pageRendering = true;
loadingTask.promise.then(pdf => {
this.pdfDoc = pdf;
this.totalPages = pdf.numPages;
this.$nextTick(() => {
this.renderPage(1); // 初始/首页渲染
});
});
},
renderPage(num) {
this.currentPage = num; // 更新当前页码
this.pdfDoc.getPage(num).then(page => {
let canvas = document.getElementById("pdfCanvas");
let ctx = canvas.getContext("2d");
let dpr = window.devicePixelRatio || 1;
let bsr =
ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||
1;
let ratio = dpr / bsr;
let viewport = page.getViewport({
scale: this.pdfScale });
canvas.width = viewport.width * ratio;
canvas.height = viewport.height * ratio;
canvas.style.width = viewport.width + "px";
this.pdfWidth = viewport.width + "px";
canvas.style.height = viewport.height + "px";
ctx.setTransform(ratio, 0, 0, ratio, 0, 0);
// 将 PDF 页面渲染到 canvas 上下文中
let renderContext = {
canvasContext: ctx,
viewport: viewport
};
let renderTask = page.render(renderContext);
renderTask.promise.then(() => {
this.pageRendering = false;
if (this.pageNumPending === null) return;
this.renderPage(this.pageNumPending);
this.pageNumPending = null;
});
});
},
onPrePage() {
// 上一页
if (this.currentPage <= 1) return;
this.currentPage--;
this.queueRender(this.currentPage);
},
onNextPage() {
// 下一页
if (this.currentPage >= this.totalPages) return;
this.currentPage++;
this.queueRender(this.currentPage);
},
queueRender(num) {
//渲染等待;如果正在进行另一个页面渲染,请等待渲染完成。 否则,立即执行渲染
!this.pageRendering ? this.renderPage(num) : (this.pageNumPending = num);
}
}
};
</script>
<style lang="scss">
.preview-pdf {
h1 {
margin: 30px auto;
text-align: center;
font-family: "宋体";
letter-spacing: 2px;
}
}
</style>
referência: