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

使用react-pdf-js加载Base64 PDF遇报错,求解决方法

解决react-pdf-js加载Base64 PDF出现「PDFDocument: stream must have data」的问题

我之前也遇到过react-pdf-js加载Base64 PDF的这个问题,核心原因是react-pdf-js不像react-pdf那样自动处理Base64字符串的转换,它需要的是可读取的数据流格式(比如Blob、ArrayBuffer),而不是纯Base64文本。给你一套可行的解决方案:

1. 先把Base64字符串转换成Blob对象

写一个工具函数,把Base64字符串(带前缀或不带都可以)转换成Blob,这是react-pdf-js能识别的格式:

const base64ToBlob = (base64String) => {
  // 移除Base64前缀(如果存在的话,比如"data:application/pdf;base64,")
  const strippedBase64 = base64String.replace(/^data:application\/pdf;base64,/, '');
  // 解码Base64字符串为二进制字符
  const byteCharacters = atob(strippedBase64);
  const byteArrays = [];

  // 分批处理二进制字符,转成Uint8Array
  for (let offset = 0; offset < byteCharacters.length; offset += 512) {
    const slice = byteCharacters.slice(offset, offset + 512);
    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }

  // 创建Blob对象,指定MIME类型为PDF
  return new Blob(byteArrays, { type: 'application/pdf' });
};

2. 在组件中使用转换后的Blob加载PDF

把转换后的Blob传给react-pdf-js的Document组件,同时实现分页功能:

import React, { useState, useEffect } from 'react';
import { Document, Page } from 'react-pdf-js';

const Base64PdfViewer = ({ base64Pdf }) => {
  const [pdfBlob, setPdfBlob] = useState(null);
  const [totalPages, setTotalPages] = useState(null);
  const [currentPage, setCurrentPage] = useState(1);

  // 当传入的Base64 PDF变化时,转换为Blob
  useEffect(() => {
    if (base64Pdf) {
      const blob = base64ToBlob(base64Pdf);
      setPdfBlob(blob);
    }
  }, [base64Pdf]);

  // 文档加载成功后获取总页数
  const handleDocumentLoad = ({ numPages }) => {
    setTotalPages(numPages);
  };

  return (
    <div className="pdf-viewer">
      {pdfBlob && (
        <>
          <Document file={pdfBlob} onLoadSuccess={handleDocumentLoad}>
            <Page pageNumber={currentPage} />
          </Document>
          {/* 分页控制按钮 */}
          <div className="pagination-controls">
            <span>第 {currentPage} 页 / 共 {totalPages} 页</span>
            <button
              onClick={() => setCurrentPage(prev => Math.max(prev - 1, 1))}
              disabled={currentPage === 1}
            >
              上一页
            </button>
            <button
              onClick={() => setCurrentPage(prev => Math.min(prev + 1, totalPages))}
              disabled={currentPage === totalPages}
            >
              下一页
            </button>
          </div>
        </>
      )}
    </div>
  );
};

// 别忘了引入上面的base64ToBlob函数
export default Base64PdfViewer;

关键注意点

  • 移除Base64前缀:如果你的Base64字符串带有data:application/pdf;base64,前缀,一定要先移除,否则atob解码会失败,导致无法生成有效的Blob。
  • 不要直接传Base64字符串:react-pdf-js的file属性不接受纯Base64文本,必须是Blob、File、URL或ArrayBuffer类型,这就是你出现「PDFDocument: stream must have data」错误的根本原因。
  • 处理大PDF:如果你的PDF文件很大,可以考虑用异步方式转换Base64,但普通大小的PDF用上面的同步方法完全没问题。

内容的提问来源于stack exchange,提问作者terrabl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:12:41