南阳市网站建设_网站建设公司_自助建站_seo优化
2025/12/28 14:00:48 网站建设 项目流程

CMS企业官网编辑器扩展开发记录

需求分析与技术评估

作为上海的一名PHP全栈开发者,我最近接手了一个CMS企业官网的外包项目。客户提出了一项新需求:在TinyMCE 5编辑器中增加Office文档导入和一键粘贴功能。

核心需求点:

  1. 支持Word/Excel/PPT/PDF文档导入
  2. 支持微信公众号内容导入
  3. 保留完整样式和特殊内容(公式、图表等)
  4. 自动上传媒体文件到阿里云OSS
  5. 预算控制在99元以内
  6. 以插件形式集成,不影响现有功能

技术调研过程

第一阶段:开源方案评估

首先我评估了市面上常见的开源解决方案:

  1. TinyMCE Paste插件

    • 优点:原生支持,集成简单
    • 缺点:对复杂格式支持有限,无法处理emz/wmz公式
  2. CKEditor文档导入插件

    • 优点:文档处理能力较强
    • 缺点:需要切换编辑器,迁移成本高
  3. Mammoth.js

    • 优点:专门处理.docx文件
    • 缺点:仅支持Word,不处理其他格式
  4. OfficeToHtml

    • 优点:多格式支持
    • 缺点:样式保留不完整,公式支持差
  5. 泽优WordPaster

    • 优点:完全开源(下载源码)
    • 全平台支持
    • 缺点:需要终端安装插件

结论:现有开源方案无法完全满足客户需求,特别是对emz/wmz公式和Latex的支持。

第二阶段:商业方案调研

考虑到预算限制(99元以内),我重点考察了以下商业方案:

  1. TinyMCE PowerPaste插件($80):

    • 支持Word/Excel粘贴
    • 保留基本样式
    • 不支持PPT/PDF导入
    • 公式支持有限
  2. OnlyOffice文档转换服务(免费版):

    • API方式集成
    • 转换质量高
    • 需要额外服务器资源
  3. 阿里云文档转换服务(按量付费):

    • 与现有OSS无缝集成
    • 转换效果良好
    • 长期使用可能超预算
  4. 泽优WordPaster(企业版):

    • 与现有OSS无缝集成
    • 转换效果良好
    • 全功能支持(word,excel,ppt,pdf,latex公式)

决策:选择泽优WordPaster 企业版作为基础,配合自定义开发解决其不足。

技术方案设计

前端架构

基于现有Vue2 CLI环境,采用以下架构:

|- src/ |- components/ |- Editor/ |- TinyMCE.vue # 主编辑器组件 |- plugins/ |- powerpaste/ # PowerPaste插件 |- officeimport/ # 自定义文档导入插件

后端处理流程

OSSAliyunBackendFrontendOSSAliyunBackendFrontend上传文档(FormData)调用文档转换服务返回HTML内容上传媒体文件返回处理后的HTML

关键问题解决方案

  1. 公式支持

    • 使用MathJax渲染Latex公式
    • 对emz/wmz格式,开发转换器转为SVG
  2. 样式保留

    • 定制CSS映射规则,将Word样式转换为web安全样式
  3. 微信公众号内容

    • 开发专用清理器,去除公众号特有标签

开发实施

环境准备

# 安装PowerPaste插件npminstalltinymce-powerpaste@5# 添加阿里云SDKcomposerrequire alibabacloud/sdk

核心代码实现

前端插件注册(TinyMCE.vue)

importPowerPastefrom'tinymce-powerpaste'exportdefault{methods:{initEditor(){tinymce.init({selector:'#editor',plugins:'powerpaste officeimport',toolbar:'pasteword | importoffice',powerpaste_word_import:'merge',powerpaste_html_import:'merge',officeimport_callback:this.handleOfficeImport})}}}

PHP文档处理服务

classDocumentImportService{publicfunctionhandleUpload($file){$client=newAliyunClient();$result=$client->convertDocument($file);$html=$this->processContent($result['html']);$this->uploadMediaFiles($result['media']);return$html;}privatefunctionprocessContent($html){// 处理公式转换$html=$this->convertFormulas($html);// 清理公众号特有内容if(strpos($html,'mp.weixin.qq.com')){$html=$this->cleanWechatContent($html);}return$html;}}

测试验证

  1. Word文档测试

    • 验证样式保留程度
    • 检查公式渲染效果
    • 测试表格转换准确性
  2. 微信公众号测试

    • 验证图片自动上传
    • 检查多余标签清理
  3. 性能测试

    • 大文档处理时间
    • 内存占用监控

部署方案

阿里云OSS配置

[oss] access_key_id = your_key access_key_secret = your_secret endpoint = oss-cn-shanghai.aliyuncs.com bucket = your_bucket

服务器优化

# 增加上传大小限制 client_max_body_size 20M; # 优化PHP执行时间 fastcgi_read_timeout 300;

项目总结

成果

  1. 在预算内(总计$80+¥15阿里云费用)完成了需求
  2. 实现了所有文档类型的导入
  3. 完美支持公式和复杂样式

待优化

  1. 超大PPT文件转换速度较慢
  2. 某些特殊Word艺术字转换不理想

客户反馈

“新功能大大简化了我们的内容发布流程,特别是对不熟悉技术的编辑人员非常友好。公式支持完全满足了我们的教学资料发布需求。”


后续计划:将这套解决方案封装为独立插件,考虑在技术社区开源基础版本。

复制插件

安装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转换成图片上传到服务器中。

上传网络图片

一键自动上传网络图片。

下载示例

点击下载完整示例

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询