f-docx-editor 0.1.0 → 0.1.1
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 +35 -0
- package/dist/FDocxEditor.common.js +199743 -0
- package/dist/FDocxEditor.css +1 -0
- package/dist/FDocxEditor.umd.js +199762 -0
- package/dist/FDocxEditor.umd.min.js +16 -0
- package/dist/README.md +112 -0
- package/dist/demo.html +1 -0
- package/dist/package.json +52 -0
- package/package.json +100 -52
- package/src/App.vue +116 -0
- package/src/FDocxEditor.vue +4613 -0
- package/src/index.js +8 -0
- package/src/main.js +8 -0
- package/src/mock.js +2408 -0
- package/FDocxEditor.common.js +0 -2
- package/FDocxEditor.css +0 -1
- package/FDocxEditor.umd.js +0 -2
- package/FDocxEditor.umd.min.js +0 -2
package/dist/README.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# FDocxEditor
|
|
2
|
+
|
|
3
|
+
`FDocxEditor` 是一个基于 Vue 3 的 Word 报告组件,支持 docx 模板渲染、页面预览、定点富文本编辑和导出最新 docx。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install f-docx-editor
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
项目结构
|
|
12
|
+
|
|
13
|
+
f-docx-editor/
|
|
14
|
+
├── src/
|
|
15
|
+
│ ├── FDocxEditor.vue # 核心组件
|
|
16
|
+
│ ├── index.js # 组件导出入口
|
|
17
|
+
│ ├── App.vue # 开发测试用 App
|
|
18
|
+
│ └── main.js # 开发入口
|
|
19
|
+
├── example/ # 示例代码
|
|
20
|
+
├── scripts/
|
|
21
|
+
│ └── prepare-package.mjs # 打包脚本
|
|
22
|
+
├── public/
|
|
23
|
+
│ └── index.html
|
|
24
|
+
├── package.json
|
|
25
|
+
├── vue.config.js
|
|
26
|
+
└── README.md
|
|
27
|
+
|
|
28
|
+
使用方式
|
|
29
|
+
|
|
30
|
+
开发测试
|
|
31
|
+
|
|
32
|
+
cd /Users/fang/Documents/f-docx-editor
|
|
33
|
+
npm install
|
|
34
|
+
npm run serve
|
|
35
|
+
|
|
36
|
+
构建库
|
|
37
|
+
|
|
38
|
+
npm run build:lib
|
|
39
|
+
|
|
40
|
+
发布到 npm
|
|
41
|
+
|
|
42
|
+
npm run build:lib
|
|
43
|
+
cd dist
|
|
44
|
+
npm publish --access public
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
import FDocxEditor from 'f-docx-editor'
|
|
48
|
+
import 'f-docx-editor/FDocxEditor.css'
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 基础使用
|
|
52
|
+
|
|
53
|
+
```vue
|
|
54
|
+
<template>
|
|
55
|
+
<FDocxEditor
|
|
56
|
+
ref="editorRef"
|
|
57
|
+
render-type="edit"
|
|
58
|
+
:render-data="reportData"
|
|
59
|
+
template-url="/运营报告.docx"
|
|
60
|
+
@save-payload-change="handleSavePayloadChange"
|
|
61
|
+
/>
|
|
62
|
+
</template>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 模板配置
|
|
66
|
+
|
|
67
|
+
发布到 npm 的包不会内置 `运营报告.docx`,避免把业务模板、真实字段和示例数据一起发布出去。
|
|
68
|
+
|
|
69
|
+
你需要在业务系统中提供模板文件,有两种方式:
|
|
70
|
+
|
|
71
|
+
1. 放到业务项目的 `public/运营报告.docx`,组件使用 `template-url="/运营报告.docx"`。
|
|
72
|
+
2. 由后端或文件服务返回模板地址,组件使用 `template-url="https://your-domain/path/运营报告.docx"`。
|
|
73
|
+
|
|
74
|
+
模板中的可编辑变量需要使用:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
[EDITOR_START] {字段名} [EDITOR_END]
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
例如:
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
[EDITOR_START] {OverallSituation} [EDITOR_END]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
后端保存时建议保存 `save-payload-change` 事件抛出的结构,其中富文本内容在 `renderData.__editableRichTextMap` 中。下次渲染时,把后端保存后的完整 `renderData` 重新传给组件即可。
|
|
87
|
+
|
|
88
|
+
## Props
|
|
89
|
+
|
|
90
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
91
|
+
| --- | --- | --- | --- |
|
|
92
|
+
| `renderData` | `Object` | `{}` | docxtemplater 渲染数据,包含普通变量、循环数据、图表数据和富文本数据 |
|
|
93
|
+
| `renderType` | `'view' \| 'edit'` | `'view'` | `view` 为只预览,`edit` 为定点可编辑 |
|
|
94
|
+
| `templateUrl` | `String` | `''` | 推荐使用,指定 docx 模板文件地址 |
|
|
95
|
+
| `templateFileName` | `String` | `'运营报告.docx'` | 未传 `templateUrl` 时,从站点根路径加载该文件 |
|
|
96
|
+
| `exportFileName` | `String` | `''` | 自定义导出文件名 |
|
|
97
|
+
|
|
98
|
+
## 暴露方法
|
|
99
|
+
|
|
100
|
+
通过 `ref` 可以调用:
|
|
101
|
+
|
|
102
|
+
| 方法 | 说明 |
|
|
103
|
+
| --- | --- |
|
|
104
|
+
| `exportDocx()` | 导出最新 docx |
|
|
105
|
+
| `getRenderData()` | 获取当前组件内最新 `renderData` |
|
|
106
|
+
| `getSavePayload()` | 获取建议提交给后端的保存结构 |
|
|
107
|
+
| `getEditorHtml()` | 获取当前弹窗编辑器 HTML |
|
|
108
|
+
| `getEditorJson()` | 获取当前弹窗编辑器 JSON |
|
|
109
|
+
|
|
110
|
+
## 数据安全建议
|
|
111
|
+
|
|
112
|
+
不要把真实业务模板、真实接口数据、内部地址、账号信息、密钥或生产 mock 数据发布进 npm 包。模板文件建议由业务系统自行托管,并通过 `templateUrl` 注入。
|
package/dist/demo.html
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<!doctype html><meta charset="utf-8"><title>FDocxEditor demo</title><script src="./FDocxEditor.umd.js"></script><link rel="stylesheet" href="./FDocxEditor.css"><script>console.log(FDocxEditor)</script>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "f-docx-editor",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Vue 3 Word docx preview, editable rich-text regions and docx export component.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"vue3",
|
|
7
|
+
"docx",
|
|
8
|
+
"docxtemplater",
|
|
9
|
+
"docx-preview",
|
|
10
|
+
"tiptap",
|
|
11
|
+
"word"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"main": "./FDocxEditor.common.js",
|
|
15
|
+
"unpkg": "./FDocxEditor.umd.min.js",
|
|
16
|
+
"jsdelivr": "./FDocxEditor.umd.min.js",
|
|
17
|
+
"files": [
|
|
18
|
+
"FDocxEditor.common.js",
|
|
19
|
+
"FDocxEditor.umd.js",
|
|
20
|
+
"FDocxEditor.umd.min.js",
|
|
21
|
+
"FDocxEditor.css",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"vue": "^3.2.13",
|
|
26
|
+
"element-plus": "^2.6.2"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@element-plus/icons-vue": "^2.3.1",
|
|
30
|
+
"@tiptap/core": "^3.23.4",
|
|
31
|
+
"@tiptap/extension-color": "^3.23.4",
|
|
32
|
+
"@tiptap/extension-highlight": "^3.23.4",
|
|
33
|
+
"@tiptap/extension-placeholder": "^3.23.4",
|
|
34
|
+
"@tiptap/extension-table": "^3.23.4",
|
|
35
|
+
"@tiptap/extension-table-cell": "^3.23.4",
|
|
36
|
+
"@tiptap/extension-table-header": "^3.23.4",
|
|
37
|
+
"@tiptap/extension-table-row": "^3.23.4",
|
|
38
|
+
"@tiptap/extension-text-align": "^3.23.4",
|
|
39
|
+
"@tiptap/extension-text-style": "^3.23.4",
|
|
40
|
+
"@tiptap/pm": "^3.23.4",
|
|
41
|
+
"@tiptap/starter-kit": "^3.23.4",
|
|
42
|
+
"@tiptap/vue-3": "^3.23.4",
|
|
43
|
+
"docx-preview": "^0.3.7",
|
|
44
|
+
"docxtemplater": "^3.68.7",
|
|
45
|
+
"docxtemplater-image-module-free": "^1.1.1",
|
|
46
|
+
"echarts": "^5.5.0",
|
|
47
|
+
"pizzip": "^3.2.0"
|
|
48
|
+
},
|
|
49
|
+
"sideEffects": [
|
|
50
|
+
"*.css"
|
|
51
|
+
]
|
|
52
|
+
}
|
package/package.json
CHANGED
|
@@ -1,52 +1,100 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "f-docx-editor",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Vue 3 Word docx preview, editable rich-text regions and docx export component.",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"vue3",
|
|
7
|
-
"docx",
|
|
8
|
-
"docxtemplater",
|
|
9
|
-
"docx-preview",
|
|
10
|
-
"tiptap",
|
|
11
|
-
"word"
|
|
12
|
-
],
|
|
13
|
-
"license": "MIT",
|
|
14
|
-
"main": "./FDocxEditor.common.js",
|
|
15
|
-
"unpkg": "./FDocxEditor.umd.min.js",
|
|
16
|
-
"jsdelivr": "./FDocxEditor.umd.min.js",
|
|
17
|
-
"files": [
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
},
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"@
|
|
34
|
-
"@tiptap/
|
|
35
|
-
"@tiptap/extension-
|
|
36
|
-
"@tiptap/extension-
|
|
37
|
-
"@tiptap/extension-
|
|
38
|
-
"@tiptap/extension-
|
|
39
|
-
"@tiptap/extension-
|
|
40
|
-
"@tiptap/
|
|
41
|
-
"@tiptap/
|
|
42
|
-
"@tiptap/
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "f-docx-editor",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Vue 3 Word docx preview, editable rich-text regions and docx export component.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"vue3",
|
|
7
|
+
"docx",
|
|
8
|
+
"docxtemplater",
|
|
9
|
+
"docx-preview",
|
|
10
|
+
"tiptap",
|
|
11
|
+
"word"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"main": "./dist/FDocxEditor.common.js",
|
|
15
|
+
"unpkg": "./dist/FDocxEditor.umd.min.js",
|
|
16
|
+
"jsdelivr": "./dist/FDocxEditor.umd.min.js",
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"src"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"dev": "vue-cli-service serve",
|
|
23
|
+
"build": "vue-cli-service build",
|
|
24
|
+
"build:lib": "vue-cli-service build --target lib --name FDocxEditor --dest dist src/index.js && node scripts/prepare-package.mjs",
|
|
25
|
+
"lint": "vue-cli-service lint",
|
|
26
|
+
"prepublishOnly": "npm run build:lib"
|
|
27
|
+
},
|
|
28
|
+
"peerDependencies": {
|
|
29
|
+
"vue": "^3.2.13",
|
|
30
|
+
"element-plus": "^2.6.2"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@element-plus/icons-vue": "^2.3.1",
|
|
34
|
+
"@tiptap/core": "^3.23.4",
|
|
35
|
+
"@tiptap/extension-color": "^3.23.4",
|
|
36
|
+
"@tiptap/extension-highlight": "^3.23.4",
|
|
37
|
+
"@tiptap/extension-placeholder": "^3.23.4",
|
|
38
|
+
"@tiptap/extension-table": "^3.23.4",
|
|
39
|
+
"@tiptap/extension-table-cell": "^3.23.4",
|
|
40
|
+
"@tiptap/extension-table-header": "^3.23.4",
|
|
41
|
+
"@tiptap/extension-table-row": "^3.23.4",
|
|
42
|
+
"@tiptap/extension-text-align": "^3.23.4",
|
|
43
|
+
"@tiptap/extension-text-style": "^3.23.4",
|
|
44
|
+
"@tiptap/pm": "^3.23.4",
|
|
45
|
+
"@tiptap/starter-kit": "^3.23.4",
|
|
46
|
+
"@tiptap/vue-3": "^3.23.4",
|
|
47
|
+
"docx-preview": "^0.3.7",
|
|
48
|
+
"docxtemplater": "^3.68.7",
|
|
49
|
+
"docxtemplater-image-module-free": "^1.1.1",
|
|
50
|
+
"echarts": "^5.5.0",
|
|
51
|
+
"pizzip": "^3.2.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@babel/core": "^7.12.16",
|
|
55
|
+
"@babel/eslint-parser": "^7.12.16",
|
|
56
|
+
"@vue/cli-plugin-babel": "~5.0.0",
|
|
57
|
+
"@vue/cli-plugin-eslint": "~5.0.0",
|
|
58
|
+
"@vue/cli-service": "~5.0.0",
|
|
59
|
+
"core-js": "^3.8.3",
|
|
60
|
+
"element-plus": "^2.6.2",
|
|
61
|
+
"eslint": "^7.32.0",
|
|
62
|
+
"eslint-plugin-vue": "^8.0.3",
|
|
63
|
+
"less": "^4.0.0",
|
|
64
|
+
"less-loader": "^8.0.0",
|
|
65
|
+
"vue": "^3.2.13"
|
|
66
|
+
},
|
|
67
|
+
"eslintConfig": {
|
|
68
|
+
"root": true,
|
|
69
|
+
"env": {
|
|
70
|
+
"node": true,
|
|
71
|
+
"browser": true
|
|
72
|
+
},
|
|
73
|
+
"extends": [
|
|
74
|
+
"plugin:vue/vue3-essential",
|
|
75
|
+
"eslint:recommended"
|
|
76
|
+
],
|
|
77
|
+
"parserOptions": {
|
|
78
|
+
"parser": "@babel/eslint-parser",
|
|
79
|
+
"ecmaVersion": 2020,
|
|
80
|
+
"sourceType": "module"
|
|
81
|
+
},
|
|
82
|
+
"globals": {
|
|
83
|
+
"defineProps": "readonly",
|
|
84
|
+
"defineEmits": "readonly",
|
|
85
|
+
"defineExpose": "readonly"
|
|
86
|
+
},
|
|
87
|
+
"rules": {
|
|
88
|
+
"no-unused-vars": "error"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
"browserslist": [
|
|
92
|
+
"> 1%",
|
|
93
|
+
"last 2 versions",
|
|
94
|
+
"not dead",
|
|
95
|
+
"not ie 11"
|
|
96
|
+
],
|
|
97
|
+
"sideEffects": [
|
|
98
|
+
"*.css"
|
|
99
|
+
]
|
|
100
|
+
}
|
package/src/App.vue
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="view-page">
|
|
3
|
+
<div class="bar">
|
|
4
|
+
<div class="left">
|
|
5
|
+
<div class="title">2025年1月第1周运维周报</div>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="right">
|
|
8
|
+
<el-button @click="onChangeRenderType">{{ renderType === 'edit' ? '完成编辑' : '编辑' }}</el-button>
|
|
9
|
+
<el-button type="primary" @click="onSave">保存</el-button>
|
|
10
|
+
<el-button @click="onExport">导出</el-button>
|
|
11
|
+
</div>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="view-page-content">
|
|
14
|
+
<FDocxEditor
|
|
15
|
+
ref="docxEditorRef"
|
|
16
|
+
:renderData="mockExamples"
|
|
17
|
+
:renderType="renderType"
|
|
18
|
+
template-url="/运维运营周报模版.docx"
|
|
19
|
+
@render-data-change="onRenderDataChange"
|
|
20
|
+
@save-payload-change="onSavePayloadChange"
|
|
21
|
+
/>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
|
|
26
|
+
<script>
|
|
27
|
+
export default {
|
|
28
|
+
name: "DocxViewPage"
|
|
29
|
+
}
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<script setup>
|
|
33
|
+
import FDocxEditor from "./FDocxEditor.vue";
|
|
34
|
+
import {ref,onMounted} from "vue";
|
|
35
|
+
import {ElMessage} from "element-plus";
|
|
36
|
+
import {mockData} from "./mock"
|
|
37
|
+
|
|
38
|
+
const renderType = ref('view')
|
|
39
|
+
const docxEditorRef = ref(null)
|
|
40
|
+
const savePayload = ref(null)
|
|
41
|
+
function onChangeRenderType(){
|
|
42
|
+
renderType.value = renderType.value === 'edit' ? 'view' : 'edit'
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function onRenderDataChange(data){
|
|
46
|
+
mockExamples.value = data
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function onSavePayloadChange(payload){
|
|
50
|
+
savePayload.value = payload
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function onSave(){
|
|
54
|
+
const latestRenderData = docxEditorRef.value?.getRenderData?.() || mockExamples.value
|
|
55
|
+
const latestSavePayload = docxEditorRef.value?.getSavePayload?.() || savePayload.value
|
|
56
|
+
mockExamples.value = latestRenderData
|
|
57
|
+
console.log('weekly report renderData:', latestRenderData)
|
|
58
|
+
console.log('weekly report save payload:', latestSavePayload)
|
|
59
|
+
ElMessage.success('已生成可直接提交后端的保存 payload。')
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function onExport(){
|
|
63
|
+
const exportResult = await docxEditorRef.value?.exportDocx?.()
|
|
64
|
+
|
|
65
|
+
if (exportResult?.success) {
|
|
66
|
+
ElMessage.success(`已导出 ${exportResult.fileName}`)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const mockExamples = ref({})
|
|
71
|
+
onMounted(()=>{
|
|
72
|
+
mockExamples.value = mockData
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
</script>
|
|
76
|
+
|
|
77
|
+
<style scoped lang="less">
|
|
78
|
+
html{
|
|
79
|
+
height: 100vh;
|
|
80
|
+
}
|
|
81
|
+
#app{
|
|
82
|
+
height: 100%;
|
|
83
|
+
}
|
|
84
|
+
.view-page{
|
|
85
|
+
height: 100%;
|
|
86
|
+
overflow: hidden;
|
|
87
|
+
.bar{
|
|
88
|
+
height: 50px;
|
|
89
|
+
display: flex;
|
|
90
|
+
justify-content: space-between;
|
|
91
|
+
background: #FFFFFF;
|
|
92
|
+
border-radius: 10px;
|
|
93
|
+
padding: 0 10px;
|
|
94
|
+
.left{
|
|
95
|
+
display: flex;
|
|
96
|
+
align-items: center;
|
|
97
|
+
.title{
|
|
98
|
+
margin-left: 10px;
|
|
99
|
+
font-size: 18px;
|
|
100
|
+
line-height: 50px;
|
|
101
|
+
font-weight: 600;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
.right{
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
.view-page-content{
|
|
110
|
+
background: #fff;
|
|
111
|
+
margin-top: 10px;
|
|
112
|
+
height: calc(100% - 50px - 10px);
|
|
113
|
+
border-radius: 10px;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
</style>
|