fix: pdf重复渲染bug

This commit is contained in:
liyulin 2023-09-02 17:28:43 +08:00
parent cd2c014cfe
commit a525ad1fe1
8 changed files with 46 additions and 15 deletions

View File

@ -15,6 +15,7 @@ export interface Options {
export interface JsPdfPreview {
preview: (src: string | ArrayBuffer | Blob) => Promise<any>;
rerender: () => Promise<any>;
save: (fileName?: string) => void;
setOptions: (options: Options) => void;
setRequestOptions: (requestOptions?: any) => void;

View File

@ -1,7 +1,7 @@
{
"name": "@js-preview/pdf",
"type" :"module",
"version": "1.5.0",
"version": "1.5.2",
"description": "",
"main": "lib/index.js",
"files": [

View File

@ -33,7 +33,11 @@ class JsPdfPreview{
this.wrapperMain.setAttribute('style', 'background: gray; padding: 30px 0;position: relative;');
this.wrapper.appendChild(this.wrapperMain);
}
createCanvas(){
createCanvas(num){
let existCanvas = this.wrapperMain.querySelectorAll('canvas');
if(existCanvas[num -1]){
return [existCanvas[num -1], existCanvas[num -1].getContext('2d')];
}
const canvas = document.createElement('canvas');
canvas.setAttribute('style', 'width:100%');
this.wrapperMain.appendChild(canvas);
@ -64,7 +68,7 @@ class JsPdfPreview{
return this.pdfDocument.getPage(num).then((pdfPage) => {
const viewport = pdfPage.getViewport({scale: 2});
const outputScale = window.devicePixelRatio || 1;
let [canvas, ctx] = this.createCanvas();
let [canvas, ctx] = this.createCanvas(num);
canvas.width = Math.floor(viewport.width * outputScale);
canvas.height = Math.floor(viewport.height * outputScale);
@ -76,9 +80,10 @@ class JsPdfPreview{
domWidth = Math.floor(this.options.width);
domHeight = Math.floor(domHeight * scale);
}
if(domWidth > document.documentElement.clientWidth){
let scale = document.documentElement.clientWidth / domWidth;
domWidth = Math.floor(document.documentElement.clientWidth);
let wrapperWidth = this.wrapperMain.getBoundingClientRect().width - 20;
if(domWidth > wrapperWidth){
let scale = wrapperWidth / domWidth;
domWidth = Math.floor(wrapperWidth);
domHeight = Math.floor(domHeight * scale);
}
@ -96,7 +101,7 @@ class JsPdfPreview{
});
return renderTask.promise.then(() => {
if (this.pdfDocument.numPages > num) {
this.renderSinglePage(num + 1);
return this.renderSinglePage(num + 1);
}
});
});
@ -104,6 +109,13 @@ class JsPdfPreview{
renderPage(){
if(!this.wrapperMain){
this.createWrapperMain();
}else{
let canvas = this.wrapperMain.querySelectorAll('canvas');
if(canvas.length > this.pdfDocument.numPages){
for(let i = canvas.length-1; i >= this.pdfDocument.numPages; i--){
this.wrapperMain.removeChild(canvas[i]);
}
}
}
return this.renderSinglePage(1);
}
@ -145,6 +157,14 @@ class JsPdfPreview{
});
}));
}
rerender(){
return this.renderPage().then(_=>{
return Promise.resolve();
}).catch(e=>{
this.clearAllCanvas();
return Promise.reject(e);
});
}
save(fileName){
this.pdfDocument && this.pdfDocument._transport && this.pdfDocument._transport.getData().then(fileData=>{
downloadFile(fileName || `js-preview-pdf-${new Date().getTime()}.pdf`,fileData.buffer);

View File

@ -1,6 +1,7 @@
declare const VueOfficePdf: {
install?: (vue: any) => void;
src: string|ArrayBuffer|Blob;
rerender: () => any;
staticFileUrl?: string,
requestOptions?: any;
options?: any

View File

@ -1,6 +1,6 @@
{
"name": "@vue-office/pdf",
"version": "1.5.1",
"version": "1.5.2",
"description": "",
"main": "lib/index.js",
"files": [

View File

@ -30,6 +30,7 @@ export default defineComponent({
setup(props, { emit }) {
let pdfDocument = null;
let loadingTask = null;
const wrapperRef = ref(null);
const rootRef = ref([]);
const numPages = ref(0);
@ -107,9 +108,10 @@ export default defineComponent({
domWidth = Math.floor(props.options.width);
domHeight = Math.floor(domHeight * scale);
}
if (domWidth > document.documentElement.clientWidth) {
let scale = document.documentElement.clientWidth / domWidth;
domWidth = Math.floor(document.documentElement.clientWidth);
let wrapperWidth = wrapperRef.value.getBoundingClientRect().width - 20;
if (domWidth > wrapperWidth) {
let scale = wrapperWidth / domWidth;
domWidth = Math.floor(wrapperWidth);
domHeight = Math.floor(domHeight * scale);
}
@ -140,6 +142,9 @@ export default defineComponent({
}
function rerender(){
renderPage(1);
}
onMounted(() => {
if (props.src) {
checkPdfLib().then(init).catch(e => {
@ -159,10 +164,12 @@ export default defineComponent({
});
}
return {
wrapperRef,
rootRef,
numPages,
save,
onScrollPdf
onScrollPdf,
rerender
};
}
});
@ -170,7 +177,7 @@ export default defineComponent({
<template>
<div class="vue-office-pdf" ref="vue-office-pdf" style="text-align: center;overflow-y: auto;" @scroll="onScrollPdf">
<div v-if="numPages" class="vue-office-pdf-wrapper" style="background: gray; padding: 30px 0;position: relative;">
<div v-if="numPages" ref="wrapperRef" class="vue-office-pdf-wrapper" style="background: gray; padding: 30px 0;position: relative;">
<canvas v-for="page in numPages" ref="rootRef" :key="page" style="width:100%" />
</div>
</div>

View File

@ -1,5 +1,5 @@
<template>
<div ref="dom" style="height: calc(100vh - 50px)">
<div ref="dom" style="height: calc(100vh - 50px);">
</div>
</template>
@ -18,6 +18,7 @@ onMounted(() => {
console.log('err',err);
});
});
</script>

View File

@ -2,7 +2,7 @@
import VueOfficePdf from '../../packages/vue-pdf/index';
import PreviewWrapper from '../common/PreviewWrapper.vue';
import useLoading from '../hooks/useLoading.js';
import {ref} from "vue";
import {ref} from 'vue';
function onRendered(){
useLoading.hideLoading();
}
@ -15,6 +15,7 @@ const defaultSrc = location.origin +
+ 'static/test-files/test.pdf';
const docxRef = ref();
window.docxRef = docxRef;
// setTimeout(()=>{
// console.log( docxRef.value.download());
// }, 2000);