如何在React应用中实现PDF的上传、查看与编辑功能?
React 实现PDF上传、查看及页面编辑方案
功能总览
整个实现分为三个核心模块:
- PDF上传模块:负责本地PDF文件选择、上传到后端存储
- PDF查看模块:支持PDF渲染、翻页、缩放等基础查看操作
- PDF编辑模块:支持页面删除、新增等操作,所有编辑操作可实时预览
1. PDF上传功能实现
前端仅需要处理文件选择和提交逻辑,后端上传逻辑可直接复用现有实现:
// React端上传组件示例 const PdfUploader = () => { const handleFileChange = async (e) => { const file = e.target.files[0] if (file.type !== 'application/pdf') return alert('请选择PDF文件') // 存储文件的ArrayBuffer供后续编辑使用 const arrayBuffer = await file.arrayBuffer() // 上传到后端 const formData = new FormData() formData.append('pdfFile', file) await fetch('/api/upload', { method: 'POST', body: formData }) } return <input type="file" accept=".pdf" onChange={handleFileChange} /> }
2. PDF查看功能实现
使用 react-pdf 库实现前端PDF渲染,无需依赖后端接口:
- 安装依赖:
npm install react-pdf - 配置PDF worker:将对应版本的pdf.worker.js放到项目静态资源目录直接引用即可
- 渲染示例:
import { Document, Page, pdfjs } from 'react-pdf' // 引用本地静态资源的worker文件 pdfjs.GlobalWorkerOptions.workerSrc = '/static/pdf.worker.min.js' const PdfViewer = ({ pdfData }) => { const [pageNum, setPageNum] = useState(1) const [totalPage, setTotalPage] = useState(0) return ( <div> <Document file={pdfData} onLoadSuccess={({ numPages }) => setTotalPage(numPages)}> <Page pageNumber={pageNum} scale={1.5} /> </Document> <div> <button onClick={() => setPageNum(prev => Math.max(1, prev-1))}>上一页</button> <span>{pageNum} / {totalPage}</span> <button onClick={() => setPageNum(prev => Math.min(totalPage, prev+1))}>下一页</button> </div> </div> ) }
3. PDF页面编辑功能实现
使用 pdf-lib 库实现纯前端PDF页面编辑,无需调用后端接口:
- 安装依赖:
npm install pdf-lib - 删除指定页面示例:
import { PDFDocument } from 'pdf-lib' const deletePdfPage = async (originPdfBuffer, targetPageIndex) => { // 加载原PDF,注意内部页码从0开始计数,展示给用户的第1页对应索引0 const pdfDoc = await PDFDocument.load(originPdfBuffer) // 删除指定页 pdfDoc.removePage(targetPageIndex) // 生成新的PDF数据,可直接传给预览组件,也可导出上传后端 const newPdfBuffer = await pdfDoc.save() return newPdfBuffer }
- 新增页面示例:
const addPdfPage = async (originPdfBuffer, insertPosition = 0) => { const pdfDoc = await PDFDocument.load(originPdfBuffer) // 插入A4尺寸空白页,也可以通过copyPages方法导入其他PDF的页面插入 pdfDoc.insertPage(insertPosition, [595.28, 841.89]) const newPdfBuffer = await pdfDoc.save() return newPdfBuffer }
4. 流程串接建议
- 上传PDF后同时存储原始文件的ArrayBuffer,作为编辑的初始数据源
- 所有增删页操作调用pdf-lib处理后,将新生成的Buffer传给PDF查看组件实时预览
- 编辑完成后,将最终的PDF Buffer转成Blob对象,封装为FormData上传到后端存储
- 面向用户展示的页码统一从1开始计数,内部调用API时自动减1转换为索引,避免操作错误
内容的提问来源于stack exchange,提问作者Saiful
相关产品推荐
相关产品推荐

