应客户需求,要实现在ckeditor5上进行word上传,并将word解析后,显示到编辑器中。当然,解析word前台不可行,所以就由java完成,然后将解析结果返回给我。
这个插件的编写,是基于vue3使用ck-editor5这篇文章的编辑器实现的。
一、在《vue3使用ck-editor5》一文中第七步提到的下载后的文件夹的src目录下,新建plugins/ImportWord文件夹:
二、在ImportWord文件夹中新建
ui.js —— 此文件定义ui样式
word.svg —— 此为图标文件
command.js —— 此为点击时执行的具体操作
editing.js —— 此为绑定command事件文件
index.js —— 此为插件入口文件
具体代码下面提供,由于才疏学浅,时间有限,具体上传等就直接用原生在那弄了,肯定有更好的方法。
ui.js
/** * @module clear-empty/ui */ import { Plugin } from '@ckeditor/ckeditor5-core'; import { ButtonView } from '@ckeditor/ckeditor5-ui'; import wordIcon from './word.svg'; export class ImportWordUI extends Plugin { /** * @inheritDoc */ static get pluginName() { return 'ImportWordUI'; } /** * @inheritDoc */ init() { const editor = this.editor; editor.ui.componentFactory.add('importWord', (locale) => { const command = editor.commands.get('importWord'); const buttonView = new ButtonView(locale); buttonView.set({ label: '导入Word文档', icon: wordIcon, tooltip: true, }); buttonView.bind('isOn', 'isEnabled').to(command, 'value', 'isEnabled'); this.listenTo(buttonView, 'execute', () => { editor.execute('importWord'); editor.editing.view.focus(); }); return buttonView; }); } } command.js /** * @module import-wrod/command */ import { Command } from '@ckeditor/ckeditor5-core'; export class ImportWordCommand extends Command { /** * @inheritDoc */ // 导入按钮点击时触发 execute(/*options = {}*/) { const model = this.editor.model; const temp = document.createElement('div') temp.innerHTML = '<input id="importWordInput" class="ck-hidden" type="file" tabindex="-1" accept="application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.wordprocessingml.template">' document.body.append(temp) const uploadDom = document.querySelector('#importWordInput') // 上传框点击 uploadDom.click() uploadDom.addEventListener('change', importWordChange) function importWordChange(e) { var formData = new FormData(); formData.append('file', e.target.files[0]); var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { try { const res = JSON.parse(xhr.responseText) if(res.status === 200) { // 读取的后端解析的html内容 const data = res.data const viewFragment = this.editor.data.processor.toView(data) const modelFragment = this.editor.data.toModel(viewFragment) // 将获取的html写入到编辑器 model.insertContent(modelFragment, model.createRangeIn(model.document.getRoot())) } } catch (error) { console.log(error) } // 解绑事件 uploadDom.removeEventListener('change', importWordChange) // 移除上传框 uploadDom.parentNode.removeChild(uploadDom) } } // 调用后端提供的上传接口 xhr.open('POST', '/api/cms/dynamic/readWord') const token = localStorage.getItem('TOKEN') // 设置token if (token) { xhr.setRequestHeader('Authorization', token) } else { xhr.setRequestHeader('Authorization', 'Basic dnVlOnZ1ZQ==') } xhr.send(formData) } } }
editing.js
/** * @module import-word/editing */ import { Plugin } from '@ckeditor/ckeditor5-core'; import { ImportWordCommand } from './command'; export class ImportWordEditing extends Plugin { /** * @inheritDoc */ static get pluginName() { return 'ImportWordEditing'; } /** * @inheritDoc */ init() { const editor = this.editor; editor.commands.add('importWord', new ImportWordCommand(editor)); } }
index.js
/** * @module clear-empty/index */ import { Plugin } from '@ckeditor/ckeditor5-core'; import { ImportWordUI } from './ui'; import { ImportWordEditing } from './editing'; class ImportWord extends Plugin { /** * @inheritDoc */ static get requires() { return [ImportWordUI, ImportWordEditing]; } /** * @inheritDoc */ // 定义插件名称 static get pluginName() { return 'ImportWord'; } } export default ImportWord
三、在src目录的ckeditor.js中引入插件:
import ImportWord from './plugins/ImportWord';
四、在src目录的ckeditor.js中将插件放到build配置中:
Editor.builtinPlugins = [ // ... ImportWord // ... ]
五、在src目录的ckeditor.js中调用插件(当然,这里的调用会被项目中的配置覆盖)
Editor.defaultConfig = { toolbar: { items: [ // ... 'ImportWord', // ... ] } }
六、运行命令打包
npm run build
七、将打包后的build文件夹的内容复制到项目中即可。
最终效果如下: