news 2026/2/26 12:11:32

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/2/24 15:53:39

C#使用EasyModbus进行通讯

C#使用EasyModbus进行通讯 EasyModbus是一个流行的.NET库&#xff0c;用于实现Modbus TCP、RTU和UDP协议通信。以下是使用EasyModbus库的基本指南&#xff1a; 安装EasyModbus 首先&#xff0c;你需要通过NuGet安装EasyModbus库&#xff1a; 在Visual Studio中&#xff0c…

作者头像 李华
网站建设 2026/2/18 4:46:09

phoneagent Open-AutoGLM性能优化秘籍(响应速度提升90%的底层逻辑)

第一章&#xff1a;phoneagent Open-AutoGLM性能优化的核心价值phoneagent 集成 Open-AutoGLM 框架后&#xff0c;在移动端智能任务处理中展现出卓越的推理效率与资源利用率。其核心价值在于通过动态计算图剪枝、量化感知训练和轻量级缓存机制&#xff0c;显著降低模型响应延迟…

作者头像 李华
网站建设 2026/2/26 10:52:46

Open-AutoGLM在Win11上的部署秘籍(仅限高级开发者知晓)

第一章&#xff1a;Open-AutoGLM部署前的高级准备 在将 Open-AutoGLM 投入生产环境之前&#xff0c;必须完成一系列高级准备工作&#xff0c;以确保系统稳定性、安全性与可扩展性。这些步骤涵盖硬件资源配置、依赖项管理、环境隔离以及安全策略设定。 硬件与系统要求评估 Open…

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

别再让 AI 自由发挥了!用 LangChain + Zod 强制它输出合法 JSON

用 LangChain Zod 构建类型安全的 AI 结构化输出 —— 从“一句话解释 Promise”开始大模型很聪明&#xff0c;但也很“自由”。 你让它解释 Promise&#xff0c;它可能回你一段优美的散文&#xff1b; 你想要一个干净的 JSON&#xff0c;它却在前后加上“好的&#xff01;”“…

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

24、云存储队列与表服务操作全解析

云存储队列与表服务操作全解析 在云存储的应用场景中,队列和表服务是非常重要的组成部分。下面将详细介绍队列消息的操作以及 Windows Azure 表服务的相关内容。 队列消息操作 消息入队 向队列中添加消息时,通过发送如下的 HTTP POST 请求: POST /testq1/messages?ti…

作者头像 李华