kdf-pdf-tools
v2.5.2
Published
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.
Maintainers
Readme
KDF PDF Tools
一个强大的 React PDF 组件库,支持文档查看、BBox 标注和多媒体附件管理
✨ 特性
- 📄 PDF 文档查看 - 基于 react-pdf,支持高质量 PDF 渲染
- 🎯 BBox 标注 - 支持边界框(BBox)标注和可视化
- 📎 多媒体附件 - 支持图片、视频、音频、3D 模型等多种文件类型
- ✏️ 可编辑模式 - 支持上传、删除、显示/隐藏多媒体文件
- 🔌 完整 API - 通过 ref 暴露强大的 API,方便与后端集成
- 📱 响应式设计 - 自适应不同屏幕尺寸
- 🎨 可定制 - 支持自定义样式和行为
📦 安装
npm install kdf-pdf-tools react react-dom react-pdf pdfjs-dist或使用 yarn:
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
🚀 快速开始
基本用法
import { KDFReader } from 'kdf-pdf-tools'
function App() {
return (
<KDFReader
pdfUrl="https://example.com/document.pdf"
editable={true}
/>
)
}带 BBox 标注
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
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 |
🔌 Ref API
通过 ref 可以访问以下方法:
PDF 相关
getPdfFile()- 获取 PDF File 对象getPdfUrl()- 获取 PDF URLgetPdfDocument()- 获取 pdf.js Document 对象getNumPages()- 获取 PDF 页数
多媒体相关
getMultimedias()- 获取多媒体元数据getMultimediaFiles()⭐ - 获取多媒体 File 对象(用于上传)getMultimediaByBboxId(bboxId)- 获取指定 bbox 的元数据getMultimediaFileByBboxId(bboxId)⭐ - 获取指定 bbox 的 File 对象
数据相关
getBboxData()- 获取 BBox 数据getSnapshot()- 获取完整数据快照
详细的 API 文档请参考 REF_API.md
📖 文档
- API 文档 - 完整的组件 API 说明
- Ref API 文档 - Ref 方法详细说明
- 使用示例 - 更多实用示例
- 快速参考 - 快速上手指南
🎯 支持的文件类型
| 类型 | 支持格式 | 功能 | |------|---------|------| | 图片 | jpg, png, gif, webp | 查看、适应/填充、显示/隐藏 | | 视频 | mp4, webm, ogg | 播放控制、进度条 | | 音频 | mp3, wav, ogg | 播放控制、进度条 | | 3D 模型 | gltf, glb | 预留支持 |
💡 示例
上传 PDF + 多媒体文件到服务器
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)
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
🛠️ 开发
构建
npm run build发布
npm publish⚠️ 注意事项
- Worker 自动配置:PDF.js worker 会自动配置,无需手动设置(详见 WORKER_SETUP.md)
- CORS 配置:PDF 和多媒体文件需要正确的 CORS 配置
- File 对象:
getMultimediaFiles()只返回通过上传的文件,URL 加载的文件不会返回 File 对象 - Blob URL 清理:使用
URL.createObjectURL()后记得清理
📄 许可证
MIT © [Your Name]
🤝 贡献
欢迎提交 Issue 和 Pull Request!
📮 联系方式
如有问题,请提交 Issue
