亚马逊FBA仓储成本上升背景下的库存路径比较:BBWEYY独立站分流与周转策略,含零代码SAAS、AI编程、源码定制交付
2026/7/31 17:10:37
“导师说CMS要支持Word一键粘贴,还要保留Latex公式和表格样式?这比让我 debug 隔壁宿舍的WiFi还刺激!”
localhost)npminstall@tinymce/tinymce-vue tinymce --saveimport { ref } from 'vue'; import Editor from '@tinymce/tinymce-vue'; import 'tinymce/themes/silver'; import 'tinymce/plugins/paste'; import 'tinymce/plugins/table'; import 'tinymce/plugins/image'; import 'tinymce/plugins/advlist'; const content = ref(''); const editorInit = { height: 500, plugins: 'paste table image advlist', toolbar: 'wordpaste | styleselect | bold italic | table | image', setup: (editor) => { editor.ui.registry.addButton('wordpaste', { text: 'Word粘贴', onAction: () => { editor.execCommand('mceInsertContent', false, '<div class="word-paste-placeholder">请在此粘贴Word内容</div>' ); } }); }, paste_data_images: true, // 允许粘贴图片 images_upload_handler: (blobInfo, success) => uploadImage(blobInfo, success) }; // 处理粘贴内容 const handlePaste = (e) => { const wordHtml = e.clipboardData.getData('text/html'); if (wordHtml.includes('mso-')) { // 判断是否为Word内容 fetch('/api/parseWord', { method: 'POST', body: JSON.stringify({ html: wordHtml }), headers: { 'Content-Type': 'application/json' } }) .then(res => res.json()) .then(data => { content.value = data.processedHtml; }); } }; // 图片上传到OSS const uploadImage = async (blobInfo, success) => { const formData = new FormData(); formData.append('file', blobInfo.blob(), blobInfo.filename()); const res = await fetch('/api/uploadImage', { method: 'POST', body: formData }); const data = await res.json(); success(data.url); // 返回图片URL给编辑器 };// WordParserServlet.java@WebServlet("/api/parseWord")@MultipartConfigpublicclassWordParserServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{// 1. 读取前端传来的HTML(模拟Word粘贴)StringBuildersb=newStringBuilder();Stringline;while((line=request.getReader().readLine())!=null){sb.append(line);}Stringhtml=sb.toString();// 2. 提取图片并上传OSS(伪代码,需配置阿里云SDK)PatternimgPattern=Pattern.compile("]+src=\"data:image/(.*?);base64,([^\"]+)\"");Matchermatcher=imgPattern.matcher(html);while(matcher.find()){Stringbase64Data=matcher.group(2);byte[]imgBytes=Base64.getDecoder().decode(base64Data);StringossUrl=OSSUploader.upload(imgBytes,"word-images/"+UUID.randomUUID()+".png");html=html.replace(matcher.group(0),"");}// 3. 处理Latex公式(调用Node服务或本地转换)html=html.replaceAll("\\$\\$(.+?)\\$\\$","$1");// 4. 返回处理后的HTMLresponse.setContentType("application/json");response.getWriter().write("{\"processedHtml\": \""+html.replace("\"","\\\"")+"\"}");}}// ImageUploadServlet.java@WebServlet("/api/uploadImage")@MultipartConfigpublicclassImageUploadServletextendsHttpServlet{protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{PartfilePart=request.getPart("file");InputStreamfileContent=filePart.getInputStream();StringossUrl=OSSUploader.upload(fileContent,"editor-images/"+UUID.randomUUID()+".png");response.setContentType("application/json");response.getWriter().write("{\"url\": \""+ossUrl+"\"}");}}// OSSUploader.javaimportcom.aliyun.oss.OSS;importcom.aliyun.oss.OSSClientBuilder;publicclassOSSUploader{privatestaticfinalStringENDPOINT="your-oss-endpoint";privatestaticfinalStringACCESS_KEY="your-access-key";privatestaticfinalStringSECRET_KEY="your-secret-key";privatestaticfinalStringBUCKET="your-bucket";publicstaticStringupload(byte[]data,StringobjectName){OSSossClient=newOSSClientBuilder().build(ENDPOINT,ACCESS_KEY,SECRET_KEY);ossClient.putObject(BUCKET,objectName,newByteArrayInputStream(data));ossClient.shutdown();return"https://"+BUCKET+"."+ENDPOINT+"/"+objectName;}publicstaticStringupload(InputStreaminputStream,StringobjectName){OSSossClient=newOSSClientBuilder().build(ENDPOINT,ACCESS_KEY,SECRET_KEY);ossClient.putObject(BUCKET,objectName,inputStream);ossClient.shutdown();return"https://"+BUCKET+"."+ENDPOINT+"/"+objectName;}}在前端引入 KaTeX,处理 Latex 公式:
在 TinyMCE 初始化后动态渲染公式:
// 在 mounted 或编辑器初始化后调用functionrenderMath(){document.querySelectorAll('.mathml').forEach(el=>{katex.render(el.textContent,el,{throwOnError:false});});}白嫖资源:
求职暗号:
# 技术栈 - 精通用99元预算完成企业级需求 - 擅长在JSP和Vue3之间搭建“跨世代”桥梁赚钱攻略:
// 伪代码:计算提成publicdoublecalcCommission(doubleorderAmount){returnorderAmount*0.2;// 青铜会员// 黄金会员?先拉5个下线再说}![示意图:TinyMCE编辑器中显示Word内容,包含表格、图片、公式,右侧为工具栏新增的“Word粘贴”按钮]
(实际效果取决于你的头发浓度)
加入技术交流群获取完整代码:
tinymce-word-paste-plugin.zip(前端插件)jsp-word-parser.war(后端打包)(温馨提示:本群不保证月入过万,但保证能学会用Excel算提成)
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转换成图片上传到服务器中。
一键自动上传网络图片。
点击下载完整示例