UNPKG

kdf-pdf-tools

Version:

A powerful React component library for viewing, annotating, and managing PDFs and Markdown documents with BBox support and multimedia attachments. Perfect for document annotation systems.

289 lines (218 loc) 7.7 kB
# KDF PDF Tools > 一个强大的 React PDF 组件库,支持文档查看、BBox 标注和多媒体附件管理 [![npm version](https://img.shields.io/npm/v/kdf-pdf-tools.svg)](https://www.npmjs.com/package/kdf-pdf-tools) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ## ✨ 特性 - 📄 **PDF 文档查看** - 基于 react-pdf,支持高质量 PDF 渲染 - 🎯 **BBox 标注** - 支持边界框(BBox)标注和可视化 - 📎 **多媒体附件** - 支持图片、视频、音频、3D 模型等多种文件类型 - ✏️ **可编辑模式** - 支持上传、删除、显示/隐藏多媒体文件 - 🔌 **完整 API** - 通过 ref 暴露强大的 API,方便与后端集成 - 📱 **响应式设计** - 自适应不同屏幕尺寸 - 🎨 **可定制** - 支持自定义样式和行为 ## 📦 安装 ```bash npm install kdf-pdf-tools react react-dom react-pdf pdfjs-dist ``` 或使用 yarn: ```bash yarn add kdf-pdf-tools react react-dom react-pdf pdfjs-dist ``` ## ⚡ Worker 自动配置 **无需手动配置!** 从 v2.0.0 开始,PDF.js worker 会自动配置: - ✅ 自动使用 CDN(jsDelivr)- 开箱即用 - ✅ 自动版本匹配 - 与 pdfjs-dist 包版本一致 - ✅ 跨平台兼容 - 支持 Vite/Webpack/CRA/Next.js - ✅ 支持自定义 worker 路径(可选) 详细信息请查看 [WORKER_SETUP.md](./WORKER_SETUP.md) ## 🚀 快速开始 ### 基本用法 ```jsx import { KDFReader } from 'kdf-pdf-tools' function App() { return ( <KDFReader pdfUrl="https://example.com/document.pdf" editable={true} /> ) } ``` ### 带 BBox 标注 ```jsx import { KDFReader } from 'kdf-pdf-tools' const bboxData = { blocksByPage: { "1": [ { id: "block_1", bbox: [100, 100, 200, 150], type: "text" } ] } } function App() { return ( <KDFReader pdfUrl="https://example.com/document.pdf" bboxData={bboxData} editable={true} /> ) } ``` ### 使用 Ref API ```jsx import { useRef } from 'react' import { KDFReader } from 'kdf-pdf-tools' function App() { const kdfReaderRef = useRef(null) const handleUpload = async () => { // 获取 PDF File 对象 const pdfFile = kdfReaderRef.current.getPdfFile() // 获取多媒体 File 对象 const multimediaFiles = kdfReaderRef.current.getMultimediaFiles() // 创建 FormData 并上传 const formData = new FormData() formData.append('pdf', pdfFile) multimediaFiles.forEach((item, index) => { formData.append(`multimedia_${index}`, item.file) formData.append(`multimedia_${index}_bboxId`, item.bboxId) }) // 发送到服务器 await fetch('/api/upload', { method: 'POST', body: formData }) } return ( <div> <KDFReader ref={kdfReaderRef} pdfUrl={pdfFile} bboxData={bboxData} editable={true} /> <button onClick={handleUpload}>上传到服务器</button> </div> ) } ``` ## 📚 Props | Prop | 类型 | 必填 | 默认值 | 描述 | |------|------|------|--------|------| | `pdfUrl` | `string \| File` | ✅ | - | PDF 文件 URL 或 File 对象 | | `bboxData` | `Object` | ❌ | `null` | BBox 标注数据 | | `editable` | `boolean` | ❌ | `false` | 是否可编辑(显示上传/删除按钮) | | `multimedias` | `Array` | ❌ | `[]` | 已存在的多媒体文件 | | `width` | `number` | ❌ | `900` | 查看器宽度 | | `onMultimediaChange` | `Function` | ❌ | `null` | 多媒体变化回调 | | `documentOptions` | `Object` | ❌ | - | PDF.js 文档选项 | | `workerSrc` | `string` | ❌ | auto | 自定义 worker 路径(自动配置) | | `fileSizeLimits` | `Object` | ❌ | 见下表 | 文件大小限制 | | `style` | `Object` | ❌ | `{}` | 容器自定义样式 | ### 默认文件大小限制 | 类型 | 限制 | |------|------| | 图片 | 10 MB | | 视频 | 100 MB | | 音频 | 20 MB | | 3D模型 | 50 MB | | PDF | 50 MB | 详见 [FILE_SIZE_LIMITS.md](./FILE_SIZE_LIMITS.md) ## 🔌 Ref API 通过 `ref` 可以访问以下方法: ### PDF 相关 - `getPdfFile()` - 获取 PDF File 对象 - `getPdfUrl()` - 获取 PDF URL - `getPdfDocument()` - 获取 pdf.js Document 对象 - `getNumPages()` - 获取 PDF 页数 ### 多媒体相关 - `getMultimedias()` - 获取多媒体元数据 - `getMultimediaFiles()` ⭐ - 获取多媒体 File 对象(用于上传) - `getMultimediaByBboxId(bboxId)` - 获取指定 bbox 的元数据 - `getMultimediaFileByBboxId(bboxId)` ⭐ - 获取指定 bbox 的 File 对象 ### 数据相关 - `getBboxData()` - 获取 BBox 数据 - `getSnapshot()` - 获取完整数据快照 详细的 API 文档请参考 [REF_API.md](./REF_API.md) ## 📖 文档 - **[API 文档](./API.md)** - 完整的组件 API 说明 - **[Ref API 文档](./REF_API.md)** - Ref 方法详细说明 - **[使用示例](./EXAMPLES.md)** - 更多实用示例 - **[快速参考](./QUICK_REFERENCE.md)** - 快速上手指南 ## 🎯 支持的文件类型 | 类型 | 支持格式 | 功能 | |------|---------|------| | 图片 | jpg, png, gif, webp | 查看、适应/填充、显示/隐藏 | | 视频 | mp4, webm, ogg | 播放控制、进度条 | | 音频 | mp3, wav, ogg | 播放控制、进度条 | | 3D 模型 | gltf, glb | 预留支持 | ## 💡 示例 ### 上传 PDF + 多媒体文件到服务器 ```jsx const handleUploadAll = async () => { const pdfFile = kdfReaderRef.current.getPdfFile() const multimediaFiles = kdfReaderRef.current.getMultimediaFiles() const formData = new FormData() formData.append('pdf', pdfFile) multimediaFiles.forEach((item, index) => { formData.append(`multimedia_${index}`, item.file) formData.append(`multimedia_${index}_bboxId`, item.bboxId) formData.append(`multimedia_${index}_metadata`, JSON.stringify(item.metadata)) }) const response = await fetch('/api/documents/upload-all', { method: 'POST', body: formData }) const result = await response.json() console.log('上传成功:', result) } ``` ### 后端示例 (Node.js + Express) ```javascript const express = require('express') const multer = require('multer') const app = express() const upload = multer({ dest: 'uploads/' }) app.post('/api/documents/upload-all', upload.any(), (req, res) => { const files = req.files const pdfFile = files.find(f => f.fieldname === 'pdf') const multimediaFiles = files.filter(f => f.fieldname.startsWith('multimedia_')) const mediaMapping = multimediaFiles.map(file => { const index = file.fieldname.split('_')[1] return { filename: file.filename, bboxId: req.body[`multimedia_${index}_bboxId`], metadata: JSON.parse(req.body[`multimedia_${index}_metadata`]) } }) res.json({ success: true, pdf: pdfFile.filename, multimedias: mediaMapping }) }) ``` 更多示例请查看 [EXAMPLES.md](./EXAMPLES.md) ## 🛠️ 开发 ### 构建 ```bash npm run build ``` ### 发布 ```bash npm publish ``` ## ⚠️ 注意事项 1. **Worker 自动配置**:PDF.js worker 会自动配置,无需手动设置(详见 [WORKER_SETUP.md](./WORKER_SETUP.md)) 2. **CORS 配置**:PDF 和多媒体文件需要正确的 CORS 配置 3. **File 对象**`getMultimediaFiles()` 只返回通过上传的文件,URL 加载的文件不会返回 File 对象 4. **Blob URL 清理**:使用 `URL.createObjectURL()` 后记得清理 ## 📄 许可证 MIT © [Your Name] ## 🤝 贡献 欢迎提交 Issue 和 Pull Request! ## 📮 联系方式 如有问题,请提交 [Issue](https://github.com/yourusername/kdf-pdf-tools/issues)