长春市网站建设_网站建设公司_测试上线_seo优化
2026/1/9 16:46:13 网站建设 项目流程

日期:2023年X月X日
角色:北京XX软件公司 全栈开发工程师(.NET Core + Vue2)
项目背景:客户要求在后台管理系统的文章发布模块新增三大功能:

  1. Word粘贴功能:支持从Word复制内容粘贴到UEditor,图片自动上传至内网单据存储服务器(二进制存储,非Base64),保留样式(字体、字号、颜色等)。
  2. 文档导入功能:支持上传Word/Excel/PPT/PDF,解析内容并保留图片和样式,渲染至UEditor。
  3. 微信公众号内容粘贴:支持从微信公众号编辑器复制内容(含富文本和图片)并粘贴到UEditor,图片自动上传至内网服务器。

技术栈

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

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

1. Word粘贴功能

核心问题

  • 浏览器原生粘贴事件无法直接处理Word中的复杂样式(如mso-前缀的CSS)和图片(图片以剪贴板对象或二进制流形式存在)。
  • UEditor默认会过滤Word特有的HTML标签和样式,需自定义过滤规则。
  • 图片需从剪贴板提取二进制数据并上传至内网服务器,生成可访问的URL。

解决方案

  • 前端
    • 使用Clipboard API拦截粘贴事件,提取HTML和图片二进制数据(通过FileReaderFormData)。
    • 调用.NET Core后端接口上传图片,替换HTML中的本地图片路径为服务器URL。
    • 调整UEditor配置,保留Word相关CSS属性(如font-familycolor)。
  • 后端(.NET Core)
    • 提供图片上传接口,接收二进制流并保存至内网服务器,返回访问路径。
    • 支持未来迁移至对象存储(如阿里云OSS),通过依赖注入切换存储服务。

工具评估

  • NPOI:开源.NET库,支持Word/Excel/PPT解析,但需手动处理样式和图片提取。
  • OpenXML SDK:微软官方库,支持Word文档(.docx)解析,可提取图片二进制数据。
  • iTextSharp:PDF解析库,但样式保留能力有限。
  • Aspose.Words:商业库,支持所有格式且样式保留完整,但需授权。
  • 泽优WordPaster:开源库,支持所有格式且样式保留完整,完全开放产品源代码(下载源码)。

结论

  • Word粘贴:前端使用Clipboard API+FormData上传图片,后端用OpenXML SDK处理复杂样式(备用方案:Aspose.Words试用版)。
  • 图片存储:直接上传二进制流至服务器,避免Base64转换。

2. 文档导入功能

核心问题

  • 需支持多种格式(Word/Excel/PPT/PDF),并保留样式和图片。
  • 大文件(如PPT)解析性能优化,避免阻塞主线程。
  • 图片需从文档中提取为二进制并上传至服务器。

解决方案

  • 后端(.NET Core)
    • Word/Excel/PPT:使用OpenXML SDK(开源)或Aspose(商业)解析文档,提取文本、图片二进制数据和样式。
    • PDF:使用iTextSharpPdfPig(开源)解析文本,图片需额外处理。
    • 图片上传至内网服务器,生成URL替换文档中的本地路径。
  • 前端
    • 通过文件上传组件(如el-upload)将文档发送至后端。
    • 后端返回解析后的HTML,注入UEditor。

工具评估

  • OpenXML SDK:免费,但API复杂,需手动处理样式映射。
  • Aspose.Total:全功能商业库,支持所有格式,但成本较高。
  • LibreOffice:通过命令行转换文档为HTML,但需服务器安装且样式可能丢失。

结论

  • 优先方案OpenXML SDK(Word/Excel/PPT) +iTextSharp(PDF),样式保留不足时手动补充CSS。
  • 备选方案:评估泽优WordPaster源码版,满足公司自主安全可控需求,没有授权限制。

3. 微信公众号内容粘贴

核心问题

  • 微信公众号编辑器导出的HTML可能包含微信特有的CSS类名(如wx_fmt_*)。
  • 图片以微信CDN链接形式存在,需下载二进制数据并上传至内网服务器。

解决方案

  • 前端
    • 拦截粘贴事件,提取HTML中的微信图片URL。
    • 通过.NET Core后端接口下载图片二进制数据并上传至内网服务器,替换HTML中的CDN链接。
  • 后端
    • 使用HttpClient下载微信图片,保存为二进制文件至内网服务器。

工具评估

  • HttpClient(.NET Core):标准库,支持异步下载图片。
  • HtmlAgilityPack:解析HTML并提取图片URL。

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


二、开发过程记录

1. Word粘贴功能实现

前端(Vue2 + UEditor)

// 监听UEditor粘贴事件consteditor=UE.getEditor('editor');editor.addListener('beforePaste',function(){// 阻止默认粘贴行为,手动处理returnfalse;});editor.addListener('ready',function(){document.getElementById('editor').addEventListener('paste',async(e)=>{e.preventDefault();constclipboardData=e.clipboardData||window.clipboardData;consthtml=clipboardData.getData('text/html');constfiles=clipboardData.files;if(html&&files.length>0){constformData=newFormData();for(leti=0;i<files.length;i++){formData.append('files',files[i]);// 图片二进制数据}// 调用后端上传图片接口constresponse=awaitaxios.post('/api/upload/word-images',formData,{headers:{'Content-Type':'multipart/form-data'}});// 替换HTML中的图片路径为服务器URLletnewHtml=html;response.data.urls.forEach((url,index)=>{newHtml=newHtml.replace(/src=["']?([^"']*)["']?/g,(match,src)=>{if(src.startsWith('blob:')||src.startsWith('cid:')){return`src="${url}"`;}returnmatch;});});editor.setContent(newHtml);// 更新编辑器内容}});});

后端(.NET Core 6)

// 图片上传接口(接收二进制流)[ApiController][Route("api/upload")]publicclassUploadController:ControllerBase{privatereadonlyIWebHostEnvironment_env;privatereadonlyIConfiguration_config;publicUploadController(IWebHostEnvironmentenv,IConfigurationconfig){_env=env;_config=config;}[HttpPost("word-images")]publicasyncTaskUploadWordImages(Listfiles){varuploadPath=Path.Combine(_env.WebRootPath,"uploads");if(!Directory.Exists(uploadPath))Directory.CreateDirectory(uploadPath);varurls=newList();foreach(varfileinfiles){varfileName=$"{Guid.NewGuid()}{Path.GetExtension(file.FileName)}";varfilePath=Path.Combine(uploadPath,fileName);using(varstream=newFileStream(filePath,FileMode.Create)){awaitfile.CopyToAsync(stream);// 直接保存二进制数据}// 返回内网可访问的URL(需配置Nginx反向代理)varurl=$"{Request.Scheme}://{Request.Host}/uploads/{fileName}";urls.Add(url);}returnOk(new{urls});}}

2. 文档导入功能实现

后端(.NET Core 6 + OpenXML SDK)

// Word导入示例(DOCX)[HttpPost("import/docx")]publicasyncTaskImportDocx(IFormFilefile){using(varstream=newMemoryStream()){awaitfile.CopyToAsync(stream);using(vardocument=WordprocessingDocument.Open(stream,false)){varbody=document.MainDocumentPart.Document.Body;varhtmlBuilder=newStringBuilder();foreach(varparagraphinbody.Descendants()){htmlBuilder.Append("");foreach(varruninparagraph.Descendants()){htmlBuilder.Append("");htmlBuilder.Append(run.GetFirstChild()?.Text??"");htmlBuilder.Append("");}// 处理段落中的图片(二进制提取)foreach(vardrawinginparagraph.Descendants()){varimagePart=document.MainDocumentPart.GetPartById(drawing.Descendants().First().Embed.Value)asImagePart;if(imagePart!=null){using(varimageStream=newMemoryStream()){imagePart.FeedData(imageStream);varimageBytes=imageStream.ToArray();// 上传图片至服务器(调用UploadController逻辑)varimageUrl=awaitUploadImageToServer(imageBytes,"docx-import");htmlBuilder.Append($"");}}}htmlBuilder.Append("");}returnOk(htmlBuilder.ToString());}}}// 图片上传辅助方法privateasyncTaskUploadImageToServer(byte[]imageBytes,stringprefix){varfileName=$"{prefix}_{Guid.NewGuid()}.jpg";varfilePath=Path.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 } } };

3. 微信公众号内容粘贴实现

前端(Vue2)

asyncfunctionhandleWechatPaste(html){// 提取微信图片URL(示例:src="https://mmbiz.qpic.cn/...")constimgTags=html.match(/]+src="https:\/\/mmbiz\.qpic\.cn[^>]+>/g)||[];for(constimgTagofimgTags){consturl=imgTag.match(/src="([^"]+)"/)[1];constresponse=awaitdownloadFromWechat(url);// 调用后端接口constnewImgTag=imgTag.replace(url,response.url);html=html.replace(imgTag,newImgTag);}consteditor=UE.getEditor('editor');editor.setContent(html);}asyncfunctiondownloadFromWechat(url){constresponse=awaitaxios.get('/api/download/wechat-image',{params:{url},responseType:'arraybuffer'// 接收二进制数据});// 调用图片上传接口(复用Word粘贴的上传逻辑)constformData=newFormData();constblob=newBlob([response.data],{type:'image/jpeg'});formData.append('file',blob,'wechat-image.jpg');constuploadResponse=awaitaxios.post('/api/upload/word-images',formData);return{url:uploadResponse.data.urls[0]};}

后端(.NET Core 6)

// 下载微信图片接口[HttpGet("download/wechat-image")]publicasyncTaskDownloadWechatImage([FromQuery]stringurl){using(varclient=newHttpClient()){varresponse=awaitclient.GetAsync(url);if(!response.IsSuccessStatusCode)returnBadRequest("Failed to download image");varimageBytes=awaitresponse.Content.ReadAsByteArrayAsync();returnFile(imageBytes,"image/jpeg");// 返回二进制流}}

三、问题与优化

  1. 性能问题
    • 大文件解析(如PPT)采用异步任务队列(如Hangfire)优化。
  2. 样式兼容性
    • Word中的复杂样式(如文本框)需手动转换为HTML/CSS,或通过Aspose.Words自动处理。
  3. 安全性
    • 对上传文件进行MIME类型校验,防止恶意文件上传。
  4. 多云支持
    • 封装存储服务接口(如IStorageService),未来可替换为阿里云/华为云实现。

四、总结

通过结合UEditor的扩展能力、.NET Core的OpenXML SDKHttpClient,成功实现了客户需求。后续计划将文档解析服务拆分为独立微服务,并完善多云对象存储的适配层。

复制插件目录

引入插件文件

UEditor 1.4.3.3示例

注意:不要重复引入jquery,如果您的项目已经引入了jq,则不用再引入jq-1.4

在工具栏中增加插件按钮

//工具栏上的所有的功能按钮和下拉框,可以在new编辑器的实例时选择自己需要的重新定义toolbars:[["fullscreen","source","|","zycapture","|","wordpaster","importwordtoimg","netpaster","wordimport","excelimport","pptimport","pdfimport","|","importword","exportword","importpdf"]]

初始化控件

varpos=window.location.href.lastIndexOf("/");varapi=[window.location.href.substr(0,pos+1),"asp/upload.asp"].join("");WordPaster.getInstance({//上传接口:http://www.ncmem.com/doc/view.aspx?id=d88b60a2b0204af1ba62fa66288203edPostUrl:api,//为图片地址增加域名:http://www.ncmem.com/doc/view.aspx?id=704cd302ebd346b486adf39cf4553936ImageUrl:"",//设置文件字段名称:http://www.ncmem.com/doc/view.aspx?id=c3ad06c2ae31454cb418ceb2b8da7c45FileFieldName:"file",//提取图片地址:http://www.ncmem.com/doc/view.aspx?id=07e3f323d22d4571ad213441ab8530d1ImageMatch:''});//加载控件

注意

如果接口字段名称不是file,请配置FileFieldName。ueditor接口中使用的upfile字段

点击查看详细教程

配置ImageMatch

匹配图片地址,如果服务器返回的是JSON则需要通过正则匹配

ImageMatch:'',

点击参考链接

配置ImageUrl

为图片地址增加域名,如果服务器返回的图片地址是相对路径,可通过此属性添加自定义域名。

ImageUrl:"",

点击查看详细教程

配置SESSION

如果接口有权限验证(登陆验证,SESSION验证),请配置COOKIE。或取消权限验证。
参考:http://www.ncmem.com/doc/view.aspx?id=8602DDBF62374D189725BF17367125F3

效果

编辑器界面

导入Word文档,支持doc,docx

导入Excel文档,支持xls,xlsx

粘贴Word

一键粘贴Word内容,自动上传Word中的图片,保留文字样式。

Word转图片

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

导入PDF

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

导入PPT

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

上传网络图片

下载示例

点击下载完整示例

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询