# pdfViewer
**Repository Path**: 694243440/pdf-viewer
## Basic Information
- **Project Name**: pdfViewer
- **Description**: 基于 pdf.js 开发的 pdf 文件预览工具
- **Primary Language**: JavaScript
- **License**: MPL-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 11
- **Forks**: 9
- **Created**: 2024-12-19
- **Last Updated**: 2026-08-26
## Categories & Tags
**Categories**: Uncategorized
**Tags**: pdf, pdfjs
## README
# Paperline PDF 查看器
一个基于 Web 的 PDF 阅读与批注工具,零构建、原生 ES 模块、内置同源代理与跨域支持。适合本地预览、在线文档浏览,以及需要手写批阅的场景。
## 功能特性
### 阅读与导航
- **连续滚动浏览**:按页流式渲染,支持上下翻页与平滑滚动定位。
- **页码指示**:右上角实时显示当前页 / 总页数。
- **跳转**:支持跳转到首页、尾页,或直接输入页号定位。
- **缩放**:一键切换「适合页宽」与「适合页面」两种视图模式。
### 阅读舒适度
- **护眼模式**:提供 8 种阅读背景色(银河白、杏仁黄、秋叶褐、胭脂红、青草绿、海天蓝、葛巾紫、极光灰),可按环境光线选择。
### 手写批阅
- **签批工具**:支持笔触(手写笔/鼠标)与手触(触摸屏)两种输入模式。
- **橡皮擦**:带跟随光圈的橡皮擦工具,可擦除指定批注。
- **保存**:批注完成后可导出带有签批的 PDF 文件,通过浏览器下载。
### 文档来源
- **本地文件**:直接选择设备中的 PDF 文件预览。
- **在线地址**:输入同源路径或在线 PDF 地址。
- **跨域代理**:在线地址受 CORS 限制时,自动走内置 `/api/pdf-proxy` 同源代理加载。
## 快速开始
### 在线体验
测试地址:
### 环境要求
- Node.js 18+(内置测试与原生 ES 模块需要)。
- 现代浏览器(Chrome、Firefox、Safari、Edge 最新版)。
### 安装与运行
```bash
# 安装依赖(当前为纯静态项目,无运行时依赖)
npm install
# 启动服务
npm start
```
默认地址:`http://127.0.0.1:4173`
启动后会在浏览器打开查看器,默认加载项目根目录的 `test.pdf` 用于演示。
### 自定义端口
通过环境变量 `PDF_VIEWER_PORT` 指定端口:
```bash
PDF_VIEWER_PORT=8080 npm start
```
### 打开指定 PDF
在地址栏通过 `?file=` 参数指定 PDF 路径:
```
http://127.0.0.1:4173/?file=./your-document.pdf
```
## 使用说明
### 工具栏功能(从左到右)
| 按钮 | 功能 |
|---|---|
| 缩放 | 切换「适合页宽」/「适合页面」 |
| 护眼 | 选择阅读背景色 |
| 上一页 / 下一页 | 翻页(首尾页时自动禁用) |
| 跳转到 | 跳至首页、尾页或指定页号 |
| 手写批阅 | 开启/关闭批注层,展开笔触/手触/橡皮擦工具 |
| 保存批阅 | 导出带批注的 PDF(无批注时禁用) |
### 上传与在线 PDF
- 点击右上角「打开 PDF」可直接选择本地 PDF 文件预览。
- 也可粘贴同源路径或在线 PDF 地址。查看器会先直接加载;若在线地址未配置 CORS,则自动改走同源代理 `/api/pdf-proxy`。
- `npm start` 已内置该代理。若部署到已有后端,请实现兼容的 `GET /api/pdf-proxy?url=` 接口,或让 PDF 源站返回允许当前站点访问的 CORS 响应头。
- 代理会请求用户输入的远程地址;生产环境应在网关或后端按业务需求限制可访问的域名。
## 项目结构
```
.
├── index.html # 应用入口与页面结构
├── server.mjs # 内置开发服务(静态托管 + PDF 代理 + CORS)
├── package.json # 脚本配置
├── test.pdf # 演示文档
├── static/
│ ├── css/
│ │ └── style.css # 全部样式(含响应式)
│ ├── js/
│ │ ├── app.js # UI 事件绑定与启动入口
│ │ ├── viewer.js # 查看器门面(Facade),协调各子模块
│ │ └── viewer/
│ │ ├── page-renderer.js # 页面渲染、缓存、滚动与布局
│ │ ├── annotation-manager.js # 手写签批层(SignaturePad)
│ │ ├── pdf-document-loader.js # PDF.js 加载与跨域代理回退
│ │ ├── dialog-manager.js # 对话框与遮罩状态管理
│ │ └── utils.js # 通用工具函数
│ ├── icon/ # 工具栏与签批图标
│ ├── image/、md_file/ # 静态素材
│ └── plugin/ # 第三方库
│ ├── pdfjs/ # PDF.js 渲染引擎(含 worker 与 cmaps)
│ ├── signature_pad/ # 手写签名库
│ └── uniapp/ # UniApp WebView 通信桥
└── tests/ # 单元测试(node:test)
```
### 模块职责
- **`viewer.js`**:对外门面,组合渲染、批注、对话框三个子系统,暴露 `loadSource`、`skipPage`、`setPageZoom`、`setAnnotationEnabled`、`savePdfFile` 等方法。
- **`page-renderer.js`**:管理页面元数据、DOM 占位、渲染任务队列、IntersectionObserver 可见性跟踪,以及基于距离的缓存淘汰。
- **`annotation-manager.js`**:基于 SignaturePad 的可恢复批注层,按页持久化数据,页面被淘汰后批注不丢失。
- **`pdf-document-loader.js`**:封装 PDF.js worker 配置与加载任务,跨域失败时自动回退到同源代理。
- **`dialog-manager.js`**:统一管理对话框打开/关闭、遮罩点击与焦点,保证重复打开时状态一致。
## 开发
### 命令
```bash
npm run check # 语法检查(app.js / viewer.js / server.mjs)
npm test # 运行单元测试
npm start # 启动开发服务
```
### 技术栈
- 原生 ES 模块,无打包构建步骤。
- [PDF.js](https://mozilla.github.io/pdf.js/) 负责 PDF 解析与渲染。
- [Signature Pad](https://github.com/szimek/signature_pad) 负责手写笔迹采集。
- [UniApp WebView](https://uniapp.dcloud.io/) 通信桥用于宿主集成。
## 许可证
MIT,详见 [LICENSE](./LICENSE)。
## 致谢
- [PDF.js](https://mozilla.github.io/pdf.js/) — Mozilla 开发的 PDF 渲染引擎。
- [Signature Pad](https://github.com/szimek/signature_pad) — 用于手写签名的 JavaScript 库。