news 2026/6/12 20:21:42

TinyMCE4解决Word图片粘贴转存政府公文格式需求

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TinyMCE4解决Word图片粘贴转存政府公文格式需求

黑龙江XX集团站群新闻功能升级项目实施记录
(基于信创环境的TinyMCE扩展与SpringBoot集成方案)

一、项目背景与需求分析

  1. 现状梳理

    • 集团站群涵盖50+站点(内网+外网),采用统一后台管理系统,新闻模块基于TinyMCE编辑器开发,后端为SpringBoot 2.7.x框架。
    • 当前编辑器功能单一,仅支持基础文本编辑,无法满足Word文档快速导入需求,且图片需手动上传至服务器,效率低下。
  2. 核心需求

    • 功能升级:实现Word文档一键导入,保留原格式(字体、段落、表格、图片等),图片自动上传至服务器并生成CDN链接。
    • 信创兼容:支持国产操作系统(如麒麟、统信UOS)、数据库(达梦DM8、人大金仓)及中间件(东方通、宝兰德)。
    • 服务保障:提供7×24小时在线技术支持,确保系统稳定性。

二、技术选型与产品评估

1. 编辑器扩展方案对比
方案优势劣势适配性评估
TinyMCE官方插件原生集成,开发成本低;支持基础Word粘贴(仅文本+简单格式)图片无法自动上传,复杂样式(如表格、背景色)易丢失需二次开发,信创环境需验证
第三方插件(如Pell富文本)开源免费,支持Word图片自动上传文档兼容性差,样式保留不完整;社区支持弱不满足核心需求,排除
商业解决方案(如UEditor、CKEditor企业版)功能完整,支持Word一键导入+图片自动上传;提供信创认证版本成本较高(年费制);部分功能需定制开发需评估预算与长期合作可行性
自研扩展组件完全可控,可深度定制;适配信创环境开发周期长(预估3-6个月);需维护独立代码库风险较高,暂不考虑

结论:选择TinyMCE官方插件+定制开发,结合Apache POI解析Word文档,实现图片自动上传与样式保留。

2. 信创环境兼容性验证
  • 操作系统:在麒麟V10、统信UOS 20上测试TinyMCE渲染效果,修复CSS兼容性问题。
  • 数据库:使用达梦DM8替代MySQL,调整JPA注解映射规则(如@Column@DmColumn)。
  • 中间件:替换Tomcat为东方通TongWeb 7.0,配置JVM参数优化内存占用。

三、开发实施过程

1. 功能模块拆分
  • 前端(TinyMCE扩展)

    • 集成tiny-mce-wordimport插件,监听paste事件,拦截Word内容。
    • 通过FileReader解析.docx文件,提取文本、图片Base64数据。
    • 调用后端接口上传图片,替换为CDN链接后插入编辑器。
  • 后端(SpringBoot)

    • 新增WordImportController,接收图片Base64数据并存储至MinIO对象存储。
    • 使用Apache POI的XWPFDocument类解析Word文档结构,生成JSON格式的样式数据。
    • 封装WordStyleConverter工具类,将Word样式映射为TinyMCE支持的HTML标签(如``)。
2. 关键代码片段
// Word图片上传接口(SpringBoot)@PostMapping("/api/word/upload-image")publicResponseEntityuploadImage(@RequestParam("file")MultipartFilefile){StringobjectName="word-images/"+UUID.randomUUID()+".png";minioClient.putObject(BucketName.WORD_IMAGES,objectName,file.getInputStream(),file.getContentType());returnResponseEntity.ok("https://cdn.xxgroup.com/"+objectName);}// Word样式转换(Apache POI)publicStringconvertToHtml(XWPFParagraphparagraph){StringBuilderhtml=newStringBuilder("").append(paragraph.getText()).append("");returnhtml.toString();}
3. 信创适配优化
  • 字体问题:在服务器部署中文字体包(如微软雅黑、宋体),避免Word导入后显示乱码。
  • 性能优化:对大文件(>10MB)采用分片上传,通过Web Worker避免前端卡顿。
  • 安全加固:限制图片上传类型(仅.jpg/.png),对Word内容进行XSS过滤。

四、测试与部署

  1. 测试用例

    • 功能测试:验证Word文档(含表格、图片、超链接)导入后的样式一致性。
    • 兼容性测试:在麒麟+达梦、统信+人大金仓环境下进行全量回归测试。
    • 压力测试:模拟100并发用户同时上传Word文档,监控服务器资源占用(CPU<60%,内存<80%)。
  2. 部署方案

    • 内网环境:使用Kubernetes集群部署,通过Ingress实现负载均衡。
    • 外网环境:通过CDN加速静态资源(如图片、CSS、JS),降低服务器压力。

五、技术支持与运维保障

  1. 服务承诺

    • 提供7×24小时在线工单系统,响应时间≤15分钟。
    • 每月定期巡检,输出《系统健康度报告》。
  2. 知识转移

    • 编制《TinyMCE信创环境开发手册》,包含常见问题排查指南。
    • 对集团运维团队进行2次现场培训(每次4小时),覆盖日志分析、性能调优等场景。

六、项目成果

  • 效率提升:新闻发布时间从平均45分钟缩短至8分钟(含Word导入+图片上传)。
  • 信创认证:通过麒麟软件生态兼容性认证(证书编号:KY-2023XXXXXX)。
  • 成本节约:相比商业解决方案,节省授权费用约12万元/年。

附录

  • 完整代码库地址:[GitLab私有仓库链接]
  • 测试报告:[PDF文档链接]
  • 技术支持联系方式:400-XXX-XXXX(7×24小时)

记录人:XXX集团技术中心
日期:2025年XX月XX日

复制插件

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

上传网络图片

一键自动上传网络图片。

下载示例

点击下载完整示例

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

Open-AutoGLM + Android = 未来智能终端?深度剖析5大融合场景与落地挑战

第一章&#xff1a;Open-AutoGLM在Android端的演进与战略意义Open-AutoGLM作为开源自动语言模型框架&#xff0c;近年来在移动端特别是Android平台展现出显著的技术演进与生态扩展能力。其轻量化推理引擎与模块化架构设计&#xff0c;使得大型语言模型能够在资源受限设备上高效…

作者头像 李华
网站建设 2026/6/9 23:59:43

智谱 GLM-4.7 抢先实测体验:Claude Code 的升级替代品!

这个页面&#xff0c;是 GLM-4.7 自己写的。 一次提示&#xff0c;没改过&#xff0c;直接出。 黑底荧光绿配色&#xff0c;3D 几何体在旋转&#xff0c;代码演示区有打字机动画&#xff0c;连鼠标光标都换成了霓虹绿的小圆点。 感谢智谱大大给了我新模型的内测资格。 抢先…

作者头像 李华
网站建设 2026/6/10 21:04:34

3步搞定复杂手机自动化:基于Open-AutoGLM的phoneagent快速上手教程

第一章&#xff1a;3步搞定复杂手机自动化&#xff1a;基于Open-AutoGLM的phoneagent快速上手教程在移动设备管理与测试领域&#xff0c;自动化操作已成为提升效率的核心手段。Open-AutoGLM 推出的 phoneagent 框架&#xff0c;结合大模型理解能力与设备控制接口&#xff0c;实…

作者头像 李华
网站建设 2026/6/12 13:32:31

35、Ruby编程:编译时、运行时与内置类的灵活运用

Ruby编程:编译时、运行时与内置类的灵活运用 1. Ruby的编译时与运行时特性 在Ruby中,“编译时”和“运行时”之间并没有显著的区别,它们本质上是相同的。这意味着你可以在运行过程中添加代码,动态重新定义方法,改变方法的作用域(例如从公共变为私有),甚至修改基本类型…

作者头像 李华
网站建设 2026/6/12 15:04:10

46、Ruby 核心类与标准库使用指南

Ruby 核心类与标准库使用指南 1. ThreadGroup 类 1.1 基本概念 ThreadGroup 类用于跟踪一组线程。一个线程在同一时间只能属于一个 ThreadGroup ,当将一个线程添加到一个组时,它会自动从当前组中移除。新创建的线程会属于创建它们的线程所在的组。 1.2 常量 Default …

作者头像 李华
网站建设 2026/6/12 15:43:13

47、Ruby 标准库实用功能解析

Ruby 标准库实用功能解析 1. Abbrev 库:生成唯一缩写集合 Abbrev 库的主要功能是为一组字符串生成唯一的缩写集合。它会返回一个哈希表,其中键是所有可能的缩写,值是完整的字符串。 1.1 使用方法 对于输入的字符串集合,如 “car” 和 “cone”,指向 “car” 的键为 “…

作者头像 李华