> 技术文档 > ueditor互联网应用中复制图片并上传到服务器的组件?

ueditor互联网应用中复制图片并上传到服务器的组件?

咱安徽程序员实锤了!最近接了个CMS外包活,客户是做企业官网的,非要给后台新闻编辑器加“文档导入+Word一键粘贴”功能——好家伙,需求单写着“要保留Word里的花里胡哨样式,图片公式、甚至MathType的鬼画符都得给我原模原样塞进文章里,高龄编辑用着得比我妈用微信视频还顺溜”。

咱先捋捋客户痛点:他们编辑部有个大爷,70岁的人,打字比蜗牛爬,发篇新闻得先在Word里捣鼓两小时排版,再复制粘贴到后台,结果图片全乱码,公式变乱码,气得大爷拍桌子:“这破系统还不如我用钢笔写稿子!” 所以客户要的哪是功能?是要“让大爷也能轻松发新闻”的救命神器啊!

第一步:摸透UEditor的“脾气”

咱前端用的是Vue3,编辑器是百度那老古董UEditor——好处是文档全,坏处是扩展起来像拆盲盒。要在工具栏加按钮?行,先改ueditor.config.js,把“导入文档”按钮塞进去:

// ueditor.config.js 里加按钮配置UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;UE.Editor.prototype.getActionUrl = function(action) { if (action === \'uploadword\' || action === \'pastehtml\') { // 自定义接口 return \'/api/editor/handleDoc\'; // 后端接口地址 } else { return this._bkGetActionUrl.call(this, action); }};// 工具栏添加按钮(在toolbars数组里加)toolbars: [ [\'bold\', \'italic\', \'underline\', \'insertimage\', \'uploadword\'] // 新增uploadword按钮]

前端点击按钮后,触发文件选择或粘贴事件。粘贴的话,得监听paste事件,把剪贴板里的Word内容捞出来:

import { onMounted } from \'vue\';const ue = ref(null);onMounted(() => { ue.value = UE.getEditor(\'editor\', { serverUrl: \'/api/editor/upload\', // 原图上传接口 }); // 监听粘贴事件 ue.value.addListener(\'paste\', (type, event) => { const clipboardData = event.clipboardData || window.clipboardData; if (clipboardData.items) { for (let i = 0; i  { ue.value.execCommand(\'insertHtml\', text); // 直接插入带样式的HTML }); } } } }); // 自定义按钮点击事件(上传Word) UE.registerUI(\'uploadword\', (editor, uiName) => { const btn = new UE.ui.Button({ name: uiName, title: \'导入Word/PPT/Excel\', onclick: () => { const input = document.createElement(\'input\'); input.type = \'file\'; input.accept = \'.doc,.docx,.ppt,.pptx,.xls,.xlsx,.pdf\'; input.onchange = async (e) => { const file = e.target.files[0]; if (file) { const formData = new FormData(); formData.append(\'file\', file); const res = await fetch(\'/api/editor/handleDoc\', {  method: \'POST\',  body: formData, }); const html = await res.json(); editor.execCommand(\'insertHtml\', html.content); // 把解析后的内容塞进编辑器 } }; input.click(); }, }); return btn; });});

第二步:后端PHP“暴力”解析文档

前端搞定了,后端得硬刚各种文档格式。客户要保留图片、公式,咱得找个能“拆文档”的库——PhpWord能读Word,但Excel/PPT得用PhpSpreadsheetPhpPresenter,PDF用TCPDFSmalot/pdfparser。不过最头疼的是公式和样式:Word里的公式可能是图片(emz/wmz)或者Latex,得扒出来转成MathML。

先写个接收文件的接口/api/editor/handleDoc

// PHP后端接口public function handleDoc(Request $request) { $file = $request->file(\'file\'); $ext = $file->getClientOriginalExtension(); $html = \'\'; switch ($ext) { case \'docx\': $html = $this->parseWord($file); break; case \'pdf\': $html = $this->parsePdf($file); break; // 其他格式类似... } // 图片上传OSS(阿里云SDK) $html = $this->uploadImagesToOSS($html); // Latex转MathML(用LaTeXML工具) $html = $this->convertLatexToMathML($html); return json([\'code\' => 200, \'content\' => $html]);}private function parseWord($file) { require \'vendor/autoload.php\'; // 引入Composer库 $phpWord = \\PhpOffice\\PhpWord\\IOFactory::load($file->getPathname()); $htmlWriter = new \\PhpOffice\\PhpWord\\Writer\\HTML($phpWord); return $htmlWriter->getContent(); // 这里能拿到带样式的HTML,但公式可能丢失}

图片处理:Word里的图片会被解析成base64或临时文件,得上传到OSS。用阿里云OSS SDK的话,大概是这样:

use OSS\\OssClient;use OSS\\Core\\OssException;private function uploadImagesToOSS($html) { $ossClient = new OssClient(\'AccessKeyId\', \'AccessKeySecret\', \'oss-cn-hangzhou.aliyuncs.com\'); $bucket = \'your-bucket\'; $pattern = \'/ $base64) { $imageData = base64_decode($base64); $object = \'news-images/\' . uniqid() . \'.\' . $matches[1][$index]; // OSS路径 try { $ossClient->putObject($bucket, $object, $imageData); $html = str_replace($matches[0][$index], \'src=\"https://your-bucket.oss-cn-hangzhou.aliyuncs.com/\' . $object . \'\"\', $html); } catch (OssException $e) { error_log(\"上传失败:\" . $e->getMessage()); } } return $html;}

Latex转MathML:用LaTeXML命令行工具(得服务器装),或者用PHP库latex2mathml

private function convertLatexToMathML($html) { $latexPattern = \'/\\$$(.*?)\\$/s\'; // 匹配$$...$$的Latex公式 preg_replace_callback($latexPattern, function($matches) { $latex = $matches[1]; $mathml = shell_exec(\"latexit -c \'{$latex}\'\"); // 假设服务器装了latexit return $mathml ? \"{$mathml}\" : $matches[0]; }, $html); return $html;}

第三步:微信公众号内容“偷梁换柱”

客户还想要公众号导入,那简单——公众号复制的内容自带一堆冗余标签(比如``),咱写个过滤函数:

private function cleanWechatHtml($html) { $dom = new DOMDocument(); @$dom->loadHTML(mb_convert_encoding($html, \'HTML-ENTITIES\', \'UTF-8\')); // 移除无用标签 $xpath = new DOMXPath($dom); foreach ($xpath->query(\'//span[contains(@class, \"rich_media_meta\")]\') as $node) { $node->parentNode->removeChild($node); } // 保留关键样式(比如加粗、颜色) foreach ($xpath->query(\'//*[@style]\') as $node) { $style = $node->getAttribute(\'style\'); $style = preg_replace(\'/(font-family|line-height):[^;]+;?/\', \'\', $style); // 移除可能冲突的样式 $node->setAttribute(\'style\', trim($style)); } return $dom->saveHTML();}

预算?680块够不够?

咱用的都是开源库(PhpWord、PhpSpreadsheet、阿里云OSS SDK),服务器装个LaTeXML工具(免费),前端Vue3改改按钮,后端PHP写几个解析函数——680块够买杯奶茶庆祝了!要是客户要更复杂的公式支持(比如MathType),最多花200块买个商业解析库,剩下的钱还能给群里兄弟发红包~

最后:群里喊一嗓子

咱建的QQ群223813913,新人进群送1-99元红包!推荐客户提20%提成,成交10单就是4万提成,比在厂里打螺丝香多了!群里还有一堆技术大佬,遇到问题甩个表情包,分分钟有人帮你解决~

(PS:大爷看了咱的编辑器,拍着大腿说“比我家那台老电脑还顺手”,客户当场签了续单合同——这钱,赚得值!)

复制插件目录

ueditor互联网应用中复制图片并上传到服务器的组件?

引入插件文件

UEditor 1.4.3.3示例 

注意:不要重复引入jquery,如果您的项目已经引入了jq,则不用再引入jq-1.4
ueditor互联网应用中复制图片并上传到服务器的组件?

在工具栏中增加插件按钮

//工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的重新定义 toolbars: [ [ \"fullscreen\", \"source\", \"|\", \"zycapture\", \"|\", \"wordpaster\",\"importwordtoimg\",\"netpaster\",\"wordimport\",\"excelimport\",\"pptimport\",\"pdfimport\", \"|\", \"importword\",\"exportword\",\"importpdf\" ] ]

初始化控件

ueditor互联网应用中复制图片并上传到服务器的组件?

 var pos = window.location.href.lastIndexOf(\"/\"); var api = [ window.location.href.substr(0, pos + 1), \"asp/upload.asp\" ].join(\"\"); WordPaster.getInstance({//上传接口:http://www.ncmem.com/doc/view.aspx?id=d88b60a2b0204af1ba62fa66288203ed PostUrl: api,//为图片地址增加域名:http://www.ncmem.com/doc/view.aspx?id=704cd302ebd346b486adf39cf4553936 ImageUrl: \"\", //设置文件字段名称:http://www.ncmem.com/doc/view.aspx?id=c3ad06c2ae31454cb418ceb2b8da7c45 FileFieldName: \"file\", //提取图片地址:http://www.ncmem.com/doc/view.aspx?id=07e3f323d22d4571ad213441ab8530d1 ImageMatch: \'\' });//加载控件

注意

如果接口字段名称不是file,请配置FileFieldName。ueditor接口中使用的upfile字段
image
点击查看详细教程

配置ImageMatch

匹配图片地址,如果服务器返回的是JSON则需要通过正则匹配

ImageMatch: \'\',

点击参考链接

配置ImageUrl

为图片地址增加域名,如果服务器返回的图片地址是相对路径,可通过此属性添加自定义域名。

ImageUrl: \"\",

点击查看详细教程

配置SESSION

如果接口有权限验证(登陆验证,SESSION验证),请配置COOKIE。或取消权限验证。
参考:http://www.ncmem.com/doc/view.aspx?id=8602DDBF62374D189725BF17367125F3

效果

编辑器界面

ueditor互联网应用中复制图片并上传到服务器的组件?

导入Word文档,支持doc,docx

ueditor互联网应用中复制图片并上传到服务器的组件?

导入Excel文档,支持xls,xlsx

ueditor互联网应用中复制图片并上传到服务器的组件?

粘贴Word

一键粘贴Word内容,自动上传Word中的图片,保留文字样式。
ueditor互联网应用中复制图片并上传到服务器的组件?

Word转图片

一键导入Word文件,并将Word文件转换成图片上传到服务器中。
ueditor互联网应用中复制图片并上传到服务器的组件?

导入PDF

一键导入PDF文件,并将PDF转换成图片上传到服务器中。
ueditor互联网应用中复制图片并上传到服务器的组件?

导入PPT

一键导入PPT文件,并将PPT转换成图片上传到服务器中。
ueditor互联网应用中复制图片并上传到服务器的组件?

上传网络图片

ueditor互联网应用中复制图片并上传到服务器的组件?

下载示例

点击下载完整示例