使用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
相关产品推荐
相关产品推荐

