前言
最近在做一个需求需要用到富文本编辑器,于是选择了tinymce
。不得不说,这个编辑器真的很强大,应有尽有。
粘贴Excel表格
验收的时候,需求方反馈,粘贴表格内容时,样式会丢失。
Excel中看到的是这样的:
粘贴到富文本编辑器中,会变成这样:
经过查询相关资料,powerpaste插件可以实现这样的功能,效果如下:
但是需要注意的是,powerpaste这款插件==是收费的==。
自己实现
如果不使用这个插件,我们有什么思路可以实现呢?
查了相关的文档,发现tinymce有一个paste_preprocess
的回调,可以让你在插入内容之前对内容进行处理:
tinymce.init({
selector: "textarea", // change this value according to your HTML
plugins: "paste",
menubar: "edit",
toolbar: "paste",
paste_preprocess: function(plugin, args) {
console.log(args.content);
}
});
通过查看粘贴的内容,发现如果是使用paste
插件,content的内容长这样:
<table border=0 cellpadding=0 cellspacing=0 width=965 height=222 style='border-collapse:collapse;width:723.77pt;'>
<col width=52 style='width:39.00pt;'>
<col width=93 style='width:69.75pt;'>
<col width=85 style='width:63.75pt;' span=4>
<col width=96 style='width:72.00pt;' span=5>
<tr height=57 style='height:42.75pt;'>
<td class=et3 height=57 width=52 x:str style='height:42.75pt;width:39.00pt;'>学号</td>
<td class=et4 width=93 x:str style='width:69.75pt;'>学生姓名</td>
<td class=et4 width=85 x:str style='width:63.75pt;'>上午签到</td>
<td class=et4 width=85 x:str style='width:63.75pt;'>上午签退</td>
<td class=et4 width=85 x:str style='width:63.75pt;'>下午签到</td>
<td class=et4 width=85 x:str style='width:63.75pt;'>下午签退</td>
<td class=et5 width=96 x:str style='width:72.00pt;'>全勤<br>(天)</td>
<td class=et5 width=96 x:str style='width:72.00pt;'>请假<br>(天)</td>
<td class=et5 width=96 x:str style='width:72.00pt;'>迟到<br>(次)</td>
<td class=et5 width=96 x:str style='width:72.00pt;'>早退<br>(次)</td>
<td class=et5 width=96 x:str style='width:72.00pt;'>旷课<br>(次)</td>
</tr>
<tr height=41 style='height:30.95pt;'>
<td class=et6 height=41 x:num="1" style='height:30.95pt;'>1</td>
<td class=et6 x:str>张XX</td>
<td class=et6 x:str>√</td>
<td class=et6 x:str>√</td>
<td class=et6 x:str>√</td>
<td class=et6 x:str>√</td>
<td class=et6 x:num="1">1</td>
<td class=et6 x:num="0">0</td>
<td class=et6 x:num="0">0</td>
<td class=et6 x:num="0">0</td>
<td class=et6 x:num="0">0</td>
</tr>
<tr height=41 style='height:30.95pt;'>
<td class=et6 height=41 x:num="2" style='height:30.95pt;'>2</td>
<td class=et6 x:str>李XX</td>
<td class=et6 x:str>请假</td>
<td class=et6 x:str>请假</td>
<td class=et6 x:str>√</td>
<td class=et6 x:str>√</td>
<td class=et6 x:num="0.5">0.5</td>
<td class=et6 x:num="0.5">0.5</td>
<td class=et6 x:num="0">0</td>
<td class=et6 x:num="0">0</td>
<td class=et6 x:num="0">0</td>
</tr>
<tr height=41 style='height:30.95pt;'>
<td class=et6 height=41 x:num="3" style='height:30.95pt;'>3</td>
<td class=et6 x:str>赵XX</td>
<td class=et6 x:str>√</td>
<td class=et6 x:str>√</td>
<td class=et6 x:str>旷课</td>
<td class=et6 x:str>旷课</td>
<td class=et6 x:num="0.5">0.5</td>
<td class=et6 x:num="0">0</td>
<td class=et6 x:num="0">0</td>
<td class=et6 x:num="0">0</td>
<td class=et6 x:num="1">1</td>
</tr>
<tr height=41 style='height:30.95pt;'>
<td class=et6 height=41 x:num="4" style='height:30.95pt;'>4</td>
<td class=et6 x:str>李XX</td>
<td class=et6 x:str>√</td>
<td class=et6 x:str>√</td>
<td class=et6 x:str>√</td>
<td class=et6 x:str>√</td>
<td class=et6 x:num="1">1</td>
<td class=et6 x:num="0">0</td>
<td class=et6 x:num="0">0</td>
<td class=et6 x:num="0">0</td>
<td class=et6 x:num="0">0</td>
</tr>
</table>
然而换成powerpaste
,内容长这样:
根据以上的区别可以猜测,使用powerpaste
插件之后,把class的内容解析到了style属性里,从而达到了保持样式的作用。
那我们怎么去获取这些样式内容呢?
于是,我尝试监听了粘贴事件,看看能拿到什么内容:
document.addEventListener("paste", (e) => {
const htmlData = e.clipboardData.getData('text/html')
console.log(htmlData)
});
查看了打印的内容,可以发现,这样取到的数据,是一个完整的html文档,其中包含了style的信息:
既然如此,我们可以通过对这份内容进行解析 然后将style中的内容,根据class整合样式,就可以拿到我们想要的内容了。
总结
Tinymce还是很强大的,如果想要在粘贴Excel的时候保持表格样式,我们可以直接使用powerpaste
插件代替默认的paste
,从而达到我们的目的。
实在不行,需要自己去实现这个功能,我们也可以通过监听粘贴事件拿到原始内容,并对其进行解析处理,最后生成带样式的html内容。
以上,是在使用tinymce过程中的一些总结和思考,欢迎交流。