news 2026/5/19 1:57:06

TinyMCE5实现ppt动画效果转html兼容处理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TinyMCE5实现ppt动画效果转html兼容处理

作为一名苦逼的大三软件工程狗,我来分享下Word转存功能的血泪史

各位老铁们好啊!我是一名来自重庆某高校的软件工程大三学生,最近在折腾一个CMS新闻管理系统的升级,特别是那个让人头秃的Word内容粘贴功能。下面我就来分享下我的探索历程和解决方案,希望能帮到和我一样在坑里挣扎的兄弟们!

功能需求分析

首先说说我这个项目的需求吧:

  1. 要在TinyMCE编辑器加个按钮,支持Word/Excel/PPT/PDF内容粘贴
  2. 粘贴后要保留所有样式(表格、字体、公式啥的)
  3. 图片要自动上传到阿里云OSS
  4. 公式要支持Latex转MathML,还要多终端高清显示
  5. 预算只有99元(学生党穷啊!)

技术选型踩坑记

我试过一堆方案,这里给大家排排雷:

  1. TinyMCE官方插件:贵的要死,直接pass
  2. 各种开源库:要么功能不全,要么文档看不懂
  3. 自己撸代码:试了一周,头发掉了不少,效果还稀烂

最后找到了一个性价比超高的方案——Mammoth.js+自定义插件,总花费:0元!白嫖真香!

完整解决方案

前端部分(Vue2)

首先安装依赖:

npminstallmammoth vue-tinymce tinymce

然后在组件中集成:

importtinymcefrom'tinymce/tinymce'import'tinymce/themes/silver'import'tinymce/plugins/paste'import'tinymce/plugins/image'importEditorfrom'@tinymce/tinymce-vue'import*asmammothfrom'mammoth'exportdefault{components:{'tinymce-editor':Editor},data(){return{content:'',editorInit:{height:500,menubar:false,plugins:'paste image',toolbar:'undo redo | formatselect | bold italic | alignleft aligncenter alignright | image',images_upload_handler:this.handleImageUpload}}},methods:{asynchandlePasteFromWord(){constinput=document.createElement('input')input.type='file'input.accept='.docx,.doc'input.onchange=asynce=>{constfile=e.target.files[0]constarrayBuffer=awaitfile.arrayBuffer()constresult=awaitmammoth.extractRawText({arrayBuffer})consthtml=awaitmammoth.convertToHtml({arrayBuffer})// 处理图片上传constprocessedHtml=awaitthis.processImages(html.value)this.content=processedHtml}input.click()},asyncprocessImages(html){// 这里用正则提取图片base64并上传到OSS// 返回替换后的HTMLreturnhtml.replace(/<img[^>]+src="data:image\/([^;]+);base64,([^"]+)"[^>]*>/g,async(match,ext,base64)=>{constimageUrl=awaitthis.uploadBase64Image(base64,ext)returnmatch.replace(`data:image/${ext};base64,${base64}`,imageUrl)})},asyncuploadBase64Image(base64,ext){// 这里实现上传到阿里云OSS的逻辑// 返回图片URLreturn'https://your-oss-bucket.oss-cn-shenzhen.aliyuncs.com/xxx.jpg'},handleImageUpload(blobInfo,success,failure){// TinyMCE图片上传处理constfile=blobInfo.blob()this.uploadToOSS(file).then(url=>{success(url)}).catch(err=>{failure('上传失败')})},asyncuploadToOSS(file){// 阿里云OSS上传实现// 返回图片URL}}}.word-paste-btn{margin-top:10px;padding:8px 16px;background:#1890ff;color:white;border:none;border-radius:4px;cursor:pointer;}

后端部分(PHP)

putObject($bucket,$filename,$data);$url="https://{$bucket}.{$endpoint}/{$filename}";echojson_encode(['url'=>$url]);exit;}// 处理普通文件上传if(isset($_FILES['file'])){$file=$_FILES['file'];$filename='uploads/'.uniqid().'.'.pathinfo($file['name'],PATHINFO_EXTENSION);$ossClient->uploadFile($bucket,$filename,$file['tmp_name']);$url="https://{$bucket}.{$endpoint}/{$filename}";echojson_encode(['url'=>$url]);exit;}thrownewException('无效的请求');}catch(OssException$e){http_response_code(500);echojson_encode(['error'=>$e->getMessage()]);}?>

公式处理方案

对于Latex公式转换,我推荐使用MathJax

// 在TinyMCE初始化配置中加入 extended_valid_elements: 'math,annotation,menclose,merror,mfenced,mfrac,mfrac,mi,mmultiscripts,mn,mo,mover,mpadded,mphantom,mroot,mrow,ms,mscarries,mscarry,msgroup,mstack,msline,mspace,msqrt,msrow,mstyle,msub,msubsup,msup,mtable,mtd,mtext,mtr,munder,munderover,semantics', content_style: 'math {display: inline;}', setup: function(editor) { editor.on('init', function() { if (window.MathJax) { window.MathJax.Hub.Config({ tex2jax: { inlineMath: [['$','$'], ['\$','\$']], displayMath: [['$$','$$'], ['\$$','\$$']], processEscapes: true }, "HTML-CSS": { availableFonts: ["TeX"], linebreaks: { automatic: true } } }); } }); }

部署注意事项

  1. 跨域问题:记得在阿里云OSS设置CORS规则
  2. 权限控制:使用STS临时凭证更安全
  3. 性能优化:图片可以压缩后再上传
  4. 错误处理:做好各种异常情况的处理

加入我们的技术交流群

兄弟们,一个人撸代码太苦了!我们建了个QQ群(223813913),里面有很多像我一样的苦逼开发者,大家互相帮助,分享开源项目和接单资源。新人加群还有红包哦!

群里最近搞了个代理商活动,推荐客户能拿20%提成。算笔账:

  • 推1单1000元 = 200元到手
  • 推10单 = 2000元
  • 一个月推50单 = 1万元

比去公司996舒服多了!快来加入我们吧!

求职求内推

最后打个广告:有师兄师姐需要招人的吗?小弟我快毕业了,求个内推机会!熟悉Vue/PHP/MySQL,能吃苦耐劳,薪资要求不高,管饭就行!

希望能帮到有同样需求的兄弟,代码我都在实际项目用过,有问题随时群里交流!

复制插件

安装jquery

npm install jquery

在组件中引入

// 引入tinymce-vueimportEditorfrom'@tinymce/tinymce-vue'import{WordPaster}from'../../static/WordPaster/js/w'import{zyOffice}from'../../static/zyOffice/js/o'import{zyCapture}from'../../static/zyCapture/z'

添加工具栏

//添加导入excel工具栏按钮(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor).importExcel()}varregister$1=function(editor){editor.ui.registry.addButton('excelimport',{text:'',tooltip:'导入Excel文档',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('excelimport',{text:'',tooltip:'导入Excel文档',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('excelimport',function(editor){Buttons.register(editor);});}Plugin();}());//添加word转图片工具栏按钮(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor);WordPaster.getInstance().importWordToImg()}varregister$1=function(editor){editor.ui.registry.addButton('importwordtoimg',{text:'',tooltip:'Word转图片',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('importwordtoimg',{text:'',tooltip:'Word转图片',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('importwordtoimg',function(editor){Buttons.register(editor);});}Plugin();}());//添加粘贴网络图片工具栏按钮(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor);WordPaster.getInstance().UploadNetImg()}varregister$1=function(editor){editor.ui.registry.addButton('netpaster',{text:'',tooltip:'网络图片一键上传',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('netpaster',{text:'',tooltip:'网络图片一键上传',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('netpaster',function(editor){Buttons.register(editor);});}Plugin();}());//添加导入PDF按钮(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor);WordPaster.getInstance().ImportPDF()}varregister$1=function(editor){editor.ui.registry.addButton('pdfimport',{text:'',tooltip:'导入pdf文档',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('pdfimport',{text:'',tooltip:'导入pdf文档',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('pdfimport',function(editor){Buttons.register(editor);});}Plugin();}());//添加导入PPT按钮(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor);WordPaster.getInstance().importPPT()}varregister$1=function(editor){editor.ui.registry.addButton('pptimport',{text:'',tooltip:'导入PowerPoint文档',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('pptimport',{text:'',tooltip:'导入PowerPoint文档',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('pptimport',function(editor){Buttons.register(editor);});}Plugin();}());//添加导入WORD按钮(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor).importWord()}varregister$1=function(editor){editor.ui.registry.addButton('wordimport',{text:'',tooltip:'导入Word文档',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('wordimport',{text:'',tooltip:'导入Word文档',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('wordimport',function(editor){Buttons.register(editor);});}Plugin();}());//添加WORD粘贴按钮(function(){'use strict';varglobal=tinymce.util.Tools.resolve('tinymce.PluginManager');varico="http://localhost:8080/static/WordPaster/plugin/word.png"functionselectLocalImages(editor){WordPaster.getInstance().SetEditor(editor).PasteManual()}varregister$1=function(editor){editor.ui.registry.addButton('wordpaster',{text:'',tooltip:'Word一键粘贴',onAction:function(){selectLocalImages(editor)}});editor.ui.registry.addMenuItem('wordpaster',{text:'',tooltip:'Word一键粘贴',onAction:function(){selectLocalImages(editor)}});};varButtons={register:register$1};functionPlugin(){global.add('wordpaster',function(editor){Buttons.register(editor);});}Plugin();}());

在线代码:

添加插件

// 插件plugins:{type:[String,Array],// default: 'advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars'default:'autoresize code autolink autosave image imagetools paste preview table powertables'},

点击查看在线代码

初始化组件

// 初始化WordPaster.getInstance({// 上传接口:http://www.ncmem.com/doc/view.aspx?id=d88b60a2b0204af1ba62fa66288203edPostUrl:'http://localhost:8891/upload.aspx',// 为图片地址增加域名:http://www.ncmem.com/doc/view.aspx?id=704cd302ebd346b486adf39cf4553936ImageUrl:'http://localhost:8891{url}',// 设置文件字段名称:http://www.ncmem.com/doc/view.aspx?id=c3ad06c2ae31454cb418ceb2b8da7c45FileFieldName:'file',// 提取图片地址:http://www.ncmem.com/doc/view.aspx?id=07e3f323d22d4571ad213441ab8530d1ImageMatch:''})

在页面中引入组件

功能演示

编辑器

在编辑器中增加功能按钮

导入Word文档,支持doc,docx

导入Excel文档,支持xls,xlsx

粘贴Word

一键粘贴Word内容,自动上传Word中的图片,保留文字样式。

Word转图片

一键导入Word文件,并将Word文件转换成图片上传到服务器中。

导入PDF

一键导入PDF文件,并将PDF转换成图片上传到服务器中。

导入PPT

一键导入PPT文件,并将PPT转换成图片上传到服务器中。

上传网络图片

一键自动上传网络图片。

下载示例

点击下载完整示例

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/9 17:54:46

PyTorch-CUDA镜像能否用于电梯智能调度

PyTorch-CUDA镜像能否用于电梯智能调度 在现代高层建筑中&#xff0c;电梯不再只是简单的垂直运输工具——它正逐渐演变为一个需要实时决策、动态响应的复杂系统。每天早晚高峰时&#xff0c;人们挤在大厅等待电梯&#xff0c;而控制系统却仍在用几十年前的“就近响应”逻辑派梯…

作者头像 李华
网站建设 2026/5/16 11:54:17

从GitHub克隆项目后如何激活PyTorch虚拟环境?

从GitHub克隆项目后如何激活PyTorch虚拟环境&#xff1f; 在深度学习项目开发中&#xff0c;你是否曾遇到这样的场景&#xff1a;刚从 GitHub 克隆了一个热门的 PyTorch 项目&#xff0c;满怀期待地运行 python train.py&#xff0c;结果却抛出一连串错误——“No module named…

作者头像 李华
网站建设 2026/5/13 17:07:41

10个AI论文软件推荐,继续教育学生轻松搞定毕业论文!

10个AI论文软件推荐&#xff0c;继续教育学生轻松搞定毕业论文&#xff01; AI 工具助力论文写作&#xff0c;让学术之路更轻松 在当今信息化时代&#xff0c;AI 技术已经渗透到各行各业&#xff0c;教育领域也不例外。对于继续教育的学生而言&#xff0c;撰写毕业论文是一项…

作者头像 李华
网站建设 2026/5/1 6:34:26

网络安全完全指南:从小白到黑客必学的10大防范技术(建议收藏)

一、引言 在当今数字化的时代&#xff0c;网络已经成为人们生活和工作中不可或缺的一部分。然而&#xff0c;随着网络的普及和应用的广泛&#xff0c;网络安全问题也日益凸显。从个人隐私泄露到企业关键信息被盗&#xff0c;从网络欺诈到大规模的网络攻击&#xff0c;网络安全…

作者头像 李华
网站建设 2026/5/11 18:14:48

通达信天狼操盘 源码 贴图

{}X_1:REF(CLOSE,1); X_2:SMA(MAX(CLOSE-X_1,0),3,1)/SMA(ABS(CLOSE-X_1),3,1)*100; X_3:EMA(CLOSE,3); X_4:EMA(CLOSE,21); 波动回调提示图:MA(CLOSE,10000); STICKLINE(X_4>REF(X_4,1),X_4,X_4,5,1),COLORRED,LINETHICK2; STICKLINE(X_4<REF(X_4,1),X_4,X_4,5,1),COLOR…

作者头像 李华
网站建设 2026/5/16 21:45:13

涉密行业首选!MonkeyCode 离线私有化 AI 编程解决方案

代码安全与效率协同&#xff1a;MonkeyCode企业级AI编程私有化解决方案解析 在AI编程工具广泛应用的当下&#xff0c;代码安全与数据隐私已成为企业研发的核心关切点。MonkeyCode作为长亭科技推出的开源企业级AI编程辅助平台&#xff0c;以“私有化部署为核心、安全管控为支撑…

作者头像 李华