文章目录

  • 为什么要写这篇文章
  • 基于 Layui 本地安装 wangEditor 最新版本
    • 下载 JS 和 CSS 文件
    • 在 Layui 中创建 wangEditor
  • wangEditor 实现 word 带图片格式内容粘贴
    • 场景描述
    • 分析思路
    • 关键点:图片如何粘贴
    • 最终实现代码(因为仅涉及 JS 代码,所以只提供 JS 代码)
  • 总结

为什么要写这篇文章

  • 首先源自于实际项目的客户需求,真实且刚需。
  • 本人在网上查找了很多相关资料,也对比和参考了其他类似的文本编辑器,才实现到本文实现的效果。提前声明,本文没有做到百分百粘贴前后同样的效果,介意者慎入!!以免浪费您的宝贵时间。
  • 基于 wangEditor 免费开源的前提下实现,没有任何需要付费或使用限制。
  • 出于整理收藏、个人积累,分享出来,抛砖引玉。

基于 Layui 本地安装 wangEditor 最新版本

不建议使用官网的 CDN,亲测不是很稳定。官网安装文档

下载 JS 和 CSS 文件

  • 在任意位置新建一个 test1 文件夹,打开控制台,目录定位到该文件夹,执行 npm install @wangeditor/editor 或 yarn add @wangeditor/editor;
  • 安装完成,打开 node_modules/@wangeditor/editor/dist 文件夹,即可找到 JS CSS 文件:
    • index.js
    • css/style.css
  • 把上面两个文件拷贝到你的项目中。

在 Layui 中创建 wangEditor

  • 新建一个引入 Layui 的 HTML 文档
<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="ie=edge"><meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"><title>Page title</title><link href="/lib/layui-2.7.0/css/layui.css" rel="stylesheet"><style></style>
</head><body><script src="/lib/layui-2.7.0/layui.js"></script><script></script>
</body></html>
  • 定义编辑器 html 结构,并引入 css 和 js
    编辑器和工具栏是强制分离的,所以需要定义两个 div。此时代码结构如下。
<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="ie=edge"><meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"><title>Page title</title><link href="/lib/layui-2.7.0/css/layui.css" rel="stylesheet"><link href="/lib/wangeditor/style.css" rel="stylesheet"><style></style>
</head><body><div><!-- 工具栏 --><div id="toolbar-container"></div><!-- 编辑器 --><div id="editor-container"></div></div><script src="/lib/layui-2.7.0/layui.js"></script><script src="/lib/wangeditor/index.js"></script><script></script>
</body></html>
  • 创建编辑器(主要是 JS 代码实现)
<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="x-ua-compatible" content="ie=edge"><meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"><title>Page title</title><link href="/lib/layui-2.7.0/css/layui.css" rel="stylesheet"><link href="/lib/wangeditor/style.css" rel="stylesheet"><style>body {padding: 20px;}</style>
</head><body><div style="border: 1px solid #e1e1e1;"><!-- 工具栏 --><div id="toolbar-container" style="border-bottom: 1px solid #e1e1e1;"></div><!-- 编辑器 --><div id="editor-container" style="height: 400px;"></div></div><script src="/lib/layui-2.7.0/layui.js"></script><script src="/lib/wangeditor/index.js"></script><script>const {createEditor,createToolbar} = window.wangEditor;// 编辑器配置const editorConfig = {};editorConfig.placeholder = '请输入内容';// 工具栏配置const toolbarConfig = {};// 创建编辑器const editor = createEditor({selector: '#editor-container',config: editorConfig,mode: 'default'});// 创建工具栏const toolbar = createToolbar({editor,selector: '#toolbar-container',config: toolbarConfig,mode: 'default'});</script>
</body></html>

至此 wangEditor 编辑器已经创建成功了。刷新页面后,就可以看到和官网一样界面效果了。

wangEditor 实现 word 带图片格式内容粘贴

场景描述

  • 新建一个 word 文档,并输入常规内容,如带样式的文本内容、列表、表格,并插入图片,然后选中复制;
  • 打开上面创建的编辑器页面,点击编辑器输入区域,然后 ctrl+v 粘贴。

结果: 文字样式部分丢失,表格尚可,列表溢出,图片直接丢失。

分析思路

针对上面的实践结果,逐个寻找解决方案:

  • 样式丢失

    • 体现:如文本样式部分丢失、列表溢出等。

    • 为什么会丢失呢?

      • 这个问题其实很容易回答,word 中的文本样式肯定与我们平时写的 HTML 样式有差异,会导致样式丢失。

      • 另外一方面,我们平时写的 HTML 格式非常灵活,但是 wangEditor 无法兼容所有的 HTML 格式,这一点官方文档有特别标红说明。也就是说,我们在编辑器输入内容时,wangEdior 会做一些处理(过滤,筛选,转换等)。

      例如,wangEditor 可以识别 <strong>hello</strong> 为加粗,但无法识别 <span style="font-weight: bold;">hello</span> 等其他加粗方式。

    • 解决措施

      • 了解差异,对内容样式做额外的处理,使其尽量符合 wangEditor 支持的格式。
      • 代码实践(这只是我的思路,你还可以有更好的实现思路~~)
      // 例如缩进会超出边框,直接过滤掉相关样式即可
      html = html.replace(/text\-indent:\-(.*?)pt/gi, '')
      
  • 图片丢失

    • 为什么丢失呢?
      这个问题比较复杂,需要我们先了解复制粘贴的原理,真是情况和我们想的完全不一样,它不是简单的把 A 的内容作为一个整体一次性复制到编辑器中,而是将 A 的内容中图片的标签和图片的内容(数据)分成两部分分别以不同方式传输。此处简单说明一下,下面关键点部分做详细介绍。
    • 解决措施
      其实思路很清晰,就是我们将图片的内容复制到编辑器中,而且还可以正常显示。这块比较复杂,此处只做个概念介绍,,下面关键点部分做详细介绍。

关键点:图片如何粘贴

【开门见山】

通过 wangEditor 的编辑器配置 API 中的 customPaste 自定义粘贴

通过该 API 可以阻止编辑器的默认粘贴处理逻辑,可以实现自己的粘贴逻辑。

即:这里的自己的粘贴逻辑,就是解决图片粘贴的关键所在。

~~原来,其实道理就这么简单!!

最终实现代码(因为仅涉及 JS 代码,所以只提供 JS 代码)

  • 自定义 wangEditor 粘贴
// 其他代码
....<script>const {createEditor,createToolbar} = window.wangEditor;// 编辑器配置const editorConfig = {};editorConfig.placeholder = '请输入内容';// 自定义粘贴editorConfig.customPaste = (editor, event) => {// 获取粘贴的html部分(??没错粘贴word时候,一部分内容就是html),该部分包含了图片img标签let html = event.clipboardData.getData('text/html');// 获取rtf数据(从word、wps复制粘贴时有),复制粘贴过程中图片的数据就保存在rtf中const rtf = event.clipboardData.getData('text/rtf');if (html && rtf) { // 该条件分支即表示要自定义word粘贴// 列表缩进会超出边框,直接过滤掉html = html.replace(/text\-indent:\-(.*?)pt/gi, '')// 从html内容中查找粘贴内容中是否有图片元素,并返回img标签的属性src值的集合const imgSrcs = findAllImgSrcsFromHtml(html);// 如果有if (imgSrcs && Array.isArray(imgSrcs) && imgSrcs.length) {// 从rtf内容中查找图片数据const rtfImageData = extractImageDataFromRtf(rtf);// 如果找到if (rtfImageData.length) {// TODO:此处可以将图片上传到自己的服务器上// 执行替换:将html内容中的img标签的src替换成ref中的图片数据,如果上面上传了则为图片路径html = replaceImagesFileSourceWithInlineRepresentation(html, imgSrcs, rtfImageData)editor.dangerouslyInsertHtml(html);}}// 阻止默认的粘贴行为event.preventDefault();return false;} else {return true;}}// 工具栏配置const toolbarConfig = {};// 创建编辑器const editor = createEditor({selector: '#editor-container',config: editorConfig,mode: 'default'});// 创建工具栏const toolbar = createToolbar({editor,selector: '#toolbar-container',config: toolbarConfig,mode: 'default'});
</script>
.....
// 其他代码
  • 工具函数(上面的代码中有用到)
<script>
/*** 从html代码中匹配返回图片标签img的属性src的值的集合* @param htmlData* @return Array*/
function findAllImgSrcsFromHtml(htmlData) {let imgReg = /<img.*?(?:>|\/>)/gi; //匹配图片中的img标签let srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i; // 匹配图片中的srclet arr = htmlData.match(imgReg); //筛选出所有的imgif (!arr || (Array.isArray(arr) && !arr.length)) {return false;}let srcArr = [];for (let i = 0; i < arr.length; i++) {let src = arr[i].match(srcReg);// 获取图片地址srcArr.push(src[1]);}return srcArr;
}/*** 从rtf内容中匹配返回图片数据的集合* @param rtfData* @return Array*/
function extractImageDataFromRtf(rtfData) {if (!rtfData) {return [];}const regexPictureHeader = /{\\pict[\s\S]+?({\\\*\\blipuid\s?[\da-fA-F]+)[\s}]*/const regexPicture = new RegExp('(?:(' + regexPictureHeader.source + '))([\\da-fA-F\\s]+)\\}', 'g');const images = rtfData.match(regexPicture);const result = [];if (images) {for (const image of images) {let imageType = false;if (image.includes('\\pngblip')) {imageType = 'image/png';} else if (image.includes('\\jpegblip')) {imageType = 'image/jpeg';}if (imageType) {result.push({hex: image.replace(regexPictureHeader, '').replace(/[^\da-fA-F]/g, ''),type: imageType});}}}return result;
}/*** 将html内容中img标签的属性值替换* @param htmlData html内容* @param imageSrcs html中img的属性src的值的集合* @param imagesHexSources rtf中图片数据的集合,与html内容中的img标签对应* @param isBase64Data 是否是Base64的图片数据* @return String*/
function replaceImagesFileSourceWithInlineRepresentation(htmlData, imageSrcs, imagesHexSources, isBase64Data =true) {if (imageSrcs.length === imagesHexSources.length) {for (let i = 0; i < imageSrcs.length; i++) {const newSrc = isBase64Data ?`data:${imagesHexSources[i].type};base64,${_convertHexToBase64(imagesHexSources[i].hex)}` :imagesHexSources[i];htmlData = htmlData.replace(imageSrcs[i], newSrc);}}return htmlData;
}/*** 十六进制转base64*/
function _convertHexToBase64(hexString) {return btoa(hexString.match(/\w{2}/g).map(char => {return String.fromCharCode(parseInt(char, 16));}).join(''));
}
</script>

总结

  1. 本文基本上完美实现了从 word 复制粘贴图片的需求。

  2. 至于样式部分丢失的问题,目前不可能 100%解决,wangEditor 本身解析内容的原理导致,就目前而言,只能尽可能对损失或丢失的样式做一些额外的处理,使其接近复制粘贴的预期。

wangEditor 粘贴从 word 复制的带图片内容的最佳实践相关推荐

  1. 集群应用服务器环境中会话管理(复制)的Oracle Coherence最佳实践

    Oracle Coherence是一种内存中数据网格产品,也广泛用于跨应用程序服务器节点集群的会话复制. 它支持各种应用程序服务器,例如WebLogic,WebSphere,Tomcat,JBoss等 ...

  2. wangEditor富文本编辑器的调用开发实录2(V5版本自定义粘贴,去除复制word或网页html冗余样式代码的解决方案)

    wangEditor富文本编辑器:自定义粘贴,去除复制word或网页html冗余样式代码的解决方案 1.环境说明 2.解决方案 3.完整代码 总结 在使用wangEditor富文本编辑器时,当从wor ...

  3. wangEditor粘贴word图片问题解决

    1.4.2之后官方并没有做功能的改动,1.4.2在word复制这块没有bug,其他版本会出现手动无法转存的情况 本文使用的后台是Java.前端为Jsp(前端都一样,后台如果语言不通得自己做 Base6 ...

  4. 富文本编辑器从word复制粘贴图片

    1.4.2之后官方并没有做功能的改动,1.4.2在word复制这块没有bug,其他版本会出现手动无法转存的情况 本文使用的后台是Java.前端为Jsp(前端都一样,后台如果语言不通得自己做 Base6 ...

  5. 怎样将GIS图形复制到Windows剪贴板,粘贴到Word中

    很久没写随笔了,有点想关了这个博客,不再更新,但还是没有下定决心.趁这些天比较闲,发一个以前写着玩的功能吧.     复制.粘贴功能是一件很简单的事情,但怎样将GIS图形粘贴到word中呢?最简单的思 ...

  6. excel表格如何转换成word表格_将excel/word数据复制粘贴到word表格的几种方式

    将excel/word数据复制粘贴到word表格的几种方式 有时候我们需要把excel中的数据粘贴到word中的一个表格中,或者在word中一个表格的内容粘贴到另一个表格中.这两种情况,都遵循同样的操 ...

  7. 如何美观的把SPSS统计结果复制粘贴到Word文档中?

    我们用SPSS做统计分析后,通常会摘取一部分结果放入Word文档中,比如你写科研论文,会把方差分析表.误差条形图这些结果粘贴到Word文档中进行统一编辑. 文字.表格.图形的组合,这是Word基本操作 ...

  8. 轻松从Word复制身份证号码粘贴到Excel

    Excel 2021 中文版是目前市面上最火爆的一款报表企业办公数据处理方法专用工具,Excel2021有着着全新升级的软件页面,作用更为强劲,适用开展各种各样数据信息的解决.数据分析和輔助管理决策实 ...

  9. mathtype 复制粘贴到word中公式显示不全的问题解决方法

    mathtype 复制粘贴到word中公式显示不全的问题解决方法 由于论文模板中的段落行距设置成了固定值,而复制的公式纵向过长,仅能显示固定值设定的磅值区域. 解决办法为选定该公式,格式-段落-行距- ...

  10. 从网页复制的文字粘贴到Word间距变大_知汇Zhhuu - 电脑知识技巧 - 傲游云浏览器 (RC) 4.0.3.3000...

    从网页复制的文字粘贴到Word间距变大 时间:2011-01-29来源:Zhhuu 作者:Zhhuu 点击:1247次 问:在网页上复制了一部分文字,然后粘贴在Word 2003中,可是在段与段之间的 ...

最新文章

  1. MSSQL 2000 错误823恢复数据案例
  2. Longest Substring Without Repeating Characters(最长不重复子序列求解)
  3. python文本解析_如何通过python进行文本解析?
  4. P3605 [USACO17JAN]Promotion Counting P dfs序
  5. c# java gt;gt;gt;,C#的相当于Java的&LT ;?扩展底座&GT;在仿制药
  6. 《Flutter 从0到1构建大前端应用》读后感—第4章【事件处理】
  7. 随手练——O(n)解决无序数组排序后的相邻最大差值
  8. 会说话的PPT,从开发者角度十分钟理解区块链
  9. UG工程图自动标注工具 64位 版本无限制
  10. 银行网站 ca服务器的安装,建行网银CA认证系统建设案例介绍
  11. Kaldi的安装与测试
  12. 仿射变换affine和透视变换
  13. android微信刷脸支付宝,录指纹、敲密码太麻烦,OPPO Find X完成安卓首个微信刷脸支付...
  14. Sublime Text 全程图文指引
  15. 好用的磁盘管理工具:DiskCatalogMaker for Mac
  16. 软件测试中用正交实验法设计测试用例
  17. div标签,h标签,p标签,hr标签
  18. java udp nio_Java NIO UDP DEMO
  19. Istio服务网格实践指南 学习笔记(二) Istio架构
  20. Win10 家庭版中启用组策略

热门文章

  1. linux上mysql定时备份数据库数据_linux下如何实现mysql数据库每天自动备份定时备份...
  2. 总结 27 类深度学习主要神经网络:结构图及应用
  3. Codeforces Round #469 (Div. 1 A-E)
  4. java.io.IOException: Type mismatch in key from map: expected org.apache.hadoop.io.Text, recieved org
  5. 电影评论画像制作(豆瓣肖申克的救赎为例)
  6. 当冬日阳光照耀我孤苦的心怀
  7. graphpad两组t检验_Graphpad Prism如何科学地选择统计学方法
  8. date类型在日期增加或者减少几天
  9. 安防视频监控直播的画面都是如何采集的?
  10. iOS开发常用设计模式