获取 canvas 元素的 getContext
方法时,canvas 元素尚未正确绑定。可以通过确保在渲染 PDF 文件之前,canvas 元素已经正确挂载到 DOM 来解决这个问题。
解决方法
- 确保
pdfCanvas
引用已经绑定到正确的 DOM 元素。 - 确保在渲染 PDF 文件时,canvas 元素已经挂载。
使用 nextTick
确保在尝试渲染 PDF 文件之前,canvas 元素已经正确挂载
<template>
<div>
<button @click="triggerFileInput">选择文件</button>
<input type="file" ref="fileInput" @change="handleFileChange" style="display: none;" />
<div v-if="loading">上传中...</div>
<div v-if="error" class="error">{{ error }}</div>
<div v-if="selectedFile" class="pdf-container">
<canvas ref="pdfCanvas"></canvas>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick } from 'vue';
import * as pdfjsLib from 'pdfjs-dist';
// 设置 pdf.worker.js 路径
pdfjsLib.GlobalWorkerOptions.workerSrc = '/pdf.worker.js';
const fileInput = ref(null);
const selectedFile = ref(null);
const loading = ref(false);
const error = ref(null);
const pdfCanvas = ref(null);
const triggerFileInput = () => {
fileInput.value.click();
};
const handleFileChange = async (event) => {
const files = event.target.files;
if (files.length > 0) {
const file = files[0];
selectedFile.value = file;
// 等待 DOM 更新完成后再渲染 PDF
await nextTick();
renderPdf(file);
}
};
const renderPdf = (file) => {
loading.value = true;
error.value = null;
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function() {
const arrayBuffer = reader.result;
const uint8Array = new Uint8Array(arrayBuffer);
pdfjsLib.getDocument({ data: uint8Array }).promise.then(pdfDoc => {
return pdfDoc.getPage(1).then(page => {
const viewport = page.getViewport({ scale: 1.5 });
const canvas = pdfCanvas.value;
const context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
const renderContext = {
canvasContext: context,
viewport: viewport
};
return page.render(renderContext).promise;
});
}).then(() => {
loading.value = false;
}).catch(err => {
error.value = '加载 PDF 文件失败';
console.error('加载 PDF 出错', err);
loading.value = false;
});
};
reader.onerror = function(err) {
error.value = '读取文件失败';
console.error('读取文件出错', err);
loading.value = false;
};
};
</script>
<style scoped>
button {
margin: 10px 0;
padding: 10px 20px;
font-size: 16px;
}
.pdf-container {
margin-top: 20px;
}
canvas {
border: 1px solid #ccc;
width: 100%;
}
.error {
color: red;
margin-top: 10px;
}
</style>