需要使用pdf.js插件
https://github.com/mozilla/pdf.js
html部分
<div class="pdf-container"><div class="viewer"><div class="loading text-center mb-4" id="loading">正在加载PDF文档...</div><div class="error" id="error"></div><canvas id="pdf-canvas" class="border w-full h-[480px]"></canvas><div class="controls flex items-center justify-between py-4"><button class="btn" id="prev-btn" disabled>上一页</button><div class="page-info text-xs">第 <span id="page-num">0</span> 页 / 共 <span id="page-count">0</span> 页</div><button class="btn" id="next-btn" disabled>下一页</button></div></div> </div>
引入js
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.min.js"></script> <script>// 设置PDF.js worker路径 pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.worker.min.js';// PDF文档变量F let pdfDoc = null;let pageNum = 1;let pageRendering = false;let pageNumPending = null;let scale = 1.5;let maxScale = 2.5;let minScale = 0.8;// DOM元素引用 let canvas, ctx, loading, errorDiv, pageNumDisplay, pageCountDisplay;let prevBtn, nextBtn, zoomInBtn, zoomOutBtn;// 初始化函数 - 在DOM加载完成后调用function initPdfViewer() {// 获取DOM元素 canvas = document.getElementById('pdf-canvas');ctx = canvas.getContext('2d');loading = document.getElementById('loading');errorDiv = document.getElementById('error');pageNumDisplay = document.getElementById('page-num');pageCountDisplay = document.getElementById('page-count');prevBtn = document.getElementById('prev-btn');nextBtn = document.getElementById('next-btn');zoomInBtn = document.getElementById('zoom-in');zoomOutBtn = document.getElementById('zoom-out');// 初始化事件监听if (prevBtn) prevBtn.addEventListener('click', onPrevPage);if (nextBtn) nextBtn.addEventListener('click', onNextPage);if (zoomInBtn) zoomInBtn.addEventListener('click', zoomIn);if (zoomOutBtn) zoomOutBtn.addEventListener('click', zoomOut);// 初始化PDF文档 loadPdfDocument();}// 显示错误信息function showError(message) {if (errorDiv) {errorDiv.textContent = message;errorDiv.style.display = 'block';}if (loading) loading.style.display = 'none';console.error('PDF Viewer Error:', message);}// 渲染PDF页面function renderPage(num) {if (!pdfDoc || !canvas) {showError('PDF文档或画布未初始化');return;}pageRendering = true;if (loading) loading.style.display = 'block';if (errorDiv) errorDiv.style.display = 'none';pdfDoc.getPage(num).then(function (page) {const viewport = page.getViewport({ scale });canvas.height = viewport.height;canvas.width = viewport.width;const renderContext = {canvasContext: ctx,viewport: viewport};const renderTask = page.render(renderContext);renderTask.promise.then(function () {pageRendering = false;if (loading) loading.style.display = 'none';if (pageNumPending !== null) {renderPage(pageNumPending);pageNumPending = null;}if (pageNumDisplay) pageNumDisplay.textContent = num;if (pageCountDisplay) pageCountDisplay.textContent = pdfDoc.numPages;// 更新按钮状态if (prevBtn) prevBtn.disabled = num <= 1;if (nextBtn) nextBtn.disabled = num >= pdfDoc.numPages;});}).catch(function (error) {showError('页面渲染错误: ' + error.message);});}// 队列渲染function queueRenderPage(num) {if (pageRendering) {pageNumPending = num;} else {renderPage(num);}}// 上一页function onPrevPage() {if (pageNum <= 1) return;pageNum--;queueRenderPage(pageNum);}// 下一页function onNextPage() {if (!pdfDoc || pageNum >= pdfDoc.numPages) return;pageNum++;queueRenderPage(pageNum);}// 放大function zoomIn() {if (scale >= maxScale) return;scale += 0.1;scale = Math.round(scale * 10) / 10;queueRenderPage(pageNum);}// 缩小function zoomOut() {Fif (scale <= minScale) return;scale -= 0.1;scale = Math.round(scale * 10) / 10;queueRenderPage(pageNum);}// 加载PDF文档function loadPdfDocument() {if (loading) loading.textContent = '正在加载PDF文档...';// 替换下面的URL为您要显示的PDF文件URL const pdfUrl = './assets/demo.pdf'; // 您的PDF文件路径 pdfjsLib.getDocument(pdfUrl).promise.then(function (pdf) {pdfDoc = pdf;if (loading) loading.textContent = '加载完成!';// 初始化渲染第一页 renderPage(pageNum);}).catch(function (error) {let errorMsg = '加载失败: ' + error.message;// 提供更具体的错误信息if (error.message.includes('404')) {errorMsg = 'PDF文件未找到。请检查路径: ' + pdfUrl;} else if (error.message.includes('CORS')) {errorMsg = '跨域访问被拒绝。请将PDF文件放在同一域名下或配置CORS。';}showError(errorMsg);});}// 确保所有DOM元素都已加载完成后再执行初始化if (document.readyState === 'loading') {document.addEventListener('DOMContentLoaded', initPdfViewer);} else {// DOMContentLoaded已经触发 initPdfViewer();} </script>