azs-doc-editor
v1.0.7
Published
A Vue 3 component for editing DOCX and XLSX documents
Downloads
892
Maintainers
Readme
Vue Document Editor
一个功能完整的 Vue 3 文档编辑器组件,支持 DOCX 和 XLSX 文件的转换和编辑。
特性
- 📄 支持 DOCX 文件转换和编辑(基于 Tiptap)
- 📊 支持 XLSX 文件转换和编辑(基于 Luckysheet)
- 🎨 丰富的编辑功能(格式化、表格、图片等)
- 💾 灵活的保存机制
- 🔌 易于集成到任何 Vue 3 项目
安装
npm install vue-document-editor前置要求
Luckysheet 资源
如果需要使用 Excel 编辑功能,需要在 index.html 中引入 Luckysheet 资源:
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/css/pluginsCss.css' />
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/plugins.css' />
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/css/luckysheet.css' />
<script src="https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/plugins/js/plugin.js"></script>
<script src="https://cdn.jsdelivr.net/npm/luckysheet@latest/dist/luckysheet.umd.js"></script>使用
全局注册
import { createApp } from 'vue'
import DocumentConverter from 'vue-document-converter'
import 'vue-document-converter/style.css'
const app = createApp(App)
app.use(DocumentConverter)基础使用(仅转换)
<template>
<DocumentConverter
:file-url="fileUrl"
:file-type="fileType"
@success="handleSuccess"
@error="handleError"
>
<template #loading>
<div>自定义加载中...</div>
</template>
<template #error="{ error }">
<div>错误: {{ error }}</div>
</template>
</DocumentConverter>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { DocumentConverter, type ConversionResult } from 'vue-document-converter'
import 'vue-document-converter/style.css'
const fileUrl = ref('https://example.com/document.docx')
const fileType = ref<'docx' | 'xlsx'>('docx')
function handleSuccess(result: ConversionResult) {
console.log('转换成功:', result)
// result.type: 'docx' | 'xlsx'
// result.content: 转换后的内容
// result.fileName: 文件名
}
function handleError(error: string) {
console.error('转换失败:', error)
}
</script>2. 使用 Word 编辑器
<template>
<WordEditor
:content="htmlContent"
:editable="true"
@save="handleSave"
@update="handleUpdate"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { WordEditor } from 'vue-document-editor'
import 'vue-document-editor/style.css'
const htmlContent = ref('<p>Hello World</p>')
function handleSave(content: string) {
console.log('保存内容:', content)
// 调用 API 保存
}
function handleUpdate(content: string) {
// 实时更新
htmlContent.value = content
}
</script>3. 使用 Excel 编辑器
<template>
<ExcelEditor
:content="sheets"
:title="title"
:editable="true"
@save="handleSave"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ExcelEditor } from 'vue-document-editor'
import 'vue-document-editor/style.css'
const sheets = ref([])
const title = ref('我的表格')
function handleSave(content: any[]) {
console.log('保存表格:', content)
// 调用 API 保存
}
</script>完整示例:在你的项目中使用
<!-- pages/document-editor.vue -->
<template>
<DocumentEditorPage
:save-handler="saveDocument"
:load-handler="loadDocument"
@saved="handleSaved"
@error="handleError"
/>
</template>
<script setup lang="ts">
import { DocumentEditorPage, type SaveHandler } from 'vue-document-editor'
import { useRouter } from 'vue-router'
import 'vue-document-editor/style.css'
const router = useRouter()
const saveDocument: SaveHandler = async (result) => {
// 调用你的 API
const response = await fetch('/api/documents', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: result.type,
title: result.fileName,
content: result.content
})
})
const data = await response.json()
return { _id: data.id }
}
async function loadDocument(id: string) {
const response = await fetch(`/api/documents/${id}`)
const data = await response.json()
return {
type: data.type,
content: data.content,
title: data.title
}
}
function handleSaved({ _id, result }) {
// 保存成功,可以跳转
router.push(`/documents/${_id}`)
}
function handleError(error: string) {
console.error('错误:', error)
}
</script>路由配置
// router.ts
const routes = [
{
path: '/document/convert',
component: () => import('./pages/document-editor.vue'),
// 访问: /document/convert?fileUrl=xxx&fileType=docx
},
{
path: '/document/edit/:id',
component: () => import('./pages/document-editor.vue'),
// 访问: /document/edit/123
}
]<template>
<DocumentConverter
:file-url="fileUrl"
:file-type="fileType"
:save-handler="saveDocument"
@saved="handleSaved"
@error="handleError"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { DocumentConverter, type ConversionResult, type SaveHandler } from 'vue-document-converter'
import 'vue-document-converter/style.css'
const router = useRouter()
const fileUrl = ref('https://example.com/document.docx')
const fileType = ref<'docx' | 'xlsx'>('docx')
// 自定义保存逻辑
const saveDocument: SaveHandler = async (result) => {
// 调用你的 API 保存文档
const response = await fetch('/api/documents', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: result.type,
title: result.fileName,
content: result.content
})
})
const data = await response.json()
return { _id: data.id }
}
// 保存成功后跳转
function handleSaved({ _id, result }) {
if (result.type === 'docx') {
router.push(`/word-edit?id=${_id}`)
} else if (result.type === 'xlsx') {
router.push(`/excel-edit?id=${_id}`)
}
}
function handleError(error: string) {
console.error('转换失败:', error)
}
</script>手动触发转换
<template>
<DocumentConverter
ref="converterRef"
:auto-convert="false"
/>
<button @click="startConvert">开始转换</button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { DocumentConverter } from 'vue-document-converter'
const converterRef = ref()
function startConvert() {
converterRef.value?.convert('https://example.com/file.xlsx', 'xlsx')
}
</script>API
DocumentEditorPage
完整的文档编辑器页面组件。
Props
| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | fileUrl | string | - | 文件 URL(用于转换新文件) | | fileType | 'docx' | 'xlsx' | - | 文件类型 | | documentId | string | - | 文档 ID(用于加载已存在的文档) | | editable | boolean | true | 是否可编辑 | | loadHandler | (id: string) => Promise | - | 加载文档的处理函数 | | saveHandler | SaveHandler | - | 保存文档的处理函数 |
Events
| 事件 | 参数 | 说明 | |------|------|------| | saved | { _id: string, result: ConversionResult } | 保存成功时触发 | | error | string | 发生错误时触发 | | loaded | { type, content, title } | 文档加载成功时触发 |
WordEditor
Word 文档编辑器组件(基于 Tiptap)。
Props
| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | content | string | - | HTML 内容 | | editable | boolean | true | 是否可编辑 |
Events
| 事件 | 参数 | 说明 | |------|------|------| | save | string | 点击保存按钮时触发 | | update | string | 内容更新时触发 |
Methods
| 方法 | 参数 | 返回值 | 说明 | |------|------|--------|------| | getContent | - | string | 获取当前内容 | | setContent | content: string | - | 设置内容 |
ExcelEditor
Excel 表格编辑器组件(基于 Luckysheet)。
Props
| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | content | any[] | [] | Luckysheet 格式的表格数据 | | title | string | '未命名表格' | 表格标题 | | editable | boolean | true | 是否可编辑 |
Events
| 事件 | 参数 | 说明 | |------|------|------| | save | any[] | 点击保存按钮时触发 | | update | any[] | 内容更新时触发 |
Methods
| 方法 | 参数 | 返回值 | 说明 | |------|------|--------|------| | getContent | - | any[] | 获取当前内容 |
DocumentConverter
文件转换组件(不包含编辑功能)。
| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | fileUrl | string | - | 文件 URL | | fileType | 'docx' | 'xlsx' | - | 文件类型 | | autoConvert | boolean | true | 是否自动转换 | | loadingText | string | '加载中...' | 加载提示文本 | | successText | string | '转换成功' | 成功提示文本 | | saveHandler | SaveHandler | - | 保存处理函数,提供后会自动保存 | | autoRedirect | boolean | false | 是否自动跳转(需配合 saveHandler) |
Events
| 事件 | 参数 | 说明 | |------|------|------| | success | ConversionResult | 转换成功时触发 | | error | string | 转换失败时触发 | | loading | boolean | 加载状态变化时触发 | | saved | { _id: string, result: ConversionResult } | 保存成功时触发(需提供 saveHandler) |
Slots
| 插槽 | 作用域 | 说明 | |------|--------|------| | loading | - | 自定义加载状态 | | error | { error: string } | 自定义错误显示 | | success | { result: ConversionResult } | 自定义成功显示 |
Methods
| 方法 | 参数 | 说明 | |------|------|------| | convert | (fileUrl: string, fileType: 'docx' | 'xlsx') | 手动触发转换 |
License
MIT
