npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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.

Readme

KDF PDF Tools

一个强大的 React PDF 组件库,支持文档查看、BBox 标注和多媒体附件管理

npm version License: MIT

✨ 特性

  • 📄 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 |

详见 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

📖 文档

🎯 支持的文件类型

| 类型 | 支持格式 | 功能 | |------|---------|------| | 图片 | 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

⚠️ 注意事项

  1. Worker 自动配置:PDF.js worker 会自动配置,无需手动设置(详见 WORKER_SETUP.md
  2. CORS 配置:PDF 和多媒体文件需要正确的 CORS 配置
  3. File 对象getMultimediaFiles() 只返回通过上传的文件,URL 加载的文件不会返回 File 对象
  4. Blob URL 清理:使用 URL.createObjectURL() 后记得清理

📄 许可证

MIT © [Your Name]

🤝 贡献

欢迎提交 Issue 和 Pull Request!

📮 联系方式

如有问题,请提交 Issue