钢铁的意志,羁绊的传承小南与长门,重塑忍界的崭新篇章_1

核心内容摘要

17.c.cow
R星往期内容——今日大赛:一场穿越时空的数字嘉年华

91网页点开即看

日期2023年X月X日角色北京XX软件公司 全栈开发工程师.NET Core Vue2项目背景客户要求在后台管理系统的文章发布模块新增三大功能Word粘贴功能支持从Word复制内容粘贴到UEditor图片自动上传至内网单据存储服务器二进制存储非Base64保留样式字体、字号、颜色等。

文档导入功能支持上传Word/Excel/PPT/PDF解析内容并保留图片和样式渲染至UEditor。

微信公众号内容粘贴支持从微信公众号编辑器复制内容含富文本和图片并粘贴到UEditor图片自动上传至内网服务器。

技术栈前端Vue2-cli UEditor富文本编辑器后端.NET Core 6C#数据库SQL Server存储文章元数据图片路径存储在文件系统或对象存储服务器内网私有部署未来支持多云对象存储

技术可行性分析与工具选型

Word粘贴功能核心问题浏览器原生粘贴事件无法直接处理Word中的复杂样式如mso-前缀的CSS和图片图片以剪贴板对象或二进制流形式存在。

UEditor默认会过滤Word特有的HTML标签和样式需自定义过滤规则。

图片需从剪贴板提取二进制数据并上传至内网服务器生成可访问的URL。

解决方案前端使用Clipboard API拦截粘贴事件提取HTML和图片二进制数据通过FileReader或FormData。

调用.NET Core后端接口上传图片替换HTML中的本地图片路径为服务器URL。

调整UEditor配置保留Word相关CSS属性如font-family、color。

后端.NET Core提供图片上传接口接收二进制流并保存至内网服务器返回访问路径。

支持未来迁移至对象存储如阿里云OSS通过依赖注入切换存储服务。

工具评估NPOI开源.NET库支持Word/Excel/PPT解析但需手动处理样式和图片提取。

OpenXML SDK微软官方库支持Word文档.docx解析可提取图片二进制数据。

iTextSharpPDF解析库但样式保留能力有限。

Aspose.Words商业库支持所有格式且样式保留完整但需授权。

泽优WordPaster开源库支持所有格式且样式保留完整完全开放产品源代码下载源码。

结论Word粘贴前端使用Clipboard APIFormData上传图片后端用OpenXML SDK处理复杂样式备用方案Aspose.Words试用版。

图片存储直接上传二进制流至服务器避免Base64转换。

文档导入功能核心问题需支持多种格式Word/Excel/PPT/PDF并保留样式和图片。

大文件如PPT解析性能优化避免阻塞主线程。

图片需从文档中提取为二进制并上传至服务器。

解决方案后端.NET CoreWord/Excel/PPT使用OpenXML SDK开源或Aspose商业解析文档提取文本、图片二进制数据和样式。

PDF使用iTextSharp或PdfPig开源解析文本图片需额外处理。

图片上传至内网服务器生成URL替换文档中的本地路径。

前端通过文件上传组件如el-upload将文档发送至后端。

后端返回解析后的HTML注入UEditor。

工具评估OpenXML SDK免费但API复杂需手动处理样式映射。

Aspose.Total全功能商业库支持所有格式但成本较高。

LibreOffice通过命令行转换文档为HTML但需服务器安装且样式可能丢失。

结论优先方案OpenXML SDKWord/Excel/PPT iTextSharpPDF样式保留不足时手动补充CSS。

备选方案评估泽优WordPaster源码版满足公司自主安全可控需求没有授权限制。

微信公众号内容粘贴核心问题微信公众号编辑器导出的HTML可能包含微信特有的CSS类名如wx_fmt_*。

图片以微信CDN链接形式存在需下载二进制数据并上传至内网服务器。

解决方案前端拦截粘贴事件提取HTML中的微信图片URL。

通过.NET Core后端接口下载图片二进制数据并上传至内网服务器替换HTML中的CDN链接。

后端使用HttpClient下载微信图片保存为二进制文件至内网服务器。

工具评估HttpClient.NET Core标准库支持异步下载图片。

HtmlAgilityPack解析HTML并提取图片URL。

结论自定义实现前端处理HTML替换后端提供下载服务。

开发过程记录

Word粘贴功能实现前端Vue2 UEditor// 监听UEditor粘贴事件consteditorUE.getEditor(editor);editor.addListener(beforePaste,function(){// 阻止默认粘贴行为手动处理returnfalse;});editor.addListener(ready,function(){document.getElementById(editor).addEventListener(paste,async(e){e.preventDefault();constclipboardDatae.clipboardData||window.clipboardData;consthtmlclipboardData.getData(text/html);constfilesclipboardData.files;if(htmlfiles.length

{constformDatanewFormData();for(leti0;ifiles.length;i){formData.append(files,files[i]);// 图片二进制数据}// 调用后端上传图片接口constresponseawaitaxios.post(/api/upload/word-images,formData,{headers:{Content-Type:multipart/form-data}});// 替换HTML中的图片路径为服务器URLletnewHtmlhtml;response.data.urls.forEach((url,index){newHtmlnewHtml.replace(/src[]?([^]*)[]?/g,(match,src){if(src.startsWith(blob:)||src.startsWith(cid:)){returnsrc${url};}returnmatch;});});editor.setContent(newHtml);// 更新编辑器内容}});});后端.NET Core 6// 图片上传接口接收二进制流[ApiController][Route(api/upload)]publicclassUploadController:ControllerBase{privatereadonlyIWebHostEnvironment_env;privatereadonlyIConfiguration_config;publicUploadController(IWebHostEnvironmentenv,IConfigurationconfig){_envenv;_configconfig;}[HttpPost(word-images)]publicasyncTaskUploadWordImages(Listfiles){varuploadPathPath.Combine(_env.WebRootPath,uploads);if(!Directory.Exists(uploadPath))Directory.CreateDirectory(uploadPath);varurlsnewList();foreach(varfileinfiles){varfileName${Guid.NewGuid()}{Path.GetExtension(file.FileName)};varfilePathPath.Combine(uploadPath,fileName);using(varstreamnewFileStream(filePath,FileMode.Create)){awaitfile.CopyToAsync(stream);// 直接保存二进制数据}// 返回内网可访问的URL需配置Nginx反向代理varurl${Request.Scheme}://{Request.Host}/uploads/{fileName};urls.Add(url);}returnOk(new{urls});}}

文档导入功能实现后端.NET Core 6 OpenXML SDK// Word导入示例DOCX[HttpPost(import/docx)]publicasyncTaskImportDocx(IFormFilefile){using(varstreamnewMemoryStream()){awaitfile.CopyToAsync(stream);using(vardocumentWordprocessingDocument.Open(stream,false)){varbodydocument.MainDocumentPart.Document.Body;varhtmlBuildernewStringBuilder();foreach(varparagraphinbody.Descendants()){htmlBuilder.Append();foreach(varruninparagraph.Descendants()){htmlBuilder.Append();htmlBuilder.Append(run.GetFirstChild()?.Text??);htmlBuilder.Append();}// 处理段落中的图片二进制提取foreach(vardrawinginparagraph.Descendants()){varimagePartdocument.MainDocumentPart.GetPartById(drawing.Descendants().First().Embed.Value)asImagePart;if(imagePart!null){using(varimageStreamnewMemoryStream()){imagePart.FeedData(imageStream);varimageBytesimageStream.ToArray();// 上传图片至服务器调用UploadController逻辑varimageUrlawaitUploadImageToServer(imageBytes,docx-import);htmlBuilder.Append($);}}}htmlBuilder.Append();}returnOk(htmlBuilder.ToString());}}}// 图片上传辅助方法privateasyncTaskUploadImageToServer(byte[]imageBytes,stringprefix){varfileName${prefix}_{Guid.NewGuid()}.jpg;varfilePathPath.Combine(_env.WebRootPath,uploads,fileName);awaitSystem.IO.File.WriteAllBytesAsync(filePath,imageBytes);return${Request.Scheme}://{Request.Host}/uploads/{fileName};}前端Vue2文件上传export default { methods: { handleImportSuccess(response) { const editor UE.getEditor(editor); editor.setContent(response); // 注入解析后的HTML } } };

微信公众号内容粘贴实现前端Vue2asyncfunctionhandleWechatPaste(html){// 提取微信图片URL示例srchttps://mmbiz.qpic.cn/...)constimgTagshtml.match(/]srchttps:\/\/mmbiz\.qpic\.cn[^]/g)||[];for(constimgTagofimgTags){consturlimgTag.match(/src([^])/)[1];constresponseawaitdownloadFromWechat(url);// 调用后端接口constnewImgTagimgTag.replace(url,response.url);htmlhtml.replace(imgTag,newImgTag);}consteditorUE.getEditor(editor);editor.setContent(html);}asyncfunctiondownloadFromWechat(url){constresponseawaitaxios.get(/api/download/wechat-image,{params:{url},responseType:arraybuffer// 接收二进制数据});// 调用图片上传接口复用Word粘贴的上传逻辑constformDatanewFormData();constblobnewBlob([response.data],{type:image/jpeg});formData.append(file,blob,wechat-image.jpg);constuploadResponseawaitaxios.post(/api/upload/word-images,formData);return{url:uploadResponse.data.urls[0]};}后端.NET Core 6// 下载微信图片接口[HttpGet(download/wechat-image)]publicasyncTaskDownloadWechatImage([FromQuery]stringurl){using(varclientnewHttpClient()){varresponseawaitclient.GetAsync(url);if(!response.IsSuccessStatusCode)returnBadRequest(Failed to download image);varimageBytesawaitresponse.Content.ReadAsByteArrayAsync();returnFile(imageBytes,image/jpeg);// 返回二进制流}}

问题与优化性能问题大文件解析如PPT采用异步任务队列如Hangfire优化。

样式兼容性Word中的复杂样式如文本框需手动转换为HTML/CSS或通过Aspose.Words自动处理。

安全性对上传文件进行MIME类型校验防止恶意文件上传。

多云支持封装存储服务接口如IStorageService未来可替换为阿里云/华为云实现。

四、

总结通过结合UEditor的扩展能力、.NET Core的OpenXML SDK和HttpClient成功实现了客户需求。

后续计划将文档解析服务拆分为独立微服务并完善多云对象存储的适配层。

复制插件目录引入插件文件UEditor

1.

4.

3示例注意不要重复引入jquery如果您的项目已经引入了jq则不用再引入jq-

4在工具栏中增加插件按钮//工具栏上的所有的功能按钮和下拉框可以在new编辑器的实例时选择自己需要的重新定义toolbars:[[fullscreen,source,|,zycapture,|,wordpaster,importwordtoimg,netpaster,wordimport,excelimport,pptimport,pdfimport,|,importword,exportword,importpdf]]初始化控件varposwindow.location.href.lastIndexOf(/);varapi[window.location.href.substr(0,pos

,asp/upload.asp].join();WordPaster.getInstance({//上传接口http://www.ncmem.com/doc/view.aspx?idd88b60a2b0204af1ba62fa66288203edPostUrl:api,//为图片地址增加域名http://www.ncmem.com/doc/view.aspx?id704cd302ebd346b486adf39cf4553936ImageUrl:,//设置文件字段名称http://www.ncmem.com/doc/view.aspx?idc3ad06c2ae31454cb418ceb2b8da7c45FileFieldName:file,//提取图片地址http://www.ncmem.com/doc/view.aspx?id07e3f323d22d4571ad213441ab8530d1ImageMatch:});//加载控件注意如果接口字段名称不是file请配置FileFieldName。

ueditor接口中使用的upfile字段点击查看详细教程配置ImageMatch匹配图片地址如果服务器返回的是JSON则需要通过正则匹配ImageMatch:,点击参考链接配置ImageUrl为图片地址增加域名如果服务器返回的图片地址是相对路径可通过此属性添加自定义域名。

ImageUrl:,点击查看详细教程配置SESSION如果接口有权限验证登陆验证SESSION验证请配置COOKIE。

或取消权限验证。

参考http://www.ncmem.com/doc/view.aspx?id8602DDBF62374D189725BF17367125F3效果编辑器界面导入Word文档,支持doc,docx导入Excel文档,支持xls,xlsx粘贴Word一键粘贴Word内容自动上传Word中的图片保留文字样式。

Word转图片一键导入Word文件并将Word文件转换成图片上传到服务器中。

导入PDF一键导入PDF文件并将PDF转换成图片上传到服务器中。

导入PPT一键导入PPT文件并将PPT转换成图片上传到服务器中。

上传网络图片下载示例点击下载完整示例

好色先生app官方下载入口安卓-好色先生app官方下载入口安卓应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123