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 { export interface JsPdfPreview {
preview: (src: string | ArrayBuffer | Blob) => Promise<any>; preview: (src: string | ArrayBuffer | Blob) => Promise<any>;
rerender: () => Promise<any>;
save: (fileName?: string) => void; save: (fileName?: string) => void;
setOptions: (options: Options) => void; setOptions: (options: Options) => void;
setRequestOptions: (requestOptions?: any) => void; setRequestOptions: (requestOptions?: any) => void;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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