WangEditor5-解析Word
WangEditor5-解析Word
wangEditor官网https://www.wangeditor.com/v5/toolbar-config.html
解析并不是全部解析,如字体颜色等信息会丢失yarn add @wangeditor/editor yarn add @wangeditor/editor-for-react # 用于解析Word yarn add mammoth
1、创建工具栏类
import { IButtonMenu, IDomEditor } from '@wangeditor/editor';
import { word } from '../icon';
class WordMenu implements IButtonMenu {
title: string;
tag: string;
iconSvg: string;
constructor() {
this.title = '解析word到编辑器' // 自定义菜单标题
/**
* 图标这里我的图标是在阿里妈妈适量图标库获取的https://www.iconfont.cn/
* 搜索对应的图标赋值svg代码放到方法返回即可
* icon/index.ts源码
* export const word = () => `<svg>...</svg>`
*/
this.iconSvg = word() // 图标
this.tag = 'button'
}
/**
* 获取编辑器内容源码
* @param editor
*/
getValue(editor: IDomEditor): string | boolean {
return false;
}
/**
* 菜单是否需要激活,当切换为源码时菜单激活
* @param editor
* @param active 激活状态
*/
isActive(editor: IDomEditor, active?: boolean): boolean {
return false;
}
/**
* 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
* @param editor
*/
isDisabled(editor: IDomEditor): boolean {
return false;
}
/**
* 点击菜单时触发的函数
* @param editor
* @param value
*/
exec(editor: IDomEditor, value: string | boolean) {
if (this.isDisabled(editor)) return
editor.emit('clickWord');
}
}
export default WordMenu;
2、工具栏方法实现
import mammoth from "mammoth"; import WordMenu from "./word"; /** * 解析word为html * @param file */ export const analysisWord = (file: any): Promise<string> => { return new Promise((resolve) => { const reader = new FileReader(); reader.onload = (evt: any) => { mammoth .convertToHtml({arrayBuffer: evt.target.result, buffer: undefined, path: ""}) .then((res) => { resolve(res.value); }); } // 启动读取指定的 Blob 或 File 内容 reader.readAsArrayBuffer(file); }); } export const wordConf = { // 工具栏中的唯一key key: 'word', // 组件 factory: () => new WordMenu() };
3、页面具体代码
import { IDomEditor, Boot } from '@wangeditor/editor';
import { Editor, Toolbar } from '@wangeditor/editor-for-react';
import '@wangeditor/editor/dist/css/style.css';
import React, {useEffect, useState, useRef} from 'react';
import {analysisWord, wordConf} from "./props";
const WangEditor = ({ value = '', mode = 'default', onChange, toolbarConfig = {} }: any) => {
/***********自定义变量-------开始*************/
// editor 实例
const [editor, setEditor] = useState<IDomEditor | null>(null);
// 编辑器内容
const [html, setHtml] = useState<string>(value || '');
const file = useRef<HTMLInputElement>(null);
/***********自定义变量-------结束*************/
/***********生命周期函数-------开始*************/
// 及时销毁 editor
useEffect(() => {
if (editor?.isFocused()) {
editor?.blur();
}
return () => {
// eslint-disable-next-line eqeqeq
if (editor == null) return;
editor.destroy();
setEditor(null);
};
}, [editor]);
const onCreated = (editor: IDomEditor) => {
/*
* 在组件创建时初始化注册菜单,注意菜单不可以重复注册否则会报异常
* Unhandled Rejection (Error): Duplicated key 'source' in menu items
*/
if (!editor.getAllMenuKeys().includes('word')) {
Boot.registerMenu(wordConf);
}
setEditor(editor);
// 监听点击word事件
editor?.on('clickWord', () => {
// 开启进度条
editor.showProgressBar(20)
// 选择文件
file.current?.click();
});
}
/**
* 文件上传回调,解析word
* @param event 文件对象
*/
const handleChange = async (event: any) => {
const res = await analysisWord(event.target.files[0]);
// 这里直接插入即可
editor?.dangerouslyInsertHtml(res);
// 进度条借宿
editor?.showProgressBar(100);
// 将文件上传框value给情况
event.target.value = '';
}
/***********生命周期函数-------结束*************/
return (
<div>
<input type='file' accept='.doc,.docx' ref={file} onChange={handleChange} style={{ display: "none" }}/>
<Toolbar
editor={editor}
defaultConfig={{
...toolbarConfig,
// 添加自定义菜单
insertKeys: {
index: editor?.getAllMenuKeys().length || 0,
keys: ['word'],
}
}}
mode={mode}
/>
<Editor value={html} onCreated={onCreated} />
</div>
);
};
export default WangEditor;
效果:https://blog.csdn.net/Ajie246862/article/details/132624660

浙公网安备 33010602011771号