@koi-br/ocr-web-sdk
v1.0.21
Published
一个支持多种Office文件格式预览的Vue3组件SDK,包括PDF、Word、Excel、图片、OFD、TIF等格式
Readme
@koi-br/ocr-web-sdk
一个功能强大的 Vue3 文件预览组件 SDK,支持多种 Office 文件格式和图片格式的在线预览,包括 PDF、Word、Excel、图片、OFD、TIF 等格式。
✨ 功能特性
📄 PDF 预览
- ✅ 完整的 PDF 文档渲染和浏览
- ✅ 目录导航和印章列表(支持侧边栏切换)
- ✅ 多种缩放模式(适应宽度、适应高度、实际大小、适应页面)
- ✅ 缩放控制(放大、缩小、重置)
- ✅ 全屏预览
- ✅ 文本选择和复制
- ✅ 页面跳转和定位
- ✅ 支持外部调用跳转方法
- ✅ 支持跳转事件监听
- ✅ PDF 分块数据支持(blocksData)
📊 Excel 预览
- ✅ XLSX 格式完整支持
- ✅ 缩放控制(0.5x - 2x)
- ✅ 下载功能(可选)
📝 Word 预览
- ✅ DOCX 格式完整支持
- ✅ 文档样式渲染
- ✅ 下载功能(可选)
🖼️ 图片预览
- ✅ 支持 JPG、PNG、GIF、BMP、WEBP、SVG、APNG、AVIF 等格式
- ✅ 缩放控制(可配置范围)
- ✅ 图片旋转(左右旋转)
- ✅ 拖拽平移
- ✅ 滚轮缩放
- ✅ 查看原图功能
- ✅ 下载功能(可选)
📑 OFD 预览
- ✅ OFD 格式文件预览
- ✅ 下载功能(可选)
🖨️ TIF 预览
- ✅ TIF/TIFF 多页图片支持
- ✅ 缩放控制
- ✅ 图片旋转
- ✅ 拖拽平移
- ✅ 查看原图功能
- ✅ 下载功能(可选)
📦 安装
npm install @koi-br/ocr-web-sdk
# 或
yarn add @koi-br/ocr-web-sdk
# 或
pnpm add @koi-br/ocr-web-sdk🔧 依赖要求
必需依赖
- Vue 3.x - Vue 框架(peer dependency)
- @arco-design/web-vue - Arco Design UI 组件库
内部依赖(已包含)
pdfjs-dist- PDF 渲染引擎@vue-office/excel- Excel 预览组件docx-preview- Word 文档预览bestofdview- OFD 文件预览lucide-vue-next- 图标库
🚀 快速开始
✨ 样式自动加载:SDK 会自动加载样式,无需手动导入样式文件!
方式一:使用 FilePreview 组件(推荐)
FilePreview 是一个统一的文件预览入口组件,会根据文件类型自动选择合适的预览组件。
<template>
<div>
<FilePreview
ref="previewRef"
:is-download="true"
:pdf-props="{
showTocSidebar: true,
blocksData: blocksData
}"
:image-props="{
minScale: 0.1,
maxScale: 5,
clickStep: 0.25
}"
/>
<button @click="previewFile">预览文件</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { FilePreview } from '@koi-br/ocr-web-sdk';
const previewRef = ref(null);
const blocksData = ref([]); // PDF 分块数据
// 预览文件 URL
const previewFile = () => {
previewRef.value.preview('https://example.com/file.pdf', 'file.pdf');
};
// 预览 Blob 对象
const previewBlob = async () => {
const response = await fetch('https://example.com/file.xlsx');
const blob = await response.blob();
previewRef.value.preview(blob, 'file.xlsx');
};
// 预览 File 对象(上传的文件)
const handleFileUpload = (event) => {
const file = event.target.files[0];
if (file) {
previewRef.value.preview(file, file.name);
}
};
// 带选项的预览
const previewWithOptions = () => {
previewRef.value.preview('https://example.com/image.jpg', 'image.jpg', {
onProgress: (progress) => {
console.log('下载进度:', progress);
},
originalId: 'original-image-id'
});
};
// 清除预览
const clearPreview = () => {
previewRef.value.clearPreview();
};
</script>方式二:使用单个预览组件
如果需要更精细的控制,可以直接使用对应的预览组件。
<template>
<!-- PDF 预览 -->
<PdfPreview
ref="pdfRef"
:pdf-url="pdfUrl"
:blocks-data="blocksData"
:show-toc-sidebar="true"
@pdf-loaded="handlePdfLoaded"
@page-jump="handlePageJump"
@position-jump="handlePositionJump"
/>
<!-- 图片预览 -->
<ImagePreview
:url="imageUrl"
:min-scale="0.1"
:max-scale="5"
:original-id="originalId"
:is-download="true"
@original="handleOriginal"
@download="handleDownload"
/>
<!-- Excel 预览 -->
<XlsxPreview
:url="excelUrl"
:is-download="true"
@download="handleDownload"
/>
<!-- Word 预览 -->
<DocxPreview
:url="wordUrl"
:is-download="true"
@download="handleDownload"
/>
<!-- OFD 预览 -->
<OfdPreview
:url="ofdUrl"
:is-download="true"
@download="handleDownload"
/>
<!-- TIF 预览 -->
<TifPreview
:url="tifUrl"
:min-scale="0.1"
:max-scale="5"
:original-id="originalId"
:is-download="true"
@original="handleOriginal"
@download="handleDownload"
/>
</template>
<script setup>
import {
PdfPreview,
ImagePreview,
XlsxPreview,
DocxPreview,
OfdPreview,
TifPreview
} from '@koi-br/ocr-web-sdk';
const pdfUrl = ref('https://example.com/file.pdf');
const imageUrl = ref('https://example.com/image.jpg');
// ... 其他 URL
const handlePdfLoaded = () => {
console.log('PDF 加载完成');
};
const handlePageJump = (pageNum) => {
console.log('跳转到第', pageNum, '页');
};
const handlePositionJump = (pageNum, bbox, type) => {
const typeName = type === 'seal' ? '印章' : '文本块';
console.log(`跳转到${typeName}:`, pageNum, bbox);
};
const handleOriginal = () => {
console.log('查看原图');
};
const handleDownload = () => {
console.log('下载文件');
};
</script>📚 API 文档
FilePreview 组件
统一的文件预览入口组件,自动根据文件类型选择合适的预览组件。
Props
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| isDownload | boolean | false | 是否显示下载按钮(会传递给所有子组件) |
| pdfProps | object | {} | 传递给 PDF 预览组件的 props(见 PdfPreview Props) |
| imageProps | object | {} | 传递给图片预览组件的 props(见 ImagePreview Props) |
| tifProps | object | {} | 传递给 TIF 预览组件的 props(见 TifPreview Props) |
| docxProps | object | {} | 传递给 Word 预览组件的 props(见 DocxPreview Props) |
| ofdProps | object | {} | 传递给 OFD 预览组件的 props(见 OfdPreview Props) |
| xlsxProps | object | {} | 传递给 Excel 预览组件的 props(见 XlsxPreview Props) |
注意: isDownload 会单独传递给子组件,不会包含在对应的 *Props 对象中。如果需要为不同文件类型设置不同的下载按钮显示状态,可以在对应的 *Props 中设置 isDownload(优先级更高)。
Methods
preview(file, fileName?, options?)
预览文件方法。
参数:
file(string | Blob | File) - 文件 URL、Blob 对象或 File 对象fileName(string, 可选) - 文件名,用于判断文件类型。如果不提供,会尝试从 URL 或 File 对象中获取options(object, 可选) - 配置选项onProgress(Function) - 下载进度回调函数,参数为进度百分比(progress: number) => voidoriginalId(string) - 原图 ID(用于图片预览)
示例:
// 预览 URL
previewRef.value.preview('https://example.com/file.pdf', 'file.pdf');
// 预览 Blob
previewRef.value.preview(blob, 'file.xlsx');
// 预览 File 对象
previewRef.value.preview(file, file.name);
// 带选项
previewRef.value.preview(url, 'file.pdf', {
onProgress: (progress) => {
console.log('下载进度:', progress);
},
originalId: 'original-image-id'
});clearPreview()
清除当前预览,释放资源。
示例:
previewRef.value.clearPreview();向子组件传递 Props
FilePreview 支持通过 *Props 属性向对应的子组件传递配置。例如,向 PDF 预览组件传递 blocksData 和 showTocSidebar:
示例:
<template>
<FilePreview
ref="previewRef"
:is-download="true"
:pdf-props="{
showTocSidebar: true,
blocksData: pdfBlocksData
}"
:image-props="{
minScale: 0.1,
maxScale: 5,
clickStep: 0.25,
wheelStep: 0.1
}"
:docx-props="{
docName: '我的文档',
minScale: 0.1,
maxScale: 3
}"
/>
</template>
<script setup>
import { ref } from 'vue';
import { FilePreview } from '@koi-br/ocr-web-sdk';
const previewRef = ref(null);
const pdfBlocksData = ref([
{
blockLabel: '标题',
blockContent: '第一章',
blockBbox: [100, 100, 200, 150],
blockPage: 1
}
]);
// 预览文件
previewRef.value.preview('https://example.com/file.pdf', 'file.pdf');
</script>各子组件支持的 Props:
- PDF (
pdfProps):showTocSidebar,blocksData(详见 PdfPreview Props) - 图片 (
imageProps):minScale,maxScale,clickStep,wheelStep,originalId(详见 ImagePreview Props) - TIF (
tifProps):minScale,maxScale,clickStep,wheelStep,originalId(详见 TifPreview Props) - Word (
docxProps):docName,docData,minScale,maxScale,clickStep,wheelStep(详见 DocxPreview Props) - OFD (
ofdProps): 无额外 props(详见 OfdPreview Props) - Excel (
xlsxProps): 无额外 props(详见 XlsxPreview Props)
注意: isDownload 会单独传递给所有子组件。如果需要在 *Props 中覆盖 isDownload,子组件会优先使用 *Props 中的值。
PdfPreview 组件
PDF 文档预览组件,功能最丰富。
Props
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| pdfUrl | string | - | PDF 文件 URL(必需) |
| blocksData | Array<BlockInfo> | - | PDF 分块数据(从后端 layout-parsing 接口获取),用于目录和印章列表 |
| showTocSidebar | boolean | true | 是否显示目录侧边栏(包括工具栏中的切换按钮) |
| isDownload | boolean | false | 是否显示下载按钮 |
BlockInfo 类型定义:
interface BlockInfo {
blockLabel: string; // 块标签
blockContent: string; // 块内容
blockBbox: [number, number, number, number]; // 块的边界框 [x1, y1, x2, y2]
blockPage: number; // 块所属的页码(从1开始)
}Events
| 事件名 | 参数 | 说明 |
|--------|------|------|
| pdf-loaded | - | PDF 加载并渲染完成时触发 |
| page-jump | pageNum: number | 页面跳转时触发,传递目标页码 |
| position-jump | pageNum: number, bbox: [number, number, number, number], type: "block" \| "seal" | 位置跳转时触发,传递页码、边界框和类型(自动检测,block 文本块 或 seal 印章) |
| download | - | 点击下载按钮时触发 |
Methods(通过 ref 调用)
| 方法名 | 参数 | 返回值 | 说明 |
|--------|------|--------|------|
| goToPage | pageNum: number | - | 跳转到指定页码(从1开始) |
| jumpToPosition | pageNum: number, bbox: [number, number, number, number], emitEvent?: boolean | - | 跳转到指定位置并高亮(统一接口,自动识别类型,无需传入类型参数) |
| getCurrentPage | - | number | 获取当前页码 |
| getTotalPages | - | number | 获取总页数 |
| reset | - | - | 重置预览状态 |
| cleanup | - | - | 清理资源 |
示例:
<template>
<PdfPreview
ref="pdfRef"
:pdf-url="pdfUrl"
:blocks-data="blocksData"
:show-toc-sidebar="true"
@pdf-loaded="handlePdfLoaded"
@page-jump="handlePageJump"
@position-jump="handlePositionJump"
/>
<div>
<button @click="jumpToPage(5)">跳转到第5页</button>
<button @click="jumpToBlock">跳转到文本块</button>
<button @click="jumpToSeal">跳转到印章</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { PdfPreview } from '@koi-br/ocr-web-sdk';
const pdfRef = ref(null);
const handlePdfLoaded = () => {
console.log('PDF 加载完成');
};
const handlePageJump = (pageNum) => {
console.log('跳转到第', pageNum, '页');
};
// 统一的位置跳转事件处理(类型会自动检测)
const handlePositionJump = (pageNum, bbox, type) => {
const typeName = type === 'seal' ? '印章' : '文本块';
console.log(`跳转到${typeName}:`, pageNum, bbox);
};
// 跳转到指定页面
const jumpToPage = (pageNum) => {
pdfRef.value?.goToPage(pageNum);
};
// 跳转到指定位置(自动识别是文本块还是印章)
const jumpToBlock = () => {
// bbox 格式: [x1, y1, x2, y2] - PDF 坐标系的边界框
// 无需指定类型,系统会根据坐标自动匹配
const pageNum = 3;
const bbox = [100, 200, 300, 400];
pdfRef.value?.jumpToPosition(pageNum, bbox);
};
// 跳转到印章位置(同样无需指定类型)
const jumpToSeal = () => {
const pageNum = 2;
const bbox = [150, 250, 250, 350];
// 系统会自动识别这是印章还是文本块
pdfRef.value?.jumpToPosition(pageNum, bbox);
};
// 获取当前页码
const getCurrentPage = () => {
const currentPage = pdfRef.value?.getCurrentPage();
console.log('当前页码:', currentPage);
};
// 获取总页数
const getTotalPages = () => {
const totalPages = pdfRef.value?.getTotalPages();
console.log('总页数:', totalPages);
};
</script>ImagePreview 组件
图片预览组件,支持缩放、旋转、拖拽等功能。
Props
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| url | string | - | 图片 URL(必需) |
| minScale | number | 0.1 | 最小缩放比例 |
| maxScale | number | 5 | 最大缩放比例 |
| clickStep | number | 0.25 | 点击缩放按钮的步长 |
| wheelStep | number | 0.1 | 滚轮缩放的步长 |
| originalId | string | '' | 原图 ID,用于查看原图功能 |
| isDownload | boolean | false | 是否显示下载按钮 |
Events
| 事件名 | 参数 | 说明 |
|--------|------|------|
| original | - | 点击"查看原图"按钮时触发 |
| download | - | 点击"下载"按钮时触发 |
Methods(通过 ref 调用)
| 方法名 | 参数 | 返回值 | 说明 |
|--------|------|--------|------|
| reset | - | - | 重置图片状态(缩放、旋转、位置) |
示例:
<ImagePreview
ref="imageRef"
:url="imageUrl"
:min-scale="0.1"
:max-scale="5"
:original-id="originalId"
:is-download="true"
@original="handleOriginal"
@download="handleDownload"
/>XlsxPreview 组件
Excel 文件预览组件。
Props
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| url | string | - | Excel 文件 URL(必需) |
| isDownload | boolean | false | 是否显示下载按钮 |
Events
| 事件名 | 参数 | 说明 |
|--------|------|------|
| download | - | 点击"下载"按钮时触发 |
Methods(通过 ref 调用)
| 方法名 | 参数 | 返回值 | 说明 |
|--------|------|--------|------|
| cleanup | - | - | 清理资源 |
示例:
<XlsxPreview
ref="excelRef"
:url="excelUrl"
:is-download="true"
@download="handleDownload"
/>DocxPreview 组件
Word 文档预览组件。
Props
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| url | string | - | Word 文档 URL(必需) |
| docName | string | '文档预览' | 文档名称 |
| docData | Blob \| ArrayBuffer | null | 直接传入文档数据(优先级高于 url) |
| minScale | number | 0.1 | 最小缩放比例 |
| maxScale | number | 3 | 最大缩放比例 |
| clickStep | number | 0.25 | 点击缩放按钮的步长 |
| wheelStep | number | 0.1 | 滚轮缩放的步长 |
| isDownload | boolean | false | 是否显示下载按钮 |
Events
| 事件名 | 参数 | 说明 |
|--------|------|------|
| download | - | 点击"下载"按钮时触发 |
Methods(通过 ref 调用)
| 方法名 | 参数 | 返回值 | 说明 |
|--------|------|--------|------|
| reset | - | - | 重置文档状态 |
| zoom | delta: number, isWheel?: boolean | - | 缩放文档 |
| rotate | delta: number | - | 旋转文档 |
示例:
<DocxPreview
ref="wordRef"
:url="wordUrl"
:is-download="true"
@download="handleDownload"
/>OfdPreview 组件
OFD 文件预览组件。
Props
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| url | string | - | OFD 文件 URL(必需) |
| isDownload | boolean | false | 是否显示下载按钮 |
Events
| 事件名 | 参数 | 说明 |
|--------|------|------|
| download | - | 点击"下载"按钮时触发 |
Methods(通过 ref 调用)
| 方法名 | 参数 | 返回值 | 说明 |
|--------|------|--------|------|
| cleanup | - | - | 清理资源 |
示例:
<OfdPreview
ref="ofdRef"
:url="ofdUrl"
:is-download="true"
@download="handleDownload"
/>TifPreview 组件
TIF/TIFF 图片预览组件,支持多页 TIF 文件。
✨ 自动加载: SDK 会自动通过 npm 依赖加载 TIFF 库,无需手动引入。
Props
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| url | string | - | TIF 文件 URL(必需) |
| minScale | number | 0.1 | 最小缩放比例 |
| maxScale | number | 5 | 最大缩放比例 |
| clickStep | number | 0.25 | 点击缩放按钮的步长 |
| wheelStep | number | 0.1 | 滚轮缩放的步长 |
| originalId | string | '' | 原图 ID,用于查看原图功能 |
| isDownload | boolean | false | 是否显示下载按钮 |
Events
| 事件名 | 参数 | 说明 |
|--------|------|------|
| original | - | 点击"查看原图"按钮时触发 |
| download | - | 点击"下载"按钮时触发 |
| load | - | TIF 文件加载完成时触发 |
| error | error: Error | TIF 文件加载失败时触发 |
Methods(通过 ref 调用)
| 方法名 | 参数 | 返回值 | 说明 |
|--------|------|--------|------|
| cleanup | - | - | 清理资源 |
示例:
<TifPreview
ref="tifRef"
:url="tifUrl"
:min-scale="0.1"
:max-scale="5"
:original-id="originalId"
:is-download="true"
@original="handleOriginal"
@download="handleDownload"
@load="handleLoad"
@error="handleError"
/>📋 支持的文件格式
| 格式 | 扩展名 | 预览组件 |
|------|--------|----------|
| PDF | .pdf | PdfPreview |
| Excel | .xlsx | XlsxPreview |
| Word | .docx | DocxPreview |
| 图片 | .jpg, .jpeg, .png, .gif, .bmp, .webp, .svg, .apng, .avif | ImagePreview |
| OFD | .ofd | OfdPreview |
| TIF | .tif, .tiff | TifPreview |
🛠️ 开发
本地开发
# 克隆项目
git clone <repository-url>
# 安装依赖
npm install
# 启动开发服务器
npm run dev
# 构建生产版本
npm run build
# 预览构建结果
npm run preview项目结构
@koi-br/ocr-web-sdk/
├── Preview/ # 预览组件目录
│ ├── index.vue # FilePreview 主组件
│ ├── PdfPreview.vue # PDF 预览组件
│ ├── ImagePreview.vue # 图片预览组件
│ ├── xlsxPreview.vue # Excel 预览组件
│ ├── docxPreview.vue # Word 预览组件
│ ├── ofdPreview.vue # OFD 预览组件
│ └── tifPreview.vue # TIF 预览组件
├── src/ # 源码目录
│ ├── index.ts # 入口文件
│ └── styles/ # 样式文件
├── demo/ # 示例项目
└── package.json # 项目配置💡 使用技巧
1. 文件类型判断
FilePreview 组件会根据文件扩展名自动判断文件类型。如果文件名没有扩展名,可以手动指定:
// 手动指定文件类型
previewRef.value.preview(blob, 'document.pdf');2. 预览 Blob 对象
当从 API 获取文件数据时,可以转换为 Blob 对象进行预览:
const response = await fetch('https://api.example.com/file');
const blob = await response.blob();
previewRef.value.preview(blob, 'file.pdf');3. 处理文件上传
结合文件上传组件使用:
<template>
<input type="file" @change="handleFileChange" />
<FilePreview ref="previewRef" />
</template>
<script setup>
const handleFileChange = (event) => {
const file = event.target.files[0];
if (file) {
previewRef.value.preview(file, file.name);
}
};
</script>4. PDF 分块数据使用
如果后端提供了 PDF 分块数据(blocksData),可以传递给 PdfPreview 组件以启用目录和印章列表功能:
<PdfPreview
:pdf-url="pdfUrl"
:blocks-data="blocksData"
/>5. PDF 位置跳转
通过坐标自动匹配文本块或印章,无需指定类型:
// 自动识别类型(推荐)
pdfRef.value?.jumpToPosition(pageNum, bbox);6. 资源清理
组件会在卸载时自动清理资源,但也可以手动调用清理方法:
// 切换文件时,先清除旧预览
previewRef.value.clearPreview();
// 然后加载新文件
previewRef.value.preview(newFileUrl, 'new-file.pdf');⚠️ 注意事项
样式自动加载:SDK 会自动加载样式,无需手动导入样式文件。样式已内联到 JS 文件中,导入组件后样式会自动生效。
Vue 版本要求:本项目需要 Vue 3.x,不支持 Vue 2.x
UI 组件库:需要安装
@arco-design/web-vue作为依赖文件大小:大文件预览可能会影响性能,建议对文件大小进行限制
跨域问题:预览跨域文件时,需要确保服务器配置了正确的 CORS 头
PDF 渲染:PDF 预览使用 pdfjs-dist,首次加载可能需要下载 worker 文件
TIF 格式:TIF 预览支持多页,但需要浏览器支持相应的解码器
📄 许可证
MIT
🤝 贡献
欢迎提交 Issue 和 Pull Request!
