news 2026/4/27 4:02:02

TinyMCE导入word图片自动压缩尺寸

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
TinyMCE导入word图片自动压缩尺寸

深圳XX保险集团OA系统新闻模块升级项目实施记录
(基于信创环境的Vue2+TinyMCE+SpringBoot集成方案)

一、项目背景与需求分析

  1. 现状梳理

    • 集团OA系统新闻模块采用Vue2-cli前端框架,后端为SpringBoot 2.7.x,编辑器使用TinyMCE 5.x
    • 当前仅支持基础文本编辑,Word文档需手动复制内容并逐张上传图片,效率低下且样式丢失严重(如表格、字体、段落间距)。
  2. 核心需求

    • 功能升级:实现Word文档一键导入,自动解析文本、图片、表格等元素,图片上传至服务器并生成可访问URL,保留原格式。
    • 信创兼容:支持国产操作系统(麒麟V10、统信UOS)、数据库(达梦DM8、OceanBase)、中间件(东方通TongWeb 7.0)。
    • 服务保障:提供7×24小时在线技术支持,确保金融级系统稳定性(SLA≥99.95%)。

二、技术选型与产品评估

1. 前端编辑器扩展方案
方案优势劣势适配性评估
TinyMCE官方插件原生支持Vue2集成,可通过@tinymce/tinymce-vue组件快速调用;提供基础粘贴过滤功能需二次开发实现图片自动上传与复杂样式保留核心候选方案
第三方插件(如Mammoth.js)专注Word解析,能保留大部分样式(如标题、列表)图片处理需额外开发,社区支持较弱需结合TinyMCE使用,复杂度高
商业解决方案(如CKEditor 5高级版)功能完整,支持Word一键导入+图片云存储;提供信创认证版本授权费用高(约15万元/年);需替换现有编辑器,迁移成本大暂不考虑
开源方案(WordPaster)功能完整,支持Word一键导入+Word一键粘贴;提供信创认证版本完全开放产品源代码意向方案

结论:选择TinyMCE官方插件+自定义开发,通过拦截粘贴事件(paste)触发Word解析流程。

2. 后端服务选型
  • 文件处理:使用Apache POI解析.docx文件,提取文本、图片、元数据。
  • 图片存储:对接集团现有MinIO对象存储(兼容信创环境),生成带签名的临时URL供前端访问。
  • 信创中间件适配:在东方通TongWeb中配置JVM参数(-Xms512m -Xmx2048m),优化内存泄漏问题。

三、开发实施过程

1. 前端实现(Vue2+TinyMCE)
  • 步骤1:集成TinyMCE编辑器

    // main.jsimportTinymceVuefrom'@tinymce/tinymce-vue';Vue.component('tinymce-editor',TinymceVue);// 配置支持粘贴上传的插件consttinymceInit={plugins:'paste image',toolbar:'paste | undo redo | styleselect | bold italic',paste_preprocess:(plugin,args)=>{if(isWordContent(args.content)){handleWordPaste(args.content);// 触发自定义解析逻辑}},images_upload_handler:(blobInfo,success)=>{uploadImageToServer(blobInfo.blob()).then(url=>success(url));}};
  • 步骤2:Word内容解析与图片上传

    // utils/wordParser.jsexportasyncfunctionparseWordContent(wordBlob){constreader=newFileReader();reader.onload=async(e)=>{constarrayBuffer=e.target.result;constdoc=newXWPFDocument(arrayBuffer);// Apache POI解析consthtml=convertDocToHtml(doc);// 提取文本+样式constimages=extractImages(doc);// 提取图片Base64awaituploadImages(images);// 批量上传至MinIOreturnhtml.replace(/{{IMAGE_PLACEHOLDER}}/g,imageUrls);};reader.readAsArrayBuffer(wordBlob);}
2. 后端实现(SpringBoot)
  • 步骤1:图片上传接口

    @RestController@RequestMapping("/api/oa/news")publicclassNewsController{@AutowiredprivateMinioClientminioClient;@PostMapping("/upload-image")publicResponseEntityuploadImage(@RequestParam("file")MultipartFilefile){StringobjectName="oa-news-images/"+UUID.randomUUID()+".png";minioClient.putObject(PutObjectArgs.builder().bucket("xx-insurance").object(objectName).stream(file.getInputStream(),file.getSize(),-1).contentType(file.getContentType()).build());returnResponseEntity.ok("https://minio.xxinsurance.com/"+objectName);}}
  • 步骤2:Word文档解析服务

    @ServicepublicclassWordParserService{publicStringparseDocxToHtml(MultipartFilefile)throwsIOException{XWPFDocumentdocument=newXWPFDocument(file.getInputStream());StringBuilderhtml=newStringBuilder("");for(XWPFParagraphparagraph:document.getParagraphs()){html.append("").append(paragraph.getText()).append("");}// 处理表格、图片等复杂元素...html.append("");returnhtml.toString();}}
3. 信创环境适配
  • 数据库兼容:将JPA的@GeneratedValue策略改为GenerationType.IDENTITY,适配达梦DM8的自增主键。
  • 字体渲染:在服务器部署中文字体包(如思源黑体、方正仿宋),避免Word导入后显示方框。
  • 安全加固:对上传的Word文件进行病毒扫描(集成麒麟系统自带的杀毒API)。

四、测试与部署

1. 测试用例
测试类型测试场景预期结果
功能测试导入含表格、图片的Word文档表格结构完整,图片可正常显示
兼容性测试在麒麟V10+统信UOS双系统下操作编辑器加载时间<3秒,无样式错乱
性能测试同时上传10个5MB的Word文件服务器CPU占用率≤70%,响应时间<5秒
安全测试上传恶意脚本文件(.docx)系统拦截并记录日志,返回403错误
2. 部署方案
  • 内网环境:使用Kubernetes集群部署,通过Nginx Ingress实现蓝绿发布。
  • 外网访问:通过集团SD-WAN网络加密传输,限制IP访问权限(仅允许内网IP+分支机构IP)。

五、技术支持与运维保障

  1. 服务承诺

    • 提供7×24小时企业微信/电话支持,紧急问题1小时内响应。
    • 每月出具《系统健康度报告》,包含性能趋势、安全漏洞扫描结果。
  2. 知识转移

    • 编制《信创环境下Vue2+TinyMCE开发指南》,包含常见问题(如字体丢失、表格错位)的解决方案。
    • 对集团IT团队进行3次现场培训(每次2小时),覆盖日志分析、性能调优、灾备演练。

六、项目成果

  • 效率提升:新闻发布时间从平均1.5小时缩短至20分钟(含Word导入+审核)。
  • 信创认证:通过国家工业信息安全发展研究中心认证(证书编号:CII-2023-XXXXXX)。
  • 成本节约:相比商业解决方案,节省授权费用约18万元/年。

附录

  • 完整代码库地址:[GitLab私有仓库链接]
  • 测试报告:[PDF文档链接]
  • 技术支持联系方式:企业微信群「XX保险OA升级支持组」 | 紧急电话:0755-XXXXXXX

记录人:XX保险集团信息技术部
日期: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/4/27 0:46:31

软件测试(1):基础知识总结

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 概念与定义软件危机&#xff1a;软件危机是指落后的软件生产方式无法满足迅速增长的计算机软件需求&#xff0c;从而导致软件开发与维护过程中出现一系列严重问…

作者头像 李华
网站建设 2026/4/27 0:46:30

wangEditor实现word文档公式粘贴转MathML

《独立开发者的"富文本粘贴攻坚战"&#xff1a;从Word地狱到云端救赎的技术实录》 ——上海.NET程序员的破局之路 第一章&#xff1a;当需求文档变成"技术恐怖片" 作为独立开发者&#xff0c;我独自维护着一个基于Vue2 wangEditor的文档协作平台。某天&…

作者头像 李华
网站建设 2026/4/25 1:46:25

SpaceCadetPinball开源项目终极指南:重温经典弹球游戏

SpaceCadetPinball开源项目终极指南&#xff1a;重温经典弹球游戏 【免费下载链接】SpaceCadetPinball Decompilation of 3D Pinball for Windows – Space Cadet 项目地址: https://gitcode.com/gh_mirrors/sp/SpaceCadetPinball SpaceCadetPinball是一个令人惊叹的开源…

作者头像 李华
网站建设 2026/4/24 9:26:44

15、让树莓派脱离束缚,开启户外之旅

让树莓派脱离束缚,开启户外之旅 在户外使用树莓派进行任务时,有几个关键方面需要考虑,包括电源供应、设备保护、网络连接等。下面将详细介绍相关内容。 电源与设备保护 当把树莓派用于户外任务时,主要需要解决电源供应和防潮问题。 电源选择 :锂聚合物电池组是为树莓…

作者头像 李华
网站建设 2026/4/20 16:34:25

10、网络摄像头与视频魔法

网络摄像头与视频魔法 1. 证据收集 当我们完成了 Motion 的初始设置后,就需要决定系统在检测到活动时应采取的行动。常见的响应包括发出警报、保存检测到的活动的图像和视频、将活动记录到数据库,或者通过电子邮件发出警报。 - 创建证据目录 : pi@raspberrypi ~ $ mk…

作者头像 李华
网站建设 2026/4/20 1:32:57

仿写文章Prompt:NumberFlow SSR技术深度解析

仿写文章Prompt&#xff1a;NumberFlow SSR技术深度解析 【免费下载链接】number-flow An animated number component for React, Vue, and Svelte. 项目地址: https://gitcode.com/gh_mirrors/nu/number-flow 请基于NumberFlow项目的SSR功能&#xff0c;撰写一篇技术深…

作者头像 李华