@mxmweb/fviewer 1.5.5 → 1.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -506
- package/index.js +4 -3
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/stats.html +1 -1
- package/examples/CoreReader/index.d.ts +0 -1
package/README.md
CHANGED
|
@@ -1,591 +1,240 @@
|
|
|
1
1
|
# @mxmweb/fviewer
|
|
2
2
|
|
|
3
|
-
一个功能强大的文件查看器库,支持多种文件格式的解析和显示,包括PDF、图片、文本、Markdown
|
|
3
|
+
> 一个功能强大的文件查看器库,支持多种文件格式的解析和显示,包括PDF、图片、文本、Markdown等格式
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@mxmweb/fviewer)
|
|
6
|
+
[](https://www.npmjs.com/package/@mxmweb/fviewer)
|
|
7
|
+
[](https://github.com/your-org/fviewer/blob/main/LICENSE)
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
## ✨ 核心特性
|
|
10
|
+
|
|
11
|
+
- ✅ **多格式支持**:支持 PDF、图片、文本、Markdown、HTML 等多种文件格式
|
|
12
|
+
- ✅ **智能文件解析**:自动检测文件类型并调用相应的解析器
|
|
13
|
+
- ✅ **完整的标注功能**:支持 PDF、Markdown、表格等多种标注类型
|
|
14
|
+
- ✅ **动态主题系统**:支持运行时主题切换,所有样式可配置
|
|
15
|
+
- ✅ **事件驱动架构**:通过 eventsEmit 统一处理所有交互事件
|
|
16
|
+
- ✅ **TypeScript 支持**:完整的类型定义,提供良好的开发体验
|
|
17
|
+
- ✅ **自定义组件**:支持自定义加载和错误组件
|
|
18
|
+
|
|
19
|
+
## 📦 安装
|
|
8
20
|
|
|
9
21
|
```bash
|
|
10
22
|
# 使用 pnpm(推荐)
|
|
11
|
-
pnpm add @mxmweb/fviewer
|
|
12
|
-
react react-dom \
|
|
13
|
-
styled-components @mxmweb/zui @mxmweb/rtext \
|
|
14
|
-
pdfjs-dist
|
|
15
|
-
|
|
16
|
-
# 或 yarn
|
|
17
|
-
yarn add @mxmweb/fviewer \
|
|
18
|
-
react react-dom \
|
|
19
|
-
styled-components @mxmweb/zui @mxmweb/rtext \
|
|
20
|
-
pdfjs-dist
|
|
21
|
-
|
|
22
|
-
# 或 npm
|
|
23
|
-
npm i @mxmweb/fviewer \
|
|
24
|
-
react react-dom \
|
|
25
|
-
styled-components @mxmweb/zui @mxmweb/rtext \
|
|
26
|
-
pdfjs-dist
|
|
27
|
-
```
|
|
23
|
+
pnpm add @mxmweb/fviewer react react-dom styled-components @mxmweb/zui @mxmweb/rtext pdfjs-dist
|
|
28
24
|
|
|
29
|
-
|
|
25
|
+
# 使用 npm
|
|
26
|
+
npm install @mxmweb/fviewer react react-dom styled-components @mxmweb/zui @mxmweb/rtext pdfjs-dist
|
|
30
27
|
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
# 使用 yarn
|
|
29
|
+
yarn add @mxmweb/fviewer react react-dom styled-components @mxmweb/zui @mxmweb/rtext pdfjs-dist
|
|
30
|
+
```
|
|
33
31
|
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
### 必需依赖
|
|
33
|
+
|
|
34
|
+
本库需要以下 peerDependencies:
|
|
36
35
|
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add react@>=18 react-dom@>=18 styled-components@^6.1.19 @mxmweb/zui@^1.* @mxmweb/rtext@^1.* pdfjs-dist@2.16.105
|
|
39
38
|
```
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
### PDF Worker 注册
|
|
42
41
|
|
|
43
|
-
|
|
42
|
+
PDF.js 的 worker 需由宿主自行注册一次(任意应用初始化位置):
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
```typescript
|
|
45
|
+
import { registerPDFWorker } from '@mxmweb/fviewer';
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
// 注册PDF Worker
|
|
48
|
+
registerPDFWorker('/worker/pdf.worker.min.js');
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- **fileName**: `string` - 文件名(可选)
|
|
54
|
-
- **token**: `string` - 认证令牌(可选)
|
|
55
|
-
- **initialPage**: `number` - 初始页码(可选)
|
|
56
|
-
- **annotations**: `(Annotation | MDAnnotation | TableAnnotation)[]` - 标注数据数组(可选)
|
|
57
|
-
- **data**: `any` - 直接数据传递(可选)
|
|
58
|
-
- **eventsEmit**: `(name: string, data?: any, innerFn?: any) => void` - 事件回调函数(可选)
|
|
59
|
-
- **styles**: `{ theme?: AppTheme; mode?: 'light' | 'dark' }` - 样式配置(可选)
|
|
60
|
-
- **tools**: `ToolsConfig` - 工具配置(可选)
|
|
61
|
-
- **customComponents**: `{ LoadingComponent?, ErrorComponent? }` - 自定义组件(可选)
|
|
62
|
-
- **className**: `string` - 自定义类名(可选)
|
|
63
|
-
- **headerClass**: `string` - 头部类名(可选)
|
|
64
|
-
- **contentClass**: `string` - 内容类名(可选)
|
|
65
|
-
|
|
66
|
-
#### 调用实例
|
|
50
|
+
// 或者手动注册
|
|
51
|
+
import * as pdfjsLib from 'pdfjs-dist';
|
|
52
|
+
pdfjsLib.GlobalWorkerOptions.workerSrc = '/worker/pdf.worker.min.js';
|
|
53
|
+
```
|
|
67
54
|
|
|
68
|
-
|
|
69
|
-
import { StaticFileReader } from '@mxmweb/fviewer';
|
|
55
|
+
### 样式引入
|
|
70
56
|
|
|
71
|
-
|
|
72
|
-
const handleEvents = (name: string, data?: any) => {
|
|
73
|
-
switch (name) {
|
|
74
|
-
case 'file_loaded':
|
|
75
|
-
console.log('文件加载完成:', data);
|
|
76
|
-
break;
|
|
77
|
-
case 'page_changed':
|
|
78
|
-
console.log('页面切换:', data);
|
|
79
|
-
break;
|
|
80
|
-
case 'annotation_added':
|
|
81
|
-
console.log('添加标注:', data);
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
};
|
|
57
|
+
在项目入口文件中引入样式:
|
|
85
58
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
fileUrl="https://example.com/document.pdf"
|
|
89
|
-
fileName="示例文档.pdf"
|
|
90
|
-
fileType="pdf"
|
|
91
|
-
initialPage={1}
|
|
92
|
-
eventsEmit={handleEvents}
|
|
93
|
-
styles={{
|
|
94
|
-
mode: 'light',
|
|
95
|
-
theme: {
|
|
96
|
-
colors: {
|
|
97
|
-
primary: '#1890ff',
|
|
98
|
-
background: '#ffffff',
|
|
99
|
-
text: '#000000'
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}}
|
|
103
|
-
tools={{
|
|
104
|
-
annotation: true,
|
|
105
|
-
download: true,
|
|
106
|
-
zoom: true,
|
|
107
|
-
navigation: true
|
|
108
|
-
}}
|
|
109
|
-
/>
|
|
110
|
-
);
|
|
111
|
-
}
|
|
59
|
+
```typescript
|
|
60
|
+
import '@mxmweb/fviewer/style.css';
|
|
112
61
|
```
|
|
113
62
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
| --- | ---- | --- |
|
|
118
|
-
| `file_loaded` | 文件加载完成 | `{ fileName: string, fileType: string, totalPages?: number }` |
|
|
119
|
-
| `page_changed` | 页面切换 | `{ currentPage: number, totalPages: number }` |
|
|
120
|
-
| `annotation_added` | 添加标注 | `{ id: string, pageNumber: number, x: number, y: number, content: string }` |
|
|
121
|
-
| `annotation_removed` | 删除标注 | `{ id: string }` |
|
|
122
|
-
| `zoom_changed` | 缩放变化 | `{ scale: number }` |
|
|
123
|
-
| `download_clicked` | 下载按钮点击 | `{ fileName: string }` |
|
|
124
|
-
| `error_occurred` | 错误发生 | `{ error: string, details?: any }` |
|
|
125
|
-
|
|
126
|
-
#### 技术栈
|
|
127
|
-
|
|
128
|
-
- React 18 + TypeScript
|
|
129
|
-
- Styled-components v6 主题样式
|
|
130
|
-
- PDF.js 用于PDF文件解析
|
|
131
|
-
- 响应式设计,支持移动端
|
|
132
|
-
|
|
133
|
-
#### 其他
|
|
134
|
-
|
|
135
|
-
- 支持多种文件格式:PDF、图片、文本、Markdown、HTML
|
|
136
|
-
- 内置文件类型自动检测
|
|
137
|
-
- 支持自定义主题和样式
|
|
138
|
-
- 提供完整的标注功能
|
|
139
|
-
- 支持文件下载和打印
|
|
140
|
-
|
|
141
|
-
### GientechStreamReader
|
|
142
|
-
|
|
143
|
-
流式文件阅读器组件,专门用于处理大文件的流式加载和分页显示。
|
|
144
|
-
|
|
145
|
-
#### Props接口
|
|
146
|
-
|
|
147
|
-
- **convertedFilePath**: `string` - 转换后的文件路径(必需)
|
|
148
|
-
- **csrfToken**: `string` - CSRF令牌(可选)
|
|
149
|
-
- **fileName**: `string` - 文件名(可选)
|
|
150
|
-
- **fileType**: `string` - 文件类型(必需)
|
|
151
|
-
- **initialPage**: `number` - 初始页码(可选)
|
|
152
|
-
- **totalPages**: `number` - 总页数(可选)
|
|
153
|
-
- **annotations**: `(Annotation | MDAnnotation | TableAnnotation)[]` - 标注数据数组(可选)
|
|
154
|
-
- **userName**: `string` - 用户名(可选)
|
|
155
|
-
- **userId**: `string` - 用户ID(可选)
|
|
156
|
-
- **pageSize**: `number` - 页面大小(可选)
|
|
157
|
-
- **streamApiUrl**: `string` - 流式API地址(可选)
|
|
158
|
-
- **authorization**: `string` - 授权头(可选)
|
|
159
|
-
- **eventsEmit**: `(name: string, data?: any, innerFn?: any) => void` - 事件回调函数(可选)
|
|
160
|
-
- **tools**: `Partial<ToolsConfig>` - 工具配置(可选)
|
|
161
|
-
- **styles**: `Styles` - 样式配置(可选)
|
|
162
|
-
- **customComponents**: `{ LoadingComponent?, ErrorComponent? }` - 自定义组件(可选)
|
|
163
|
-
- **className**: `string` - 自定义类名(可选)
|
|
164
|
-
- **headerClass**: `string` - 头部类名(可选)
|
|
165
|
-
- **contentClass**: `string` - 内容类名(可选)
|
|
166
|
-
|
|
167
|
-
#### 调用实例
|
|
63
|
+
## 🚀 快速开始
|
|
64
|
+
|
|
65
|
+
### 基础用法
|
|
168
66
|
|
|
169
67
|
```tsx
|
|
170
|
-
import
|
|
68
|
+
import React from 'react';
|
|
69
|
+
import { StaticFileReader } from '@mxmweb/fviewer';
|
|
70
|
+
import '@mxmweb/fviewer/style.css';
|
|
171
71
|
|
|
172
72
|
function App() {
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
case 'page_loaded':
|
|
176
|
-
console.log('页面加载完成:', data);
|
|
177
|
-
break;
|
|
178
|
-
case 'stream_error':
|
|
179
|
-
console.log('流式加载错误:', data);
|
|
180
|
-
break;
|
|
181
|
-
case 'cache_updated':
|
|
182
|
-
console.log('缓存更新:', data);
|
|
183
|
-
break;
|
|
184
|
-
}
|
|
73
|
+
const handleEvents = (eventName: string, data?: any) => {
|
|
74
|
+
console.log('Event:', eventName, data);
|
|
185
75
|
};
|
|
186
76
|
|
|
187
77
|
return (
|
|
188
|
-
<
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
styles={{
|
|
203
|
-
theme: {
|
|
204
|
-
colors: {
|
|
205
|
-
primary: '#52c41a',
|
|
206
|
-
background: '#fafafa'
|
|
78
|
+
<div style={{ width: '100%', height: '100vh' }}>
|
|
79
|
+
<StaticFileReader
|
|
80
|
+
fileUrl="https://example.com/document.pdf"
|
|
81
|
+
fileName="示例文档.pdf"
|
|
82
|
+
fileType="pdf"
|
|
83
|
+
eventsEmit={handleEvents}
|
|
84
|
+
styles={{
|
|
85
|
+
mode: 'light',
|
|
86
|
+
theme: {
|
|
87
|
+
colors: {
|
|
88
|
+
primary: '#1890ff',
|
|
89
|
+
background: '#ffffff',
|
|
90
|
+
text: '#000000'
|
|
91
|
+
}
|
|
207
92
|
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
|
|
93
|
+
}}
|
|
94
|
+
tools={{
|
|
95
|
+
annotation: true,
|
|
96
|
+
download: true,
|
|
97
|
+
zoom: true,
|
|
98
|
+
navigation: true
|
|
99
|
+
}}
|
|
100
|
+
/>
|
|
101
|
+
</div>
|
|
211
102
|
);
|
|
212
103
|
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
#### eventsEmit详细说明
|
|
216
|
-
|
|
217
|
-
| 事件名 | 说明 | 数据格式 |
|
|
218
|
-
| --- | ---- | --- |
|
|
219
|
-
| `page_loaded` | 页面加载完成 | `{ pageNo: number, data: ArrayBuffer, timestamp: number }` |
|
|
220
|
-
| `stream_error` | 流式加载错误 | `{ error: string, pageNo?: number, retryCount: number }` |
|
|
221
|
-
| `cache_updated` | 缓存更新 | `{ cacheKey: string, pages: number[], timestamp: number }` |
|
|
222
|
-
| `page_requested` | 页面请求开始 | `{ pageNo: number, requestId: string }` |
|
|
223
|
-
| `navigation_changed` | 导航变化 | `{ currentPage: number, totalPages: number, direction: 'next' \| 'prev' }` |
|
|
224
|
-
| `user_action` | 用户操作 | `{ action: string, pageNo: number, timestamp: number }` |
|
|
225
104
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
- React 18 + TypeScript
|
|
229
|
-
- Axios 用于HTTP请求
|
|
230
|
-
- 智能分页缓存系统
|
|
231
|
-
- 流式数据加载
|
|
232
|
-
- 内存优化管理
|
|
233
|
-
|
|
234
|
-
#### 其他
|
|
235
|
-
|
|
236
|
-
- 支持超大文件的分页加载
|
|
237
|
-
- 智能缓存策略,减少重复请求
|
|
238
|
-
- 支持断点续传和错误重试
|
|
239
|
-
- 内存使用优化,避免内存泄漏
|
|
240
|
-
- 支持多种认证方式
|
|
241
|
-
|
|
242
|
-
## 工具函数
|
|
243
|
-
|
|
244
|
-
### parseFile
|
|
245
|
-
|
|
246
|
-
通用文件解析函数,自动检测文件类型并调用相应的解析器。
|
|
247
|
-
|
|
248
|
-
```tsx
|
|
249
|
-
import { parseFile } from '@mxmweb/fviewer';
|
|
250
|
-
|
|
251
|
-
const result = await parseFile(fileData, {
|
|
252
|
-
fileName: 'document.pdf',
|
|
253
|
-
fileType: 'pdf'
|
|
254
|
-
});
|
|
105
|
+
export default App;
|
|
255
106
|
```
|
|
256
107
|
|
|
257
|
-
|
|
108
|
+
## 🔗 链接
|
|
258
109
|
|
|
259
|
-
|
|
110
|
+
- **NPM**: <https://www.npmjs.com/package/@mxmweb/fviewer>
|
|
111
|
+
- **GitHub**: <https://github.com/your-org/fviewer>
|
|
260
112
|
|
|
261
|
-
|
|
262
|
-
import { parsePdfFile } from '@mxmweb/fviewer';
|
|
113
|
+
## 📚 API 文档
|
|
263
114
|
|
|
264
|
-
|
|
265
|
-
fileName: 'document.pdf'
|
|
266
|
-
});
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
### parseImageFile
|
|
270
|
-
|
|
271
|
-
图片文件解析函数。
|
|
272
|
-
|
|
273
|
-
```tsx
|
|
274
|
-
import { parseImageFile } from '@mxmweb/fviewer';
|
|
275
|
-
|
|
276
|
-
const imageResult = await parseImageFile(imageBlob, {
|
|
277
|
-
fileName: 'image.jpg'
|
|
278
|
-
});
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
### parseTextFile
|
|
282
|
-
|
|
283
|
-
文本文件解析函数。
|
|
284
|
-
|
|
285
|
-
```tsx
|
|
286
|
-
import { parseTextFile } from '@mxmweb/fviewer';
|
|
287
|
-
|
|
288
|
-
const textResult = await parseTextFile(textContent, {
|
|
289
|
-
fileName: 'document.txt'
|
|
290
|
-
});
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
### parseMarkdownFile
|
|
294
|
-
|
|
295
|
-
Markdown文件解析函数。
|
|
115
|
+
> 📖 完整 API 文档请查看:[doc_assets/接口/](./doc_assets/接口/)
|
|
296
116
|
|
|
297
|
-
|
|
298
|
-
|
|
117
|
+
- **接口文档**: [Fviewer API](./doc_assets/接口/Fviewer.md)、[StaticFileReader API](./doc_assets/接口/StaticFileReader.md)
|
|
118
|
+
- **更新说明**: [CHANGELOG](./doc_assets/更新说明/CHANGELOG.md)
|
|
119
|
+
- **演示说明**: [演示文档](./doc_assets/演示/index.md)
|
|
299
120
|
|
|
300
|
-
|
|
301
|
-
fileName: 'readme.md'
|
|
302
|
-
});
|
|
303
|
-
```
|
|
121
|
+
### 核心组件(Core Components)
|
|
304
122
|
|
|
305
|
-
|
|
123
|
+
#### Fviewer
|
|
306
124
|
|
|
307
|
-
|
|
125
|
+
核心文件查看器组件,提供基础的文件显示和交互能力。
|
|
308
126
|
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
```tsx
|
|
321
|
-
import { registerPDFWorker } from '@mxmweb/fviewer';
|
|
322
|
-
|
|
323
|
-
// 注册PDF Worker
|
|
324
|
-
registerPDFWorker('/worker/pdf.worker.min.js');
|
|
325
|
-
```
|
|
326
|
-
|
|
327
|
-
### isPDFWorkerRegistered
|
|
328
|
-
|
|
329
|
-
检查PDF Worker是否已注册的函数。
|
|
330
|
-
|
|
331
|
-
```tsx
|
|
332
|
-
import { isPDFWorkerRegistered } from '@mxmweb/fviewer';
|
|
333
|
-
|
|
334
|
-
const isRegistered = isPDFWorkerRegistered();
|
|
335
|
-
console.log('PDF Worker已注册:', isRegistered);
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### getPDFWorkerPath
|
|
339
|
-
|
|
340
|
-
获取当前PDF Worker路径的函数。
|
|
341
|
-
|
|
342
|
-
```tsx
|
|
343
|
-
import { getPDFWorkerPath } from '@mxmweb/fviewer';
|
|
344
|
-
|
|
345
|
-
const workerPath = getPDFWorkerPath();
|
|
346
|
-
console.log('当前PDF Worker路径:', workerPath);
|
|
347
|
-
```
|
|
348
|
-
|
|
349
|
-
## 类型定义
|
|
350
|
-
|
|
351
|
-
### StaticFileReaderProps
|
|
352
|
-
|
|
353
|
-
静态文件阅读器组件的属性接口。
|
|
354
|
-
|
|
355
|
-
```tsx
|
|
356
|
-
interface StaticFileReaderProps {
|
|
357
|
-
// 文件相关
|
|
358
|
-
fileUrl: string;
|
|
359
|
-
fileType?: string;
|
|
360
|
-
fileName?: string;
|
|
361
|
-
token?: string;
|
|
362
|
-
initialPage?: number;
|
|
363
|
-
annotations?: (Annotation | MDAnnotation | TableAnnotation)[];
|
|
364
|
-
// 直接数据传递
|
|
365
|
-
data?: any;
|
|
366
|
-
// 事件回调
|
|
127
|
+
```typescript
|
|
128
|
+
interface FviewerProps {
|
|
129
|
+
data: FviewerData;
|
|
130
|
+
annotationData?: (Annotation | MDAnnotation | TableAnnotation)[];
|
|
131
|
+
totalPage?: number;
|
|
132
|
+
currentPage?: number;
|
|
133
|
+
scale?: number;
|
|
134
|
+
initialZoom?: number;
|
|
135
|
+
rotation?: number;
|
|
136
|
+
setScale?: (scale: number) => void;
|
|
367
137
|
eventsEmit?: (name: string, data?: any, innerFn?: any) => void;
|
|
368
|
-
// 样式配置
|
|
369
138
|
styles?: {
|
|
370
139
|
theme?: AppTheme;
|
|
371
140
|
mode?: 'light' | 'dark';
|
|
372
141
|
};
|
|
373
|
-
// 工具配置
|
|
374
142
|
tools?: ToolsConfig;
|
|
375
|
-
|
|
376
|
-
customComponents?: {
|
|
377
|
-
LoadingComponent?: React.ComponentType<{
|
|
378
|
-
status: string;
|
|
379
|
-
theme: AppTheme;
|
|
380
|
-
}>;
|
|
381
|
-
ErrorComponent?: React.ComponentType<{
|
|
382
|
-
error: string;
|
|
383
|
-
theme: AppTheme;
|
|
384
|
-
}>;
|
|
385
|
-
};
|
|
386
|
-
// 自定义类名
|
|
143
|
+
customComponents?: CustomizeComponents;
|
|
387
144
|
className?: string;
|
|
388
|
-
headerClass?: string;
|
|
389
145
|
contentClass?: string;
|
|
390
146
|
}
|
|
391
147
|
```
|
|
392
148
|
|
|
393
|
-
|
|
149
|
+
#### StaticFileReader
|
|
394
150
|
|
|
395
|
-
|
|
151
|
+
静态文件阅读器组件,用于加载和显示本地或远程静态文件。
|
|
396
152
|
|
|
397
|
-
```
|
|
398
|
-
interface
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
csrfToken?: string;
|
|
153
|
+
```typescript
|
|
154
|
+
interface StaticFileReaderProps {
|
|
155
|
+
fileUrl?: string;
|
|
156
|
+
fileType?: string;
|
|
402
157
|
fileName?: string;
|
|
403
|
-
|
|
158
|
+
token?: string;
|
|
404
159
|
initialPage?: number;
|
|
405
|
-
totalPages?: number;
|
|
406
160
|
annotations?: (Annotation | MDAnnotation | TableAnnotation)[];
|
|
407
|
-
|
|
408
|
-
userName?: string;
|
|
409
|
-
userId?: string;
|
|
410
|
-
pageSize?: number;
|
|
411
|
-
// API配置
|
|
412
|
-
streamApiUrl?: string;
|
|
413
|
-
authorization?: string;
|
|
414
|
-
// 事件回调
|
|
161
|
+
data?: any;
|
|
415
162
|
eventsEmit?: (name: string, data?: any, innerFn?: any) => void;
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
163
|
+
styles?: {
|
|
164
|
+
theme?: AppTheme;
|
|
165
|
+
mode?: 'light' | 'dark';
|
|
166
|
+
};
|
|
167
|
+
tools?: ToolsConfig;
|
|
421
168
|
customComponents?: {
|
|
422
|
-
LoadingComponent?: React.ComponentType<{
|
|
423
|
-
|
|
424
|
-
theme: AppTheme;
|
|
425
|
-
}>;
|
|
426
|
-
ErrorComponent?: React.ComponentType<{
|
|
427
|
-
error: string;
|
|
428
|
-
theme: AppTheme;
|
|
429
|
-
}>;
|
|
169
|
+
LoadingComponent?: React.ComponentType<{ status: string; theme: AppTheme }>;
|
|
170
|
+
ErrorComponent?: React.ComponentType<{ error: string; theme: AppTheme }>;
|
|
430
171
|
};
|
|
431
|
-
// 自定义类名
|
|
432
172
|
className?: string;
|
|
433
173
|
headerClass?: string;
|
|
434
174
|
contentClass?: string;
|
|
435
175
|
}
|
|
436
176
|
```
|
|
437
177
|
|
|
438
|
-
###
|
|
439
|
-
|
|
440
|
-
PDF渲染组件的属性接口。
|
|
441
|
-
|
|
442
|
-
```tsx
|
|
443
|
-
interface PdfRenderProps {
|
|
444
|
-
data: ArrayBuffer | string;
|
|
445
|
-
pageNumber?: number;
|
|
446
|
-
scale?: number;
|
|
447
|
-
annotations?: Annotation[];
|
|
448
|
-
onPageChange?: (pageNumber: number) => void;
|
|
449
|
-
onScaleChange?: (scale: number) => void;
|
|
450
|
-
}
|
|
451
|
-
```
|
|
452
|
-
|
|
453
|
-
### Annotation
|
|
454
|
-
|
|
455
|
-
PDF标注数据接口。
|
|
456
|
-
|
|
457
|
-
```tsx
|
|
458
|
-
interface Annotation {
|
|
459
|
-
id: string;
|
|
460
|
-
pageNumber: number;
|
|
461
|
-
x: number;
|
|
462
|
-
y: number;
|
|
463
|
-
width: number;
|
|
464
|
-
height: number;
|
|
465
|
-
content?: string;
|
|
466
|
-
color?: string;
|
|
467
|
-
}
|
|
468
|
-
```
|
|
469
|
-
|
|
470
|
-
### MDAnnotation
|
|
178
|
+
### 工具函数
|
|
471
179
|
|
|
472
|
-
|
|
180
|
+
- `parseFile` - 通用文件解析函数
|
|
181
|
+
- `parsePdfFile` - PDF文件解析函数
|
|
182
|
+
- `parseImageFile` - 图片文件解析函数
|
|
183
|
+
- `parseTextFile` - 文本文件解析函数
|
|
184
|
+
- `parseMarkdownFile` - Markdown文件解析函数
|
|
185
|
+
- `detectFileType` - 文件类型检测函数
|
|
186
|
+
- `registerPDFWorker` - PDF Worker注册函数
|
|
187
|
+
- `isPDFWorkerRegistered` - 检查PDF Worker是否已注册
|
|
188
|
+
- `getPDFWorkerPath` - 获取当前PDF Worker路径
|
|
473
189
|
|
|
474
|
-
|
|
475
|
-
interface MDAnnotation {
|
|
476
|
-
id: string;
|
|
477
|
-
start: number;
|
|
478
|
-
end: number;
|
|
479
|
-
content?: string;
|
|
480
|
-
color?: string;
|
|
481
|
-
}
|
|
482
|
-
```
|
|
190
|
+
## 🛠️ 技术栈
|
|
483
191
|
|
|
484
|
-
|
|
192
|
+
- **React** `>=18 <20` - 前端框架
|
|
193
|
+
- **TypeScript** - 类型支持
|
|
194
|
+
- **styled-components** `^6.1.19` - CSS-in-JS 样式方案
|
|
195
|
+
- **@mxmweb/zui** `^1.*` - UI 组件库
|
|
196
|
+
- **@mxmweb/rtext** `^1.*` - 富文本组件库
|
|
197
|
+
- **pdfjs-dist** `2.16.105` - PDF 解析库
|
|
485
198
|
|
|
486
|
-
|
|
199
|
+
## 📁 项目结构
|
|
487
200
|
|
|
488
|
-
```
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
201
|
+
```text
|
|
202
|
+
src/
|
|
203
|
+
├── lib_enter.ts # 库入口,导出所有公共 API
|
|
204
|
+
├── style.css # 样式文件
|
|
205
|
+
├── core/ # 核心组件
|
|
206
|
+
│ ├── Fviewer.tsx # Fviewer 核心组件
|
|
207
|
+
│ ├── types.ts # 类型定义
|
|
208
|
+
│ ├── PdfRender.tsx # PDF 渲染组件
|
|
209
|
+
│ └── utils/ # 工具函数
|
|
210
|
+
│ └── fileParser.ts # 文件解析工具
|
|
211
|
+
└── adopters/ # 业务扩展组件
|
|
212
|
+
└── StaticFileReader.tsx # 静态文件阅读器
|
|
495
213
|
```
|
|
496
214
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
工具配置接口。
|
|
500
|
-
|
|
501
|
-
```tsx
|
|
502
|
-
interface ToolsConfig {
|
|
503
|
-
annotation?: boolean; // 标注功能
|
|
504
|
-
download?: boolean; // 下载功能
|
|
505
|
-
zoom?: boolean; // 缩放功能
|
|
506
|
-
close?: boolean; // 关闭功能
|
|
507
|
-
navigation?: boolean; // 导航功能
|
|
508
|
-
rotate?: boolean; // 旋转功能(主要用于图片)
|
|
509
|
-
}
|
|
510
|
-
```
|
|
215
|
+
## 🎯 使用场景
|
|
511
216
|
|
|
512
|
-
|
|
217
|
+
- 文档预览系统
|
|
218
|
+
- 文件管理系统
|
|
219
|
+
- 在线文档阅读器
|
|
220
|
+
- 知识库文档展示
|
|
221
|
+
- 文件标注和批注系统
|
|
513
222
|
|
|
514
|
-
|
|
223
|
+
## 📝 示例
|
|
515
224
|
|
|
516
|
-
|
|
517
|
-
interface AppTheme {
|
|
518
|
-
colors: {
|
|
519
|
-
primary: string;
|
|
520
|
-
secondary: string;
|
|
521
|
-
success: string;
|
|
522
|
-
warning: string;
|
|
523
|
-
error: string;
|
|
524
|
-
info: string;
|
|
525
|
-
background: string;
|
|
526
|
-
text: string;
|
|
527
|
-
border: string;
|
|
528
|
-
disabled: string;
|
|
529
|
-
disabledBackground: string;
|
|
530
|
-
disabledText: string;
|
|
531
|
-
[key: string]: any;
|
|
532
|
-
};
|
|
533
|
-
space: {
|
|
534
|
-
sidebar: string;
|
|
535
|
-
size: string;
|
|
536
|
-
radius: string;
|
|
537
|
-
padding: string;
|
|
538
|
-
margin: string;
|
|
539
|
-
shadow: string;
|
|
540
|
-
lineHeight: string;
|
|
541
|
-
[key: string]: any;
|
|
542
|
-
};
|
|
543
|
-
[key: string]: any;
|
|
544
|
-
}
|
|
545
|
-
```
|
|
225
|
+
查看 `src/examples/` 目录获取更多完整示例:
|
|
546
226
|
|
|
547
|
-
|
|
227
|
+
- **基础用法** - 简单的文件预览
|
|
228
|
+
- **高级用法** - 包含标注、主题定制等完整功能
|
|
548
229
|
|
|
549
|
-
|
|
230
|
+
## 📄 许可证
|
|
550
231
|
|
|
551
|
-
|
|
552
|
-
import { Styles } from '@mxmweb/zui';
|
|
232
|
+
MIT License
|
|
553
233
|
|
|
554
|
-
|
|
555
|
-
// 用于配置组件的主题和样式
|
|
556
|
-
```
|
|
234
|
+
## 👥 作者
|
|
557
235
|
|
|
558
|
-
|
|
236
|
+
- **hanfeng_Zhang**
|
|
559
237
|
|
|
560
|
-
|
|
238
|
+
---
|
|
561
239
|
|
|
562
|
-
|
|
563
|
-
interface ParseResult {
|
|
564
|
-
type: FileType;
|
|
565
|
-
content: any;
|
|
566
|
-
fileName?: string;
|
|
567
|
-
fileType?: string;
|
|
568
|
-
totalPages?: number;
|
|
569
|
-
error?: string;
|
|
570
|
-
}
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
### ParseOptions
|
|
574
|
-
|
|
575
|
-
文件解析选项接口。
|
|
576
|
-
|
|
577
|
-
```tsx
|
|
578
|
-
interface ParseOptions {
|
|
579
|
-
fileName?: string;
|
|
580
|
-
fileType?: string;
|
|
581
|
-
token?: string;
|
|
582
|
-
}
|
|
583
|
-
```
|
|
584
|
-
|
|
585
|
-
### FileType
|
|
586
|
-
|
|
587
|
-
文件类型枚举。
|
|
588
|
-
|
|
589
|
-
```tsx
|
|
590
|
-
type FileType = 'pdf' | 'image' | 'text' | 'markdown' | 'markdown_table' | 'html' | 'unknown';
|
|
591
|
-
```
|
|
240
|
+
⭐ 如果这个项目对你有帮助,请给它一个 Star!
|