You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

点击时将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 15:50:16