2026/4/16 23:38:03
网站建设
项目流程
怎么做一个自己的网站,php手机网站开发工具,做网站建设的公司有哪些内容,wordpress个人介绍《.NET程序员的CMS升级记#xff1a;Word一键粘贴公式全兼容#xff0c;680元预算搞掂#xff01;》
一、客户爸爸的需求
“小王啊#xff0c;我们领导说每次从Word复制新闻到后台#xff0c;表格变形、公式变乱码#xff0c;连图片都丢了…” “张总#xff0c;我调研…《.NET程序员的CMS升级记Word一键粘贴公式全兼容680元预算搞掂》一、客户爸爸的需求“小王啊我们领导说每次从Word复制新闻到后台表格变形、公式变乱码连图片都丢了…”“张总我调研了要支持Word/Excel/PPT/PDF全格式还得兼容MathType和LaTeX公式预算…”“680元多一分没有要能直接粘贴Word内容保留所有样式”被客户按在地上摩擦后我摸着所剩无几的头发决定用680元预算给wangEditor加个黑科技插件实现Word/Excel/PPT/PDF/公众号一键导入图片自动上传OSSLaTeX/MathType公式自动转MathML多端高清显示表格/字体/颜色/形状样式全保留包括刁钻的emz/wmz格式开箱即用不破坏现有业务逻辑二、技术选型性价比版组件方案成本编辑器wangEditor 自定义插件免费文档解析Docx.jsWord SheetJSExcel pdf.jsPDF免费公式转换KaTeXLaTeX→MathML免费文件上传阿里云OSS SDK免费后端接口ASP.NET WebForm原生代码免费调试工具VS2022 Postman免费总预算680元预留给OSS流量费群红包三、前端实现Vue2 wangEditor1. 安装依赖npminstallwangeditor docx-preview xlsx pdfjs-dist katex --save2. 自定义编辑器插件// src/plugins/OfficeImportPlugin.jsimportEditorfromwangeditorimport*asdocxfromdocx-previewimport*asXLSXfromxlsximport{getDocument}frompdfjs-distimportkatexfromkatexexportdefaultclassOfficeImportPlugin{constructor(editor,ossConfig){this.editoreditorthis.ossConfigossConfigthis.initButton()}initButton(){const{editor}thiseditor.config.menus[...editor.config.menus,officeImport]// 注册菜单按钮editor.config.customUploadImgasync(files,insertFn){awaitthis.uploadFiles(files,insertFn)}// 监听粘贴事件editor.config.customPaste(e){this.handlePaste(e)}}asynchandlePaste(e){constitems(e.clipboardData||window.clipboardData).itemsfor(letitemofitems){// 处理Word粘贴if(item.type.includes(office)){constfileitem.getAsFile()awaitthis.importOfficeFile(file)e.preventDefault()}// 处理公众号图文粘贴简化版elseif(item.type.includes(text/html)){consthtmlawaitnewPromise(resolveitem.getAsString(resolve))if(html.includes(mp.weixin.qq.com)){awaitthis.importWechatContent(html)e.preventDefault()}}}}asyncimportOfficeFile(file){constextfile.name.split(.).pop().toLowerCase()lethtmlif(extdocx){constarrayBufferawaitfile.arrayBuffer()htmlawaitdocx.renderAsync(arrayBuffer,document.createElement(div))}elseif(extxlsx){constdataawaitfile.arrayBuffer()constworkbookXLSX.read(data)htmlXLSX.utils.sheet_to_html(workbook.Sheets[workbook.SheetNames[0]])}elseif(extpdf){constpdfawaitgetDocument(awaitfile.arrayBuffer()).promise// PDF转HTML逻辑需自行实现}// 处理公式和图片awaitthis.processContent(html)}asyncprocessContent(html){// 1. 替换公式LaTeX转MathMLhtmlhtml.replace(/\$\$(.*?)\$\$/g,(match,latex){try{returnkatex.renderToString(latex,{throwOnError:false,output:mathml})}catch{returnmatch// 失败保留原样}})// 2. 处理图片上传OSSconsttempDivdocument.createElement(div)tempDiv.innerHTMLhtmlconstimgstempDiv.querySelectorAll(img[src^data:])for(letimgofimgs){constfilethis.dataURLtoFile(img.src,pasted-image.png)consturlawaitthis.uploadToOSS(file)img.srcurl}this.editor.cmd.do(insertHTML,tempDiv.innerHTML)}// 上传到OSS简化版asyncuploadToOSS(file){constformDatanewFormData()formData.append(file,file)constresponseawaitfetch(/api/upload,{method:POST,body:formData})return(awaitresponse.json()).url}}3. 集成到Vue组件import Editor from wangeditor import OfficeImportPlugin from ./plugins/OfficeImportPlugin export default { data() { return { editor: null, ossConfig: { region: oss-cn-hangzhou, accessKeyId: your-key, accessKeySecret: your-secret, bucket: your-bucket } } }, mounted() { this.editor new Editor({ selector: [this.$refs.editorMenu, this.$refs.editorContent], onChange: () console.log(内容变化) }) new OfficeImportPlugin(this.editor, this.ossConfig) this.editor.create() } }四、后端实现ASP.NET WebForm1. OSS上传接口// api/upload.ashx%WebHandlerLanguageC#ClassUploadHandler%usingSystem;usingSystem.IO;usingSystem.Web;usingAliyun.OSS;publicclassUploadHandler:IHttpHandler{publicvoidProcessRequest(HttpContextcontext){context.Response.ContentTypeapplication/json;varfilecontext.Request.Files[0];varobjectNameuploads/Guid.NewGuid().ToString()Path.GetExtension(file.FileName);// 阿里云OSS配置建议从Web.config读取varendpointhttps://oss-cn-hangzhou.aliyuncs.com;varaccessKeyIdyour-key;varaccessKeySecretyour-secret;varbucketNameyour-bucket;varclientnewOssClient(endpoint,accessKeyId,accessKeySecret);using(varstreamfile.InputStream){client.PutObject(bucketName,objectName,stream);}context.Response.Write(${{\url\:\https://{bucketName}.{endpoint}/{objectName}\}});}publicboolIsReusablefalse;}2. 公众号内容处理接口简化版// api/wechat.ashx%WebHandlerLanguageC#ClassWechatHandler%usingSystem;usingSystem.Web;usingHtmlAgilityPack;publicclassWechatHandler:IHttpHandler{publicvoidProcessRequest(HttpContextcontext){varhtmlcontext.Request.Form[html];vardocnewHtmlDocument();doc.LoadHtml(html);// 提取公众号正文简化版varcontentNodedoc.DocumentNode.SelectSingleNode(//div[idjs_content]);if(contentNode!null){// 处理公众号图片替换为OSS地址foreach(varimgincontentNode.SelectNodes(//img)){vardataSrcimg.GetAttributeValue(data-src,);if(!string.IsNullOrEmpty(dataSrc)){// 这里应该下载图片并上传到OSSimg.SetAttributeValue(src,dataSrc);}}context.Response.Write(contentNode.OuterHtml);}else{context.Response.Write(html);}}publicboolIsReusablefalse;}五、部署优化跨域问题在阿里云OSS配置CORS规则[{AllowedOrigin:[*],AllowedMethod:[GET,POST,PUT],AllowedHeader:[*]}]性能优化使用CDN加速KaTeX资源对大文件分片上传启用OSS图片处理缩略图/水印安全加固接口添加防伪令牌验证限制上传文件类型对LaTeX公式进行XSS过滤六、求职彩蛋各位同行我们外包群现在搞活动加入QQ群223813913 领1-99元红包推荐客户拿20%提成黄金会员50%内推简历优先处理群主在郑州/深圳有HR资源PS群文件有完整源码部署文档支持Vue2无缝迁移ASP.NET后端可直接发布到IIS最终效果客户测试后“这比Word还好用”预算分配600元OSS流量费按实际使用50元群红包30元咖啡续命费风险提示emz/wmz格式需要额外转换工具复杂公式可能需要手动调整公众号图片防盗链需特殊处理全文完求打赏/转发/内推三连复制插件文件安装jquerynpm install jquery导入组件importEfromwangeditorconst{$,BtnMenu,DropListMenu,PanelMenu,DropList,Panel,Tooltip}Eimport{WordPaster}from../../static/WordPaster/js/wimport{zyCapture}from../../static/zyCapture/zimport{zyOffice}from../../static/zyOffice/js/o初始化组件//zyCapture ButtonclasszyCaptureBtnextendsBtnMenu{constructor(editor){const$elemE.$(div classw-e-menu>)super($elem,editor)}clickHandler(){window.zyCapture.setEditor(this.editor).Capture();}tryChangeActive(){this.active()}}//zyOffice ButtonclassimportWordBtnextendsBtnMenu{constructor(editor){const$elemE.$(div classw-e-menu>)super($elem,editor)}clickHandler(){window.zyOffice.SetEditor(this.editor).api.openDoc();}tryChangeActive(){this.active()}}//zyOffice ButtonclassexportWordBtnextendsBtnMenu{constructor(editor){const$elemE.$(div classw-e-menu>)super($elem,editor)}clickHandler(){window.zyOffice.SetEditor(this.editor).api.exportWord();}tryChangeActive(){this.active()}}//zyOffice ButtonclassimportPdfBtnextendsBtnMenu{constructor(editor){const$elemE.$(div classw-e-menu>)super($elem,editor)}clickHandler(){window.zyOffice.SetEditor(this.editor).api.openPdf();}tryChangeActive(){this.active()}}//WordPaster ButtonclassWordPasterBtnextendsBtnMenu{constructor(editor){const$elemE.$(div classw-e-menu>)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).Paste();}tryChangeActive(){this.active()}}//wordImport ButtonclassWordImportBtnextendsBtnMenu{constructor(editor){const$elemE.$(div classw-e-menu>)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importWord();}tryChangeActive(){this.active()}}//excelImport ButtonclassExcelImportBtnextendsBtnMenu{constructor(editor){const$elemE.$(div classw-e-menu>)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importExcel();}tryChangeActive(){this.active()}}//ppt paster ButtonclassPPTImportBtnextendsBtnMenu{constructor(editor){const$elemE.$(div classw-e-menu>)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importPPT();}tryChangeActive(){this.active()}}//pdf paster ButtonclassPDFImportBtnextendsBtnMenu{constructor(editor){const$elemE.$(div classw-e-menu>)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor);WordPaster.getInstance().ImportPDF();}tryChangeActive(){this.active()}}//importWordToImg ButtonclassImportWordToImgBtnextendsBtnMenu{constructor(editor){const$elemE.$(div classw-e-menu>)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importWordToImg();}tryChangeActive(){this.active()}}//network paster ButtonclassNetImportBtnextendsBtnMenu{constructor(editor){const$elemE.$(div classw-e-menu>)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor);WordPaster.getInstance().UploadNetImg();}tryChangeActive(){this.active()}}exportdefault{name:HelloWorld,data(){return{msg:Welcome to Your Vue.js App}},mounted(){vareditornewE(#editor);WordPaster.getInstance({//上传接口http://www.ncmem.com/doc/view.aspx?idd88b60a2b0204af1ba62fa66288203edPostUrl:http://localhost:8891/upload.aspx,License2:,//为图片地址增加域名http://www.ncmem.com/doc/view.aspx?id704cd302ebd346b486adf39cf4553936ImageUrl:http://localhost:8891{url},//设置文件字段名称http://www.ncmem.com/doc/view.aspx?idc3ad06c2ae31454cb418ceb2b8da7c45FileFieldName:file,//提取图片地址http://www.ncmem.com/doc/view.aspx?id07e3f323d22d4571ad213441ab8530d1ImageMatch:});zyCapture.getInstance({config:{PostUrl:http://localhost:8891/upload.aspx,License2:,FileFieldName:file,Fields:{uname:test},ImageUrl:http://localhost:8891{url}}})// zyoffice// 使用前请在服务端部署zyoffice// http://www.ncmem.com/doc/view.aspx?id82170058de824b5c86e2e666e5be319czyOffice.getInstance({word:http://localhost:13710/zyoffice/word/convert,wordExport:http://localhost:13710/zyoffice/word/export,pdf:http://localhost:13710/zyoffice/pdf/upload})// 注册菜单E.registerMenu(zyCaptureBtn,zyCaptureBtn)E.registerMenu(WordPasterBtn,WordPasterBtn)E.registerMenu(ImportWordToImgBtn,ImportWordToImgBtn)E.registerMenu(NetImportBtn,NetImportBtn)E.registerMenu(WordImportBtn,WordImportBtn)E.registerMenu(ExcelImportBtn,ExcelImportBtn)E.registerMenu(PPTImportBtn,PPTImportBtn)E.registerMenu(PDFImportBtn,PDFImportBtn)E.registerMenu(importWordBtn,importWordBtn)E.registerMenu(exportWordBtn,exportWordBtn)E.registerMenu(importPdfBtn,importPdfBtn)//挂载粘贴事件editor.txt.eventHooks.pasteEvents.length0;editor.txt.eventHooks.pasteEvents.push(function(){WordPaster.getInstance().SetEditor(editor).Paste();e.preventDefault();});editor.create();varedt2newE(#editor2);//挂载粘贴事件edt2.txt.eventHooks.pasteEvents.length0;edt2.txt.eventHooks.pasteEvents.push(function(){WordPaster.getInstance().SetEditor(edt2).Paste();e.preventDefault();return;});edt2.create();}}h1,h2{font-weight:normal;}ul{list-style-type:none;padding:0;}li{display:inline-block;margin:010px;}a{color:#42b983;}测试前请配置图片上传接口并测试成功接口测试接口返回JSON格式参考为编辑器添加按钮components:{Editor,Toolbar},data(){return{editor:null,html:dd,toolbarConfig:{insertKeys:{index:0,keys:[zycapture,wordpaster,pptimport,pdfimport,netimg,importword,exportword,importpdf]}},editorConfig:{placeholder:},mode:default// or simple}},整合效果导入Word文档,支持doc,docx导入Excel文档,支持xls,xlsx粘贴Word一键粘贴Word内容自动上传Word中的图片保留文字样式。Word转图片一键导入Word文件并将Word文件转换成图片上传到服务器中。导入PDF一键导入PDF文件并将PDF转换成图片上传到服务器中。导入PPT一键导入PPT文件并将PPT转换成图片上传到服务器中。上传网络图片一键自动上传网络图片自动下载远程服务器图片自动上传远程服务器图片下载示例点击下载完整示例