CMS企业官网项目 - 编辑器Word导入功能集成记录
需求分析
作为四川的一名PHP程序员,最近接手的CMS企业官网项目客户提出了一个新需求:在CKEditor 4编辑器中实现Word等文档的一键导入功能。具体要求包括:
- 支持Word/Excel/PPT/PDF文档导入
- 支持微信公众号内容粘贴
- 保留原始文档样式(字体、字号、颜色、表格、公式等)
- 自动上传图片到阿里云OSS
- 以插件形式扩展,不影响现有功能
- 预算控制在99元以内
技术评估与选型
现有技术栈
- 前端:Vue2 CLI + CKEditor 4
- 后端:PHP (Zend Studio开发环境)
- 数据库:MySQL
- 云存储:阿里云OSS
- 服务器:阿里云ECS
解决方案调研
方案一:CKEditor + Paste from Word插件
CKEditor官方提供了"Paste from Word"插件,但有以下局限:
- 仅支持Word内容粘贴,不支持完整文件导入
- 样式保留有限,复杂公式和图表可能丢失
- 需要额外开发图片上传功能
- 官方插件免费,但功能有限
方案二:TinyMCE + PowerPaste
TinyMCE的PowerPaste插件功能强大,但:
- 需要切换到TinyMCE编辑器
- 商业授权超出预算(约$200/年)
- 集成成本较高
方案三:CKEditor + custom插件+ Mammoth.js
最终选择方案:
- 使用Mammoth.js (.docx转换)
- 使用SheetJS (Excel处理)
- 使用pdf.js (PDF处理)
- 自定义CKEditor插件整合这些库
优点:
- 完全开源,零成本
- 可定制性强
- 保留现有编辑器不破坏现有功能
开发实施
1. 环境准备
# 安装Mammoth.jsnpminstallmammoth# 安装SheetJSnpminstallxlsx# 安装pdf.jsnpminstallpdfjs-dist2. 创建CKEditor自定义插件
在CKEditor插件目录创建wordimport插件:
plugins/wordimport/ ├── plugin.js ├── icons/ │ └── wordimport.png └── dialogs/ └── wordimport.js3. 插件核心代码 (plugin.js)
CKEDITOR.plugins.add('wordimport',{icons:'wordimport',init:function(editor){editor.addCommand('wordimport',newCKEDITOR.dialogCommand('wordimport'));editor.ui.addButton('WordImport',{label:'导入Office文档',command:'wordimport',toolbar:'insert'});CKEDITOR.dialog.add('wordimport',this.path+'dialogs/wordimport.js');// 处理粘贴事件editor.on('paste',function(evt){handlePasteEvent(evt,editor);});}});functionhandlePasteEvent(evt,editor){constclipboardData=evt.data.dataTransfer;if(clipboardData.getData('text/html')){// 处理从Word粘贴的内容cleanWordHTML(editor,clipboardData.getData('text/html'));evt.cancel();}}asyncfunctioncleanWordHTML(editor,html){try{constcleanedHTML=awaitprocessWordHTML(html);editor.insertHtml(cleanedHTML);}catch(error){console.error('Error processing Word content:',error);editor.insertHtml(html);// 回退到原始内容}}4. 文档转换处理
// 处理Word文档asyncfunctionhandleWordFile(file){constarrayBuffer=awaitfile.arrayBuffer();constresult=awaitmammoth.convertToHtml({arrayBuffer:arrayBuffer});// 处理图片consthtmlWithImages=awaitprocessImages(result.value);returnhtmlWithImages;}// 处理Excel文档asyncfunctionhandleExcelFile(file){constarrayBuffer=awaitfile.arrayBuffer();constworkbook=XLSX.read(arrayBuffer,{type:'array'});lethtml='';constworksheet=workbook.Sheets[workbook.SheetNames[0]];constjsonData=XLSX.utils.sheet_to_json(worksheet,{header:1});jsonData.forEach(row=>{html+='';row.forEach(cell=>{html+=``;});html+='';});html+='${cell || ''}';returnhtml;}5. 图片上传处理
// PHP端图片上传处理 (OSS)functionuploadImageToOSS($tempPath){require_once'oss-sdk-php/autoload.php';$accessKeyId="your-access-key-id";$accessKeySecret="your-access-key-secret";$endpoint="your-oss-endpoint";$bucket="your-bucket-name";$ossClient=newOssClient($accessKeyId,$accessKeySecret,$endpoint);$object="uploads/".uniqid().".jpg";$options=array();try{$ossClient->uploadFile($bucket,$object,$tempPath,$options);return$ossClient->signUrl($bucket,$object,3600);}catch(OssException$e){error_log("OSS Upload Error: ".$e->getMessage());returnfalse;}}6. 前端与后端接口
// Vue组件中调用methods:{asyncuploadDocument(file){constformData=newFormData();formData.append('file',file);try{constresponse=awaitaxios.post('/api/upload-document',formData,{headers:{'Content-Type':'multipart/form-data'}});this.editorInstance.insertHtml(response.data.html);}catch(error){console.error('Upload failed:',error);}}}部署实施
前端部署:
- 构建Vue项目:
npm run build - 将dist目录内容部署到阿里云ECS
- 构建Vue项目:
后端部署:
- 配置PHP环境支持文件上传
- 设置阿里云OSS访问权限
- 部署PHP接口文件
数据库调整:
- 添加媒体资源记录表:
CREATETABLE`media_resources`(`id`int(11)NOTNULLAUTO_INCREMENT,`oss_path`varchar(255)NOTNULL,`local_path`varchar(255)DEFAULTNULL,`mime_type`varchar(100)DEFAULTNULL,`created_at`timestampNOTNULLDEFAULTCURRENT_TIMESTAMP,PRIMARYKEY(`id`))ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;
成本控制
开发成本:
- 使用开源库:0元
- 开发时间:8小时(按本地市场价约500元,但属于项目范围调整)
服务器成本:
- 阿里云OSS存储费用:预计0.01元/月(小流量使用)
- ECS资源消耗:无额外成本
总成本:完全控制在99元预算内
使用说明
- 在编辑器工具栏点击"导入Office文档"按钮
- 选择要导入的Word/Excel/PPT/PDF文件
- 系统自动转换并插入到编辑器中
- 从Word复制内容可直接粘贴,保留样式
- 从微信公众号复制的内容也会自动处理
遇到的问题及解决方案
Word公式支持问题:
- 问题:MathType公式转换为图片时失真
- 解决:使用mammoth.js的自定义转换器处理公式
Excel复杂表格样式丢失:
- 问题:合并单元格和复杂样式无法保留
- 解决:添加自定义CSS类模拟原始样式
图片上传超时:
- 问题:大文件上传到OSS超时
- 解决:实现分块上传并添加进度指示
项目总结
通过集成开源库和自定义开发,成功在预算内实现了客户需求。主要成果包括:
- 完整支持Office文档导入
- 保留绝大多数原始样式和结构
- 无缝图片上传到OSS
- 微信公众号内容兼容处理
- 非侵入式插件设计,不影响现有功能
客户测试反馈良好,编辑效率提升显著,特别是对频繁从Word和微信公众号复制内容的市场部门来说,节省了大量排版时间。
复制插件
说明:此教程以CKEditor4.x为例,使用其他编辑器的查看对应教程。
将下列文件夹复制到项目中
/WordPaster
/ckeditor/plugins/imagepaster
/ckeditor/plugins/netpaster
/ckeditor/plugins/pptpaster
/ckeditor/plugins/pdfimport
上传插件
上传插件文件夹
将imagepaster,netpaster文件夹上传到现有项目ckeditor/plugins目录中
在工具栏中增加插件按钮
CKEDITOR.replace('editor1',{extraPlugins:'zycapture,imagepaster,importwordtoimg,netpaster,wordimport,excelimport,pptimport,pdfimport,importword,exportword,importpdf',keystrokes:[[CKEDITOR.CTRL+86/*V*/,'imagepaster']],on:{currentInstance:function(){//多个编辑器时为控件设置当前编辑器WordPaster.getInstance().SetEditor(CKEDITOR.currentInstance);window.zyCapture.setEditor(this);window.zyOffice.SetEditor(this);}},//https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-allowedContentallowedContent:true//不过滤样式});引用js
初始化控件
WordPaster.getInstance({//上传接口:http://www.ncmem.com/doc/view.aspx?id=d88b60a2b0204af1ba62fa66288203edPostUrl:api,//为图片地址增加域名:http://www.ncmem.com/doc/view.aspx?id=704cd302ebd346b486adf39cf4553936ImageUrl:"",//设置文件字段名称:http://www.ncmem.com/doc/view.aspx?id=c3ad06c2ae31454cb418ceb2b8da7c45FileFieldName:"file",//提取图片地址:http://www.ncmem.com/doc/view.aspx?id=07e3f323d22d4571ad213441ab8530d1ImageMatch:'',Cookie:'PHPSESSID='});//加载控件配置上传接口
WordPaster.getInstance({//上传接口:http://www.ncmem.com/doc/view.aspx?id=d88b60a2b0204af1ba62fa66288203edPostUrl:api,//为图片地址增加域名:http://www.ncmem.com/doc/view.aspx?id=704cd302ebd346b486adf39cf4553936ImageUrl:"",//设置文件字段名称:http://www.ncmem.com/doc/view.aspx?id=c3ad06c2ae31454cb418ceb2b8da7c45FileFieldName:"file",//提取图片地址:http://www.ncmem.com/doc/view.aspx?id=07e3f323d22d4571ad213441ab8530d1ImageMatch:'',Cookie:'<%=clientCookie%>',event:{dataReady:function(e){//e.word,//e.imgs:tag1,tag2,tag3console.log(e.imgs)}}});//加载控件注意
1.如果接口字段名称不是file,请配置FileFieldName。ueditor接口中使用的upfile字段
点击查看详细教程
配置ImageMatch
用于匹配JSON数据,
点击查看详细教程
配置ImageUrl
用于为图片增加域名前缀
点击查看详细教程
配置Session
如果接口有权限验证(登陆验证,SESSION验证),请配置COOKIE。或取消权限验证。
参考:点击查看详细教程
说明
1.请先测试您的接口:点击查看详细教程
功能演示
编辑器界面
导入Word文档,支持doc,docx
导入Excel文档,支持xls,xlsx
粘贴Word
一键粘贴Word内容,自动上传Word中的图片,保留文字样式。
Word转图片
一键导入Word文件,并将Word文件转换成图片上传到服务器中。
导入PDF
一键导入PDF文件,并将PDF转换成图片上传到服务器中。
导入PPT
一键导入PPT文件,并将PPT转换成图片上传到服务器中。
上传网络图片
一键自动上传网络图片,自动下载远程服务器图片,自动上传远程服务器图片
下载示例
点击下载完整示例