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
Markdown
# KDF PDF Tools
> 一个强大的 React PDF 组件库,支持文档查看、BBox 标注和多媒体附件管理
[](https://www.npmjs.com/package/kdf-pdf-tools)
[](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)