新疆某网络公司程序员开发日志:企业网站后台管理系统富文本编辑器功能扩展
一、需求分析与技术选型
需求背景:
客户要求在企业网站后台管理系统的文章发布模块中新增以下功能:
- Word粘贴功能:支持从Word复制内容并粘贴到UEditor中,图片自动上传至服务器(二进制存储),保留文档样式(表格、字体、颜色等)。
- Word/Excel/PPT/PDF导入功能:支持导入常见办公文档,保留图片和样式。
- 微信公众号内容粘贴:兼容微信排版格式。
技术栈:
- 前端:Vue2-cli + UEditor(百度开源富文本编辑器)
- 后端:PHP(Laravel框架)
- 存储:阿里云OSS(后期扩展至多云对象存储)
- 数据库:MySQL
选型原则:
- 兼容性:需无缝集成至现有UEditor,避免修改核心代码。
- 性能:图片二进制存储,避免BASE64导致的HTML膨胀。
- 扩展性:支持未来迁移至阿里云/华为云/腾讯云等对象存储。
二、技术调研与方案评估
1. UEditor插件扩展
UEditor官方提供wordimage和scrawl插件,但存在以下问题:
wordimage插件仅支持图片提取,需手动上传,无法自动化处理。- 默认粘贴功能会丢失复杂样式(如表格边框、字体颜色)。
2. 第三方库对比
| 库名称 | 优势 | 劣势 |
|---|---|---|
| Mammoth.js | 轻量级,支持Word样式转换 | 仅支持DOCX,需手动处理图片上传 |
| docx-preview | 纯前端渲染,无需后端 | 无法提取图片,仅预览 |
| Puppeteer | 完整渲染引擎,支持复杂格式 | 依赖Node.js,与现有PHP后端冲突 |
| Aspose.Words | 商业库,功能全面 | 成本高,学习曲线陡峭 |
| 泽优WordPaster | 完全开源(下载源码) | |
| 功能全面 | ||
| 集成简单 | ||
| 使用方便 | ||
| 免费技术支持(QQ群:223813913) | ||
| 支持二次开发 | 需要终端安装控件 |
最终方案:
- 前端:直接使用WordPaster,他已经提供了UEditor的插件,不需要手写代码,直接复制过来就能用了,通过接口实现图片自动上传。
- 后端:PHP接收图片二进制流,存储至阿里云OSS,返回URL供前端插入。
- 兼容性:通过正则表达式匹配微信公众号内容中的特殊标签(如``)。
三、开发过程记录
1. 前端实现(Vue2 + UEditor)
步骤1:扩展UEditor插件
在ueditor/dialogs目录下创建wordpaste插件,监听粘贴事件:
// ueditor/plugins/wordpaste/wordpaste.jsUE.registerUI('wordpaste',function(editor){editor.addListener('ready',function(){editor.addListener('paste',function(type,event){constclipboardData=event.clipboardData||window.clipboardData;if(clipboardData&&clipboardData.files.length>0){handleWordPaste(clipboardData,editor);}});});});functionhandleWordPaste(clipboardData,editor){// 1. 提取文本内容(保留基础样式)consthtml=clipboardData.getData('text/html')||clipboardData.getData('text/plain');// 2. 使用Mammoth解析Word内容(需引入mammoth.browser.min.js)mammoth.extractRawText({arrayBuffer:clipboardData.files[0]}).then(result=>{// 3. 提取图片并上传constimages=html.match(/]+src="data:image[^>]+>/g)||[];uploadImages(images).then(urls=>{letcleanedHtml=html;urls.forEach((url,index)=>{cleanedHtml=cleanedHtml.replace(newRegExp(`src="data:image[^"]+"`,'g'),`src="${url}"`);});editor.execCommand('insertHtml',cleanedHtml);});});}步骤2:集成至Vue组件
export default { data() { return { editorId: 'editor_' + Math.random().toString(36).substr(2), editor: null }; }, mounted() { this.editor = UE.getEditor(this.editorId, { toolbars: [['wordpaste']] // 注册自定义按钮 }); }, methods: { pasteFromWord() { // 触发UEditor的粘贴事件 this.editor.execCommand('wordpaste'); } } };2. 后端实现(PHP + 阿里云OSS)
步骤1:图片上传接口
// api/upload.phpuseOSS\OssClient;useOSS\Core\OssException;functionuploadToOSS($fileData,$fileName){$accessKeyId='your-access-key-id';$accessKeySecret='your-access-key-secret';$endpoint='oss-cn-hangzhou.aliyuncs.com';$bucket='your-bucket-name';try{$ossClient=newOssClient($accessKeyId,$accessKeySecret,$endpoint);$object="images/".date('Ymd').'/'.uniqid().'_'.$fileName;$ossClient->putObject($bucket,$object,$fileData);return"https://{$bucket}.{$endpoint}/{$object}";}catch(OssException$e){returnfalse;}}// 接收前端上传的图片$rawData=file_get_contents('php://input');$fileName=$_GET['name']??'image_'.time().'.png';$url=uploadToOSS($rawData,$fileName);header('Content-Type: application/json');echojson_encode(['url'=>$url]);步骤2:文档导入服务(使用PHPWord库)
// api/import.phprequire'vendor/autoload.php';usePhpOffice\PhpWord\IOFactory;functionimportDocument($filePath){$phpWord=IOFactory::load($filePath);$html='';foreach($phpWord->getSections()as$section){foreach($section->getElementss()as$element){if(method_exists($element,'getElementss')){// 处理表格、段落等复杂元素$html.=''.$element->getElementss().'';}}}return$html;}// 示例:接收上传的DOCX文件并返回HTML$uploadedFile=$_FILES['file']['tmp_name'];$htmlContent=importDocument($uploadedFile);echo$htmlContent;四、测试与优化
1. 关键测试点
- 样式保留:验证表格边框、字体颜色、超链接等是否完整。
- 图片上传:检查二进制存储是否成功,OSS路径是否正确。
- 性能测试:使用10MB的Word文档测试上传和渲染速度。
2. 优化措施
- 图片压缩:在后端上传前使用
intervention/image库压缩图片。 - 异步处理:大文件导入使用队列(如RabbitMQ)分片处理。
- 错误处理:捕获OSS上传失败、文档解析异常等情况。
五、部署与文档
1. 部署步骤
- 安装PHP依赖:
composer require aliyuncs/oss-sdk-php phpoffice/phpword - 配置阿里云OSS权限(Bucket Policy允许PUT Object)。
- 前端引入Mammoth.js:
npm install mammoth。
2. 用户手册摘要
- Word粘贴:复制Word内容后,点击编辑器工具栏的
Word粘贴按钮。 - 文档导入:在编辑器菜单中选择
导入文档,上传文件后自动转换。
六、后续规划
- 多云支持:封装OSS客户端为接口,未来可替换为华为云/腾讯云SDK。
- 移动端适配:优化微信公众号内容在移动端的粘贴体验。
- 安全加固:增加文件类型白名单,防止恶意文件上传。
通过此次开发,成功在现有系统中集成了高兼容性的文档处理功能,客户反馈良好,后续将推广至其他产品线。
复制插件目录
引入插件文件
UEditor 1.4.3.3示例注意:不要重复引入jquery,如果您的项目已经引入了jq,则不用再引入jq-1.4
在工具栏中增加插件按钮
//工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的重新定义toolbars:[["fullscreen","source","|","zycapture","|","wordpaster","importwordtoimg","netpaster","wordimport","excelimport","pptimport","pdfimport","|","importword","exportword","importpdf"]]初始化控件
varpos=window.location.href.lastIndexOf("/");varapi=[window.location.href.substr(0,pos+1),"asp/upload.asp"].join("");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:''});//加载控件注意
如果接口字段名称不是file,请配置FileFieldName。ueditor接口中使用的upfile字段
点击查看详细教程
配置ImageMatch
匹配图片地址,如果服务器返回的是JSON则需要通过正则匹配
ImageMatch:'',点击参考链接
配置ImageUrl
为图片地址增加域名,如果服务器返回的图片地址是相对路径,可通过此属性添加自定义域名。
ImageUrl:"",点击查看详细教程
配置SESSION
如果接口有权限验证(登陆验证,SESSION验证),请配置COOKIE。或取消权限验证。
点击查看配置教程
功能演示
编辑器界面
导入Word文档,支持doc,docx
导入Excel文档,支持xls,xlsx
粘贴Word
一键粘贴Word内容,自动上传Word中的图片,保留文字样式。
Word转图片
一键导入Word文件,并将Word文件转换成图片上传到服务器中。
导入PDF
一键导入PDF文件,并将PDF转换成图片上传到服务器中。
导入PPT
一键导入PPT文件,并将PPT转换成图片上传到服务器中。
上传网络图片
下载示例
点击下载完整示例