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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@szjy/pdf-coms

v0.1.3

Published

vue3 pdf component

Readme

@szjy/pdf-coms

一个功能强大、易于使用的 Vue 3 PDF 编辑器组件库,支持在线编辑 PDF 文档,包括添加图片、文本、绘图等多种对象,并提供完整的交互式编辑体验。

项目简介

@szjy/pdf-coms 是一个基于 Vue 3 和 TypeScript 开发的 PDF 编辑器组件库,旨在为 Web 应用提供强大的 PDF 在线编辑能力。该组件库解决了以下核心问题:

  • 在线 PDF 编辑:无需下载 PDF 文件即可在浏览器中直接编辑
  • 多类型对象支持:支持添加图片、文本、手绘图形等多种对象类型
  • 交互式操作:提供拖拽、缩放、旋转等丰富的交互操作
  • 中文字体支持:内置微软雅黑等中文字体,完美支持中文内容编辑
  • 响应式设计:适配桌面端和移动端,提供一致的用户体验

适用场景

  • 合同文档在线签署与标注
  • PDF 表单填写与编辑
  • 文档审批与批注
  • 图纸标注与说明
  • 教育培训材料编辑

目录结构

pdf-coms/
├── packages/                    # 核心源代码目录
│   ├── api/                    # API 接口层
│   │   └── project.ts          # 项目相关 API
│   ├── common/                 # 通用组件
│   │   ├── PDFObject/          # PDF 对象组件
│   │   │   ├── ImageObject.vue # 图片对象组件
│   │   │   ├── TextObject.vue  # 文本对象组件
│   │   │   └── DrawingObject.vue # 绘图对象组件
│   │   ├── PDFPage.vue         # PDF 页面渲染组件
│   │   ├── DrawingCanvas.vue   # 绘图画布组件
│   │   ├── ThumbnailPanel.vue  # 缩略图面板组件
│   │   ├── ObjectToolbar.vue   # 对象工具栏组件
│   │   └── styles/             # 样式文件
│   ├── components/             # 主要组件
│   │   ├── PdfEditor/          # PDF 编辑器主组件
│   │   │   └── src/
│   │   │       └── index.vue   # 编辑器核心实现
│   │   ├── components.ts       # 组件导出
│   │   ├── installer.ts        # 组件安装器
│   │   ├── create.ts           # 组件创建工具
│   │   └── contants.ts         # 常量定义
│   ├── composables/            # 组合式函数
│   │   ├── useObjects.ts       # 对象管理逻辑
│   │   ├── usePDF.ts           # PDF 处理逻辑
│   │   ├── usePannable.ts      # 拖拽功能逻辑
│   │   └── useClickOutside.ts  # 点击外部检测逻辑
│   ├── types/                  # TypeScript 类型定义
│   │   ├── index.ts            # 类型导出
│   │   ├── objects.ts          # 对象类型定义
│   │   ├── pdf.ts              # PDF 类型定义
│   │   └── errors.ts           # 错误类型定义
│   └── utils/                  # 工具函数
│       ├── pdfOperations.ts    # PDF 操作工具
│       ├── asyncReader.ts      # 异步文件读取
│       ├── assetLoader.ts      # 资源加载器
│       ├── helpers.ts          # 辅助函数
│       ├── request.ts          # HTTP 请求工具
│       └── ...                 # 其他工具函数
├── examples/                   # 示例代码
│   ├── App.vue                 # 示例应用入口
│   ├── components/             # 示例组件
│   │   └── PdfEditorTab.vue    # PDF 编辑器示例
│   └── main.ts                 # 示例应用启动文件
├── dist/                       # 构建输出目录
├── public/                     # 静态资源
│   ├── fonts/                  # 字体文件
│   └── scripts/                # 脚本文件
├── index.ts                    # 库入口文件
├── package.json                # 项目配置
├── vite.config.mts             # Vite 构建配置
├── tsconfig.json               # TypeScript 配置
└── README.md                   # 项目文档

核心模块说明

| 模块 | 职责 | 关键文件 | |------|------|----------| | components | 提供可复用的 UI 组件 | PdfEditor/index.vue | | composables | 封装业务逻辑的组合式函数 | usePDF.ts, useObjects.ts | | types | TypeScript 类型定义,确保类型安全 | objects.ts, pdf.ts | | utils | 通用工具函数和辅助方法 | pdfOperations.ts, asyncReader.ts | | common | 通用 UI 组件和样式 | PDFPage.vue, PDFObject/* |

模块依赖关系

graph TD
    A[PdfEditor 主组件] --> B[composables 组合式函数]
    A --> C[common 通用组件]
    B --> D[utils 工具函数]
    B --> E[types 类型定义]
    C --> E
    D --> E
    C --> B

环境与依赖配置

运行环境要求

  • Node.js: >= 16.0.0
  • 包管理器: pnpm (推荐) / npm / yarn
  • 浏览器兼容性:
    • Chrome >= 90
    • Firefox >= 88
    • Safari >= 14
    • Edge >= 90

核心依赖

| 依赖 | 版本 | 用途 | |------|------|------| | vue | ^3.4.21 | Vue 3 框架 | | element-plus | 2.7.1 | UI 组件库 | | pdfjs-dist | ^2.3.200 | PDF 渲染引擎 | | pdf-lib | ^1.17.1 | PDF 文档操作库 | | axios | ^1.4.0 | HTTP 请求库 | | echarts | ^5.5.0 | 图表库(可选) | | moment | ^2.29.4 | 日期处理库 | | downloadjs | ^1.4.7 | 文件下载工具 |

开发依赖

| 依赖 | 版本 | 用途 | |------|------|------| | typescript | ^5.2.2 | TypeScript 支持 | | vite | ^5.1.6 | 构建工具 | | vite-plugin-dts | ^3.7.3 | TypeScript 声明文件生成 | | unplugin-icons | ^22.1.0 | 图标自动导入 | | unplugin-vue-components | ^0.26.0 | 组件自动导入 | | less | ^4.2.0 | Less 预处理器 | | sass | ^1.79.3 | Sass 预处理器 |

安装步骤

1. 克隆项目(开发者)

git clone <repository-url>
cd pdf-coms

2. 安装依赖

# 使用 pnpm(推荐)
pnpm install

# 或使用 npm
npm install

# 或使用 yarn
yarn install

3. 作为 npm 包使用

npm install @szjy/pdf-coms
# 或
pnpm add @szjy/pdf-coms

推荐开发工具

  • IDE: Visual Studio Code
  • VSCode 插件:
    • Vue Language Features (Volar)
    • TypeScript Vue Plugin (Volar)
    • ESLint
    • Prettier

项目运行指南

开发模式

启动开发服务器,支持热更新:

pnpm dev

服务器将在 http://localhost:8822 启动,并自动打开浏览器。

生产构建

标准构建(生产环境)

pnpm build

构建产物将输出到 dist/ 目录,包括:

  • dist/index.mjs - ES Module 格式
  • dist/index.umd.js - UMD 格式
  • dist/index.d.ts - TypeScript 类型声明文件

开发构建(保留调试信息)

pnpm build:dev

此模式会保留变量名和标识符,便于调试。

预览构建结果

pnpm preview

发布版本

# 自动更新版本号并生成 CHANGELOG
pnpm release

# 同步到 cnpm
pnpm sync

运行模式说明

| 命令 | 模式 | 用途 | 端口 | |------|------|------|------| | pnpm dev | 开发模式 | 本地开发调试 | 8822 | | pnpm build | 生产构建 | 打包发布 | - | | pnpm build:dev | 开发构建 | 调试构建产物 | - | | pnpm preview | 预览模式 | 预览构建结果 | 默认 |

功能模块与使用示例

核心功能

  1. PDF 文档加载与渲染

    • 支持本地文件上传
    • 支持拖拽上传
    • 支持通过 API 加载远程 PDF
  2. 对象编辑功能

    • 图片对象:添加、移动、缩放、删除
    • 文本对象:添加、编辑、格式化、删除
    • 绘图对象:手绘、移动、缩放、删除
  3. 页面管理

    • 缩略图预览
    • 页面添加与删除
    • 页面跳转与选择
  4. 视图控制

    • 缩放控制(30% - 300%)
    • 滚轮缩放(Shift + 滚轮)
    • 自适应缩放
  5. 导出功能

    • 下载编辑后的 PDF
    • 打印预览
    • 生成 PDF Blob 对象

基础使用示例

1. 全局注册组件

// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import PdfComs from '@szjy/pdf-coms'
import App from './App.vue'

const app = createApp(App)
app.use(ElementPlus)
app.use(PdfComs)
app.mount('#app')

2. 在组件中使用

<template>
  <sz-pdf-editor 
    ref="editorRef"
    :show-upload="true"
  >
    <!-- 可选:自定义头部右侧内容 -->
    <template #header-right>
      <el-button @click="handleCustomAction">自定义操作</el-button>
    </template>
  </sz-pdf-editor>
</template>

<script setup lang="ts">
import { ref } from 'vue'

const editorRef = ref(null)

function handleCustomAction() {
  console.log('自定义操作')
}
</script>

3. 通过 API 初始化 PDF

<template>
  <sz-pdf-editor ref="editorRef" :show-upload="false" />
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import axios from 'axios'

const editorRef = ref(null)

onMounted(async () => {
  try {
    // 从服务器获取 PDF 数据
    const response = await axios.get('/api/pdf/document.pdf', {
      responseType: 'arraybuffer'
    })
    
    // 初始化 PDF 数据
    await editorRef.value.initPdfData(response.data, 'document.pdf')
  } catch (error) {
    console.error('PDF 加载失败:', error)
  }
})
</script>

4. 获取编辑后的 PDF

<script setup lang="ts">
import { ref } from 'vue'

const editorRef = ref(null)

async function savePdfToServer() {
  try {
    // 获取编辑后的 PDF Blob
    const pdfBlob = await editorRef.value.getPdfBlob()
    
    // 上传到服务器
    const formData = new FormData()
    formData.append('file', pdfBlob, 'edited-document.pdf')
    
    await axios.post('/api/pdf/upload', formData)
    console.log('PDF 保存成功')
  } catch (error) {
    console.error('PDF 保存失败:', error)
  }
}
</script>

组件 Props

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | showUpload | boolean | true | 是否显示"选择 PDF"按钮 |

组件方法(通过 ref 调用)

| 方法 | 参数 | 返回值 | 说明 | |------|------|--------|------| | initPdfData | (data: File | ArrayBuffer | Uint8Array, filename?: string) | Promise<boolean> | 初始化 PDF 数据 | | getPdfBlob | - | Promise<Blob> | 获取编辑后的 PDF Blob 对象 |

组件插槽

| 插槽名 | 说明 | |--------|------| | header-right | 头部工具栏右侧自定义内容 |

核心流程图

flowchart TD
    A[用户上传 PDF] --> B[PDF 解析与渲染]
    B --> C[显示 PDF 页面]
    C --> D{用户操作}
    D -->|添加图片| E[图片对象管理]
    D -->|添加文本| F[文本对象管理]
    D -->|添加绘图| G[绘图对象管理]
    D -->|页面管理| H[添加/删除页面]
    E --> I[对象交互编辑]
    F --> I
    G --> I
    I --> J[实时预览]
    J --> K{保存操作}
    K -->|下载| L[生成 PDF 文件]
    K -->|预览| M[打开新窗口预览]
    K -->|获取 Blob| N[返回 PDF Blob]

数据流转图

sequenceDiagram
    participant User as 用户
    participant Editor as PdfEditor 组件
    participant Composable as usePDF/useObjects
    participant Utils as pdfOperations
    participant PDFLib as pdf-lib

    User->>Editor: 上传 PDF 文件
    Editor->>Composable: loadPDF(file)
    Composable->>Utils: readAsPDF(file)
    Utils-->>Composable: PDF 页面数组
    Composable-->>Editor: 渲染页面
    
    User->>Editor: 添加对象(图片/文本/绘图)
    Editor->>Composable: addObject(pageIndex, object)
    Composable-->>Editor: 更新对象列表
    
    User->>Editor: 保存 PDF
    Editor->>Composable: savePDF(file, objects)
    Composable->>Utils: generatePDFBytes(file, objects)
    Utils->>PDFLib: 嵌入对象到 PDF
    PDFLib-->>Utils: PDF 字节数据
    Utils-->>Composable: 下载文件

项目维护规范

代码风格

项目使用 TypeScript 和 Vue 3 Composition API,遵循以下规范:

命名规范

  • 组件名称: 使用 PascalCase(如 PdfEditor.vue
  • 文件名: 组件使用 PascalCase,工具函数使用 camelCase
  • 变量和函数: 使用 camelCase(如 loadPDF, pdfFile
  • 常量: 使用 UPPER_SNAKE_CASE(如 COMP_PREFIX
  • 类型定义: 使用 PascalCase(如 PDFObjectType

TypeScript 规范

// ✅ 推荐:明确的类型定义
interface Props {
  id: string
  x: number
  y: number
}

// ✅ 推荐:使用类型推断
const count = ref(0) // 自动推断为 Ref<number>

// ❌ 避免:使用 any 类型
const data: any = {} // 应该定义具体类型

Vue 组件规范

<script setup lang="ts">
// ✅ 推荐:使用 Composition API
import { ref, computed } from 'vue'

interface Props {
  title: string
}

const props = defineProps<Props>()
const emit = defineEmits<{
  (e: 'update', value: string): void
}>()
</script>

Git 工作流

分支命名规范

  • main - 主分支,保持稳定
  • develop - 开发分支
  • feature/xxx - 功能分支
  • bugfix/xxx - 修复分支
  • hotfix/xxx - 紧急修复分支

提交信息格式(Conventional Commits)

<type>(<scope>): <subject>

<body>

<footer>

Type 类型:

  • feat: 新功能
  • fix: 修复 bug
  • docs: 文档更新
  • style: 代码格式调整(不影响功能)
  • refactor: 代码重构
  • perf: 性能优化
  • test: 测试相关
  • chore: 构建工具或辅助工具的变动

示例:

feat(editor): 添加页面删除功能

- 实现页面删除逻辑
- 更新缩略图面板
- 添加删除确认提示

Closes #123

代码审查流程

  1. 创建 Pull Request

    • 确保代码通过 TypeScript 类型检查
    • 填写 PR 描述,说明改动内容
    • 关联相关 Issue
  2. 代码审查要点

    • 代码逻辑正确性
    • 类型定义完整性
    • 性能影响评估
    • 代码可读性和可维护性
  3. 合并要求

    • 至少一位审查者批准
    • 通过所有自动化检查
    • 解决所有审查意见

CI/CD 流程

graph LR
    A[代码提交] --> B[类型检查]
    B --> C[构建测试]
    C --> D{检查通过?}
    D -->|是| E[合并到主分支]
    D -->|否| F[修复问题]
    F --> A
    E --> G[自动发布]

版本发布流程

  1. 更新版本号和 CHANGELOG

    pnpm release
  2. 推送标签到远程仓库

    git push --follow-tags origin main
  3. 发布到 npm

    npm publish
  4. 同步到 cnpm

    pnpm sync

常见问题与故障排查(FAQ)

1. PDF 加载失败

问题描述: 上传 PDF 文件后无法正常显示

可能原因:

  • PDF 文件损坏或格式不正确
  • PDF 文件过大导致内存溢出
  • pdfjs-dist 版本不兼容

解决方案:

// 检查文件类型
if (file.type !== 'application/pdf') {
  console.error('不是有效的 PDF 文件')
}

// 检查文件大小(建议限制在 50MB 以内)
if (file.size > 50 * 1024 * 1024) {
  console.error('PDF 文件过大')
}

2. 中文字体显示异常

问题描述: 添加中文文本后显示为方块或乱码

可能原因:

  • 字体文件未正确加载
  • 字体路径配置错误
  • 浏览器不支持该字体

解决方案:

// 确保使用支持中文的字体
const fontFamily = '微软雅黑' // 或 'SimSun', 'SimHei'

// 预加载字体
import { loadFont } from '@/utils/assetLoader'
await loadFont(fontFamily)

最佳实践:

  • 优先使用微软雅黑字体
  • public/fonts/ 目录下放置字体文件
  • 确保字体文件路径正确配置

3. 对象拖拽不流畅

问题描述: 拖拽图片或文本对象时出现卡顿

可能原因:

  • PDF 页面缩放比例过大
  • 对象数量过多
  • 浏览器性能限制

解决方案:

// 优化渲染性能
const renderScale = computed(() => {
  // 根据视图缩放调整渲染质量
  return Math.max(1, Math.min(viewScale.value, 2))
})

// 限制对象数量
const MAX_OBJECTS_PER_PAGE = 50

4. 保存 PDF 时报错

问题描述: 点击下载按钮后提示"Failed to save PDF"

可能原因:

  • 字体嵌入失败
  • 图片格式不支持
  • 内存不足

解决方案:

// 捕获详细错误信息
try {
  await savePDF(pdfFile, objects, fileName, pagesScale)
} catch (error) {
  console.error('保存失败详情:', error)
  
  // 检查是否是字体问题
  if (error.message.includes('font')) {
    console.error('字体嵌入失败,请检查字体配置')
  }
}

5. 移动端触摸事件不响应

问题描述: 在移动设备上无法拖拽或编辑对象

可能原因:

  • 触摸事件未正确绑定
  • CSS touch-action 属性设置不当

解决方案:

<style scoped>
.objects-layer {
  touch-action: none; /* 禁用浏览器默认触摸行为 */
}
</style>

6. 打印预览窗口被拦截

问题描述: 点击打印预览按钮后没有反应

可能原因:

  • 浏览器拦截了弹窗
  • 用户未授权弹窗权限

解决方案:

const previewWindow = window.open(url, '_blank')

if (!previewWindow) {
  ElMessage.warning('请允许浏览器弹窗,以便预览 PDF')
  // 提供备用方案:直接下载
  download(pdfBytes, fileName, 'application/pdf')
}

7. TypeScript 类型错误

问题描述: 编译时出现类型错误

解决方案:

# 清理缓存并重新安装依赖
rm -rf node_modules pnpm-lock.yaml
pnpm install

# 重新生成类型声明文件
pnpm build

性能优化建议

  1. PDF 文件优化

    • 压缩 PDF 文件大小
    • 限制单个文件不超过 50MB
    • 避免加载过多页面的 PDF
  2. 渲染优化

    • 使用虚拟滚动加载页面
    • 按需渲染可见区域
    • 降低非活动页面的渲染质量
  3. 内存管理

    • 及时释放不再使用的对象
    • 避免创建过多的临时变量
    • 使用 WeakMap 管理大对象引用

参考资料与延伸阅读

  1. Vue 3 官方文档
    https://cn.vuejs.org/
    Vue 3 核心概念、Composition API 和最佳实践

  2. PDF.js 文档
    https://mozilla.github.io/pdf.js/
    Mozilla 开源的 PDF 渲染引擎,本项目用于 PDF 页面渲染

  3. pdf-lib 文档
    https://pdf-lib.js.org/
    JavaScript PDF 操作库,用于创建和修改 PDF 文档

  4. Element Plus 组件库
    https://element-plus.org/zh-CN/
    基于 Vue 3 的 UI 组件库,本项目使用的 UI 框架

  5. TypeScript 官方文档
    https://www.typescriptlang.org/docs/
    TypeScript 类型系统和高级特性

  6. Vite 构建工具文档
    https://cn.vitejs.dev/
    下一代前端构建工具,本项目使用的构建工具

  7. Canvas API 教程
    https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API
    用于图片渲染和绘图功能的 Canvas API 详解

  8. Web 字体加载最佳实践
    https://web.dev/font-best-practices/
    字体加载优化和中文字体处理方案


许可证

本项目采用 MIT 许可证。详见 LICENSE 文件。

贡献指南

欢迎提交 Issue 和 Pull Request!在提交 PR 之前,请确保:

  1. 代码通过 TypeScript 类型检查
  2. 遵循项目代码规范
  3. 提交信息符合 Conventional Commits 规范
  4. 更新相关文档

联系方式

如有问题或建议,请通过以下方式联系:


版本: 0.1.1
最后更新: 2025-10-27