如何在React中使用PDF.js正确解析PDF文件?
在React中正确解析上传PDF的解决方案
问题核心原因
你遇到的MissingPDFException主要由两个关键错误导致:
- FileReader未执行读取操作:代码中创建了
FileReader但未调用readAsArrayBuffer(file),导致文件内容从未被加载,pdfFile始终为undefined,pdf.js误将其当作URL解析引发路径错误。 - 二进制数据类型不匹配:使用
Uint32Array存储文件数据,pdf.js无法正确识别该类型,进而触发无效路径的加载逻辑。
基于pdf.js的修复方案
1. 修正文件上传组件(Home)
import { useState } from 'react'; import PDFViewer from './PDFViewer'; export default function Home() { const [pdfBuffer, setPdfBuffer] = useState(null); const handleFileUpload = (e) => { const file = e.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = (event) => { // 直接传入ArrayBuffer,pdf.js原生支持该类型 setPdfBuffer(event.target.result); }; // 关键:执行文件读取操作 reader.readAsArrayBuffer(file); }; return ( <> <h1>PDF内容提取工具</h1> <input type="file" accept="application/pdf" onChange={handleFileUpload} /> {/* 仅当文件加载完成后再渲染解析组件 */} {pdfBuffer && <PDFViewer pdfBuffer={pdfBuffer} />} </> ); }
2. 修正PDF解析组件(PDFViewer)
import { useEffect, useCallback, useState } from 'react'; import * as PDFJS from 'pdfjs-dist/build/pdf'; import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'; // 全局配置worker,仅需设置一次 PDFJS.GlobalWorkerOptions.workerSrc = pdfjsWorker; export default function PDFViewer({ pdfBuffer }) { const [fullText, setFullText] = useState(''); const extractPdfContent = useCallback(async () => { try { // 直接获取文档实例 const pdfDoc = await PDFJS.getDocument(pdfBuffer).promise; let text = ''; // 循环提取所有页面文本 for (let i = 1; i <= pdfDoc.numPages; i++) { const page = await pdfDoc.getPage(i); const textContent = await page.getTextContent(); text += textContent.items.map(item => item.str).join(' '); } setFullText(text); } catch (error) { console.error('PDF解析失败:', error); } }, [pdfBuffer]); useEffect(() => { extractPdfContent(); }, [pdfBuffer, extractPdfContent]); return ( <div className="pdf-content"> <h2>提取的PDF文本</h2> <pre>{fullText}</pre> </div> ); }
更简洁的替代库推荐
如果仅需提取PDF文本内容,推荐使用pdf-parse,它封装了pdf.js的核心逻辑,用法更简洁:
import { useState } from 'react'; import pdf from 'pdf-parse'; export default function Home() { const [pdfText, setPdfText] = useState(''); const handleFileUpload = async (e) => { const file = e.target.files[0]; if (!file) return; try { // 直接传入File对象即可解析 const data = await pdf(file); setPdfText(data.text); } catch (error) { console.error('解析失败:', error); } }; return ( <> <h1>PDF文本提取</h1> <input type="file" accept="application/pdf" onChange={handleFileUpload} /> {pdfText && <pre>{pdfText}</pre>} </> ); }
webpack环境注意事项:如果遇到模块解析错误,可在webpack.config.js中添加如下规则:
module.exports = { module: { rules: [ { test: /\.pdf$/, type: 'asset/source' } ] } };
内容的提问来源于stack exchange,提问作者HelloWorldEngineer
相关产品推荐
相关产品推荐

