【Offer来了】5分钟掌握组件封装面试要点,面试官再也不会说你基础不扎实
2026/7/4 7:58:45
黑龙江XX集团站群新闻功能升级项目实施记录
(基于信创环境的TinyMCE扩展与SpringBoot集成方案)
现状梳理
核心需求
| 方案 | 优势 | 劣势 | 适配性评估 |
|---|---|---|---|
| TinyMCE官方插件 | 原生集成,开发成本低;支持基础Word粘贴(仅文本+简单格式) | 图片无法自动上传,复杂样式(如表格、背景色)易丢失 | 需二次开发,信创环境需验证 |
| 第三方插件(如Pell富文本) | 开源免费,支持Word图片自动上传 | 文档兼容性差,样式保留不完整;社区支持弱 | 不满足核心需求,排除 |
| 商业解决方案(如UEditor、CKEditor企业版) | 功能完整,支持Word一键导入+图片自动上传;提供信创认证版本 | 成本较高(年费制);部分功能需定制开发 | 需评估预算与长期合作可行性 |
| 自研扩展组件 | 完全可控,可深度定制;适配信创环境 | 开发周期长(预估3-6个月);需维护独立代码库 | 风险较高,暂不考虑 |
结论:选择TinyMCE官方插件+定制开发,结合Apache POI解析Word文档,实现图片自动上传与样式保留。
@Column转@DmColumn)。前端(TinyMCE扩展)
tiny-mce-wordimport插件,监听paste事件,拦截Word内容。FileReader解析.docx文件,提取文本、图片Base64数据。后端(SpringBoot)
WordImportController,接收图片Base64数据并存储至MinIO对象存储。XWPFDocument类解析Word文档结构,生成JSON格式的样式数据。WordStyleConverter工具类,将Word样式映射为TinyMCE支持的HTML标签(如``)。// 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();}.jpg/.png),对Word内容进行XSS过滤。测试用例
部署方案
服务承诺
知识转移
附录:
记录人:XXX集团技术中心
日期:2025年XX月XX日
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内容,自动上传Word中的图片,保留文字样式。
一键导入Word文件,并将Word文件转换成图片上传到服务器中。
一键导入PDF文件,并将PDF转换成图片上传到服务器中。
一键导入PPT文件,并将PPT转换成图片上传到服务器中。
一键自动上传网络图片。
点击下载完整示例