点击时将Bytes[]转为PDF并在右侧预览的实现方案求助
解决大体积PDF字节数据预览的方案
方案1:使用Blob + Object URL替代Data URL(推荐)
原方案使用Data URL将Base64字符串直接嵌入iframe的src中,当PDF体积较大时会触发浏览器的URL长度限制。Object URL是浏览器在内存中创建的临时引用,无长度限制且内存占用更高效,是解决该问题的最优方案。
情况1:result是Base64字符串
function GetPdf(result) { // 将Base64字符串转换为Uint8Array const binaryStr = atob(result); const pdfBytes = new Uint8Array(binaryStr.length); for (let i = 0; i < binaryStr.length; i++) { pdfBytes[i] = binaryStr.charCodeAt(i); } // 创建PDF Blob对象 const pdfBlob = new Blob([pdfBytes], { type: 'application/pdf' }); // 生成Object URL const pdfUrl = URL.createObjectURL(pdfBlob); // 更新预览容器内容 $("#DisplayPDF").html( $("<iframe>", { src: pdfUrl, width: '100%', height: '100%', frameborder: '0' }) ); // 可选:释放旧的Object URL避免内存泄漏(切换预览时启用) // if (window.prevPdfUrl) URL.revokeObjectURL(window.prevPdfUrl); // window.prevPdfUrl = pdfUrl; }
情况2:result是原始字节数组(ArrayBuffer/Uint8Array)
function GetPdf(result) { // 直接用字节数组创建Blob const pdfBlob = new Blob([result], { type: 'application/pdf' }); const pdfUrl = URL.createObjectURL(pdfBlob); $("#DisplayPDF").html( $("<iframe>", { src: pdfUrl, width: '100%', height: '100%', frameborder: '0' }) ); // 可选:内存清理 // if (window.prevPdfUrl) URL.revokeObjectURL(window.prevPdfUrl); // window.prevPdfUrl = pdfUrl; }
方案2:使用PDF.js进行自定义渲染(适合交互/定制化场景)
如果需要更灵活的预览效果(比如自定义工具栏、分页控制、缩放等),可以用PDF.js直接将PDF内容渲染到Canvas,摆脱对浏览器内置PDF查看器的依赖。
示例代码
function GetPdf(result) { // 转换为Uint8Array(若result是Base64) const binaryStr = atob(result); const pdfBytes = new Uint8Array(binaryStr.length); for (let i = 0; i < binaryStr.length; i++) { pdfBytes[i] = binaryStr.charCodeAt(i); } const pdfBlob = new Blob([pdfBytes], { type: 'application/pdf' }); // 加载PDF文档(需提前将PDF.js库下载到本地项目中) const loadingTask = pdfjsLib.getDocument(URL.createObjectURL(pdfBlob)); loadingTask.promise.then(pdf => { const container = document.getElementById('DisplayPDF'); container.innerHTML = ''; // 清空旧内容 // 渲染第一页(如需渲染全部页,可循环调用pdf.getPage(pageNum)) pdf.getPage(1).then(page => { const scale = 1.5; // 缩放比例 const viewport = page.getViewport({ scale }); // 创建Canvas元素 const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = viewport.width; canvas.height = viewport.height; container.appendChild(canvas); // 渲染PDF页面到Canvas const renderCtx = { canvasContext: ctx, viewport: viewport }; page.render(renderCtx); }); }).catch(err => { console.error('PDF加载失败:', err); document.getElementById('DisplayPDF').innerHTML = '<p>无法预览PDF,请检查文件是否损坏</p>'; }); }
关键注意点
- 内存管理:使用Object URL后,需在不需要时调用
URL.revokeObjectURL(pdfUrl)释放内存,尤其是频繁切换预览文件时。 - 兼容性:Blob和Object URL支持所有现代浏览器及IE10+,PDF.js兼容绝大多数主流浏览器。
- 自适应布局:将iframe宽高设为100%,可更好适配父容器尺寸。
内容的提问来源于stack exchange,提问作者Michaelweston
相关产品推荐
相关产品推荐

