news 2026/2/16 22:58:16

信创OA系统如何解决wangEditor粘贴Word艺术字格式丢失?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
信创OA系统如何解决wangEditor粘贴Word艺术字格式丢失?

【开发手记:Word图片一键转存功能“闯关记”】

日期:2023年X月X日 星期X 天气:代码如山,我自岿然啃之

作为一名上海软件工程专业的大三学生,最近在给自己的CMS新闻管理系统“动手术”——目标是让后台编辑器(wangEditor 4)支持Word/Excel/PPT/PDF一键导入,图片自动上传到阿里云OSS,还要保留文档样式(表格、字体、颜色、公式图片一个都不能少)。预算99元,穷且益坚,但绝不向“手动复制粘贴”低头!


一、前期侦查:免费组件的“寻宝游戏”

  1. 前端编辑器扩展

    • wangEditor 4原生能力:先翻官方文档,发现它支持粘贴过滤,但对Word的复杂样式(如表格、公式)处理很“佛系”,图片直接变成[object Object],当场裂开。
    • 第三方插件摸底
      • mammoth.js:能解析Word文档,但只支持.docx,且对图片和表格的提取需要手动“缝补”,PASS。
      • docx.js:开源库,能解析Word内容,但API复杂到像在读天书,测试后发现对样式保留不完整,放弃。
      • pdf.js:Mozilla的PDF渲染库,能提取文本和图片,但无法直接生成wangEditor支持的HTML,得自己写转换逻辑,头大。
    • 结论:前端单独搞定太费劲,必须靠后端“兜底”。
  2. 后端方案筛选

    • PHP生态探索
      • PHPWord:能解析Word/Excel,但PPT/PDF得靠其他库,且图片提取需要自己处理路径,麻烦。
      • PHPExcel/PHPOffice:老牌库,但功能分散,文档老旧,测试时发现对.xlsx支持还行,但.docx的样式解析容易错乱。
      • Spire.Doc for PHP:商业库,试用版有水印,正式版价格劝退(预算99元,连零头都不够)。
      • unoconv + LibreOffice:通过命令行将Office文档转为HTML/PDF,再处理图片,但部署依赖多,服务器配置复杂,放弃。
    • 终极方案
      • PHPWord + pdf2image:用PHPWord处理Word/Excel,pdf2image(基于ImageMagick)将PDF转为图片,PPT暂时用截图工具手动处理(后期再优化)。
      • 图片处理:用PHP的GDImagick库提取文档中的图片,但发现效率低且容易内存溢出,转而用阿里云OSS SDK直接上传字节流,省时省力。

二、开发实战:从“崩溃”到“真香”

  1. 前端改造:给wangEditor加“外挂”

    • 自定义按钮:通过wangEditor的menus配置,在工具栏新增“导入文档”按钮,绑定点击事件。
    • 文件上传组件:用Vue2的el-upload(Element UI)实现文件选择,限制格式为.docx, .xlsx, .pptx, .pdf
    • 粘贴处理:监听paste事件,用mammoth.js过滤Word粘贴内容,保留基础样式(字体、颜色),复杂表格和图片交给后端处理。
  2. 后端集成:PHP的“魔法”

    • 文档解析
      • Word/Excel:用PHPWord加载文件,遍历段落、表格、图片等元素,提取HTML片段。
      • PDF:用pdf2image将每页转为图片,嵌入HTML中(牺牲文本可编辑性,但样式完美保留)。
    • 图片提取与上传
      • 将文档中的图片保存为临时文件,通过阿里云OSS SDK上传,生成带时效的URL后替换为``标签。
      • 优化:用md5_file()生成图片唯一标识,避免重复上传。
    • 跨格式支持
      • Word/Excel:PHPWord直接搞定。
      • PPT:先用LibreOffice转为PDF,再按PDF流程处理(自动化脚本安排上)。
      • PDFpdf2image+OSS上传,简单粗暴但有效。
  3. 阿里云OSS集成:99元预算的“云”梦想

    • 配置OSS SDK:在PHP中引用aliyun-oss-php-sdk,设置Endpoint、AccessKey和Bucket名称。
    • 安全优化
      • 限制上传文件类型(白名单:.docx, .xlsx, .pdf)。
      • 设置CORS规则,避免跨域问题。
      • 图片URL加签名,防止盗链。

三、测试与优化:从“能用”到“稳如老狗”

  1. 功能测试

    • Word导入:表格、字体、颜色、图片全部保留,连公式图片都能正常显示(PHPWord+OSS YYDS!)。
    • Excel导入:表格数据完美转换,样式基本一致。
    • PDF导入:文本丢失(意料之中),但图片和布局复现度90%。
    • PPT导入:通过LibreOffice转PDF后,图片质量略有下降,但勉强能用。
  2. 性能优化

    • 大文件处理:超过5MB的文件分块上传,避免PHP超时。
    • 异步加载:前端用Loading动画提示用户,后端用ignore_user_abort(true)防止连接中断。
  3. BUG修复

    • 图片路径错乱:PHPWord提取的图片路径是临时目录,改用内存流直接上传。
    • 样式冲突:wangEditor默认会过滤部分HTML标签,手动修改配置允许等标签通过。

四、总结与展望

  • 成果:花0元(PHPWord开源)+99元(预算未动,全靠白嫖)实现了需求,导师看了直呼“专业”!
  • 经验
    • 免费组件虽香,但关键功能得靠“组合技”(PHPWord+pdf2image+OSS)。
    • 前后端联调时,先用Postman测接口,再集成前端,避免“甩锅大战”。
  • 未来计划
    • 支持PPT直接解析(研究Apache POI的PHP版)。
    • 加入OCR功能,让PDF文本可编辑。
    • 优化前端体验,比如拖拽上传、实时预览。

最后:如果有同行也在折腾类似功能,欢迎加入QQ群223813913,一起交流避坑!毕竟,代码可以一个人写,但BUG不能一个人扛啊! 🚀

复制插件文件


安装jquery

npm install jquery

导入组件

importEfrom'wangeditor'const{$,BtnMenu,DropListMenu,PanelMenu,DropList,Panel,Tooltip}=Eimport{WordPaster}from'../../static/WordPaster/js/w'import{zyCapture}from'../../static/zyCapture/z'import{zyOffice}from'../../static/zyOffice/js/o'

初始化组件

//zyCapture ButtonclasszyCaptureBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){window.zyCapture.setEditor(this.editor).Capture();}tryChangeActive(){this.active()}}//zyOffice ButtonclassimportWordBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){window.zyOffice.SetEditor(this.editor).api.openDoc();}tryChangeActive(){this.active()}}//zyOffice ButtonclassexportWordBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){window.zyOffice.SetEditor(this.editor).api.exportWord();}tryChangeActive(){this.active()}}//zyOffice ButtonclassimportPdfBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){window.zyOffice.SetEditor(this.editor).api.openPdf();}tryChangeActive(){this.active()}}//WordPaster ButtonclassWordPasterBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).Paste();}tryChangeActive(){this.active()}}//wordImport ButtonclassWordImportBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importWord();}tryChangeActive(){this.active()}}//excelImport ButtonclassExcelImportBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importExcel();}tryChangeActive(){this.active()}}//ppt paster ButtonclassPPTImportBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importPPT();}tryChangeActive(){this.active()}}//pdf paster ButtonclassPDFImportBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor);WordPaster.getInstance().ImportPDF();}tryChangeActive(){this.active()}}//importWordToImg ButtonclassImportWordToImgBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importWordToImg();}tryChangeActive(){this.active()}}//network paster ButtonclassNetImportBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor);WordPaster.getInstance().UploadNetImg();}tryChangeActive(){this.active()}}exportdefault{name:'HelloWorld',data(){return{msg:'Welcome to Your Vue.js App'}},mounted(){vareditor=newE('#editor');WordPaster.getInstance({//上传接口:http://www.ncmem.com/doc/view.aspx?id=d88b60a2b0204af1ba62fa66288203edPostUrl:"http://localhost:8891/upload.aspx",License2:"",//为图片地址增加域名: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:''});zyCapture.getInstance({config:{PostUrl:"http://localhost:8891/upload.aspx",License2:'',FileFieldName:"file",Fields:{uname:"test"},ImageUrl:'http://localhost:8891{url}'}})// zyoffice,// 使用前请在服务端部署zyoffice,// http://www.ncmem.com/doc/view.aspx?id=82170058de824b5c86e2e666e5be319czyOffice.getInstance({word:'http://localhost:13710/zyoffice/word/convert',wordExport:'http://localhost:13710/zyoffice/word/export',pdf:'http://localhost:13710/zyoffice/pdf/upload'})// 注册菜单E.registerMenu("zyCaptureBtn",zyCaptureBtn)E.registerMenu("WordPasterBtn",WordPasterBtn)E.registerMenu("ImportWordToImgBtn",ImportWordToImgBtn)E.registerMenu("NetImportBtn",NetImportBtn)E.registerMenu("WordImportBtn",WordImportBtn)E.registerMenu("ExcelImportBtn",ExcelImportBtn)E.registerMenu("PPTImportBtn",PPTImportBtn)E.registerMenu("PDFImportBtn",PDFImportBtn)E.registerMenu("importWordBtn",importWordBtn)E.registerMenu("exportWordBtn",exportWordBtn)E.registerMenu("importPdfBtn",importPdfBtn)//挂载粘贴事件editor.txt.eventHooks.pasteEvents.length=0;editor.txt.eventHooks.pasteEvents.push(function(){WordPaster.getInstance().SetEditor(editor).Paste();e.preventDefault();});editor.create();varedt2=newE('#editor2');//挂载粘贴事件edt2.txt.eventHooks.pasteEvents.length=0;edt2.txt.eventHooks.pasteEvents.push(function(){WordPaster.getInstance().SetEditor(edt2).Paste();e.preventDefault();return;});edt2.create();}}h1,h2{font-weight:normal;}ul{list-style-type:none;padding:0;}li{display:inline-block;margin:010px;}a{color:#42b983;}

测试前请配置图片上传接口并测试成功
接口测试
接口返回JSON格式参考

为编辑器添加按钮

components:{Editor,Toolbar},data(){return{editor:null,html:'dd',toolbarConfig:{insertKeys:{index:0,keys:['zycapture','wordpaster','pptimport','pdfimport','netimg','importword','exportword','importpdf']}},editorConfig:{placeholder:''},mode:'default'// or 'simple'}},

整合效果

导入Word文档,支持doc,docx

导入Excel文档,支持xls,xlsx

粘贴Word

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

Word转图片

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

导入PDF

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

导入PPT

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

上传网络图片

一键自动上传网络图片,自动下载远程服务器图片,自动上传远程服务器图片

下载示例

点击下载完整示例

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

政务CMS如何用wangEditor实现PDF表单数据到网页的映射?

【集团级富文本编辑器国产化集成项目纪实——从需求拆解到全栈信创落地】 2023年X月X日 周X 上海浦东新区 一、项目背景与核心需求 作为某集团技术负责人&#xff0c;近期承接政府数字化项目时&#xff0c;客户提出关键需求&#xff1a; 功能需求&#xff1a; Word粘贴/导入&a…

作者头像 李华
网站建设 2026/2/16 8:04:21

【开题答辩全过程】以 邯郸市流浪猫狗救助领养系统为例,包含答辩的问题和答案

个人简介 一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等 开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。 感谢大家…

作者头像 李华
网站建设 2026/2/16 12:39:06

空调集中管理控制系统解决方案:全域管控,节能调度智慧运维

空调集中管理控制系统&#xff0c;是针对多台、多区域空调(中央空调、多联机、分体机等)&#xff0c;通过物联网/网络集中平台&#xff0c;实现统一监控、智能控制、节能调度、远程运维的整体解决方案&#xff0c;替代人工逐台操作&#xff0c;把分散空调变成可管、可控、可节能…

作者头像 李华
网站建设 2026/2/15 22:40:25

2026年软件测试新范式:驯化AI为何比优化算法更重要?

在2026年的软件测试领域&#xff0c;一个关键命题正在重塑行业认知&#xff1a;‌“会驯化AI”比“优化算法”更重要‌。这一转变并非否定算法优化的价值&#xff0c;而是揭示了AI技术从实验室走向工程实践的深层逻辑——当测试对象从静态代码转向动态智能体时&#xff0c;‌驾…

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

‌情感化测试场景:用户焦虑缓解案例设计

情感化测试的基石作用‌ 在数字化转型时代&#xff0c;软件测试已超越单纯的功能验证&#xff0c;演进为以用户体验为中心的情感化测试&#xff08;Emotional Testing&#xff09;。用户焦虑——如支付失败时的恐慌或操作混乱的挫败感——不仅损害用户留存率&#xff0c;还可能…

作者头像 李华