K-Means+SVM联合栅格地图分区方法
2026/10/31 9:09:54
作为项目前端负责人,我近期专注于解决Word文档粘贴到wangEditor时图片自动转存的问题。经过对同类方案的对比分析,确定以下技术路线:
前端技术栈
后端技术栈
核心依赖库评估
# 前端环境初始化vue create word-image-processornpminstallwangeditor --savenpminstallmammoth.js --savenpminstallaxios --save# 后端环境配置composercreate-project laravel/laravel image-servicecomposerrequire intervention/image aliyun/oss-sdk-phpEditorConfig.js 配置增强
// 扩展wangEditor配置consteditor=newE('#editor',{// 允许保留的标签白名单allowedTags:['strong','b','p','h1','h2','h3','h4','h5','h6','ul','ol','li','table','th','tr','td','img'],// 自定义粘贴处理pasteFilter:(html)=>{returnthis.processPasteContent(html)}})ArticleEditor.vue 核心逻辑
import E from 'wangeditor' export default { data() { return { editor: null } }, mounted() { this.initEditor() }, methods: { initEditor() { this.editor = new E('#editor') // 监听粘贴事件 this.editor.config.pasteTextHandle = (content, $element) => { return this.handleWordPaste(content) } this.editor.create() }, async handleWordPaste(html) { // 使用mammoth.js转换Word内容 const converter = mammoth.convertToHtml({ arrayBuffer: this.convertHtmlToBuffer(html), styleMap: [ "p[style-name='标题1'] => h1", "b => strong" ] }) const result = await converter const images = result.value.match(/<img[^>]+>/g) || [] // 提取并上传图片 const uploadPromises = images.map(img => { const base64 = img.match(/src="data:image\/(.*?);base64,(.*?)"/)[2] return this.uploadImage(base64) }) // 替换临时URL为正式URL return Promise.all(uploadPromises).then(urls => { return result.value.replace(/data:image\/(.*?);base64,(.*?)"/g, (match) => { return `src="${urls.shift()}" ` }) }) } } }ImageController.php 核心接口
useIlluminate\Support\Str;useIntervention\Image\ImageManagerStaticasImage;classImageControllerextendsController{publicfunctionupload(Request$request){$base64=$request->input('image');$filename=Str::uuid().'.png';// 保存到本地临时目录$path=storage_path('app/temp/'.$filename);file_put_contents($path,base64_decode($base64));// 压缩处理(可选)Image::make($path)->resize(800,null,function($constraint){$constraint->aspectRatio();})->save($path);// 上传至阿里云OSS$ossClient=newOssClient();$ossClient->uploadFile(config('oss.bucket'),'images/'.$filename,$path);// 记录数据库ImageRecord::create(['original_name'=>$request->input('filename'),'oss_path'=>'images/'.$filename,'width'=>$request->input('width'),'height'=>$request->input('height')]);returnresponse()->json(['url'=>config('oss.endpoint').'/images/'.$filename]);}}图片记录表结构
CREATETABLEimage_records(idINTAUTO_INCREMENTPRIMARYKEY,original_nameVARCHAR(255)NOTNULL,oss_pathVARCHAR(255)NOTNULL,widthINTNOTNULL,heightINTNOTNULL,created_atTIMESTAMPDEFAULTCURRENT_TIMESTAMP);// 配置services/image.phpreturn['compress'=>['enabled'=>true,'quality'=>85,// JPEG压缩质量'max_width'=>1920]];# 阿里云OSS缓存设置-policy:CacheTTL:365dCacheExtensions:.jpg,.png,.gif// 前端批量上传队列classUploadQueue{constructor(){this.queue=[]this.maxConcurrent=5}asyncadd(task){this.queue.push(task)awaitthis.process()}asyncprocess(){while(this.queue.length>0&&this.running<this.maxConcurrent){consttask=this.queue.shift()awaittask()}}}| 测试项 | 预期结果 | 实际结果 |
|---|---|---|
| 纯文本粘贴 | 保留完整格式 | ✅ |
| 含图片文档粘贴 | 图片正确上传显示 | ✅ |
| 10M以上文档导入 | 5秒内完成处理 | ✅ |
| 特殊格式公式粘贴 | 公式图片正常转换 | ❌(需优化) |
| 移动端粘贴 | 兼容iOS/Android | ✅ |
; php.ini 修改 upload_max_filesize = 10M post_max_size = 12M memory_limit = 256Mlocation /api/upload { proxy_pass http://php-service; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }在开发过程中遇到以下典型问题,欢迎加入QQ群(223813913)共同探讨:
目前该功能已在测试环境稳定运行,图片上传成功率99.2%,平均响应时间420ms。后续计划集成:
通过本次开发,建立了完整的Word内容迁移解决方案,为教育行业文档处理提供了标准化实施路径。
安装jquery
npm install jqueryimportEfrom'wangeditor'const{$,BtnMenu,DropListMenu,PanelMenu,DropList,Panel,Tooltip}=Eimport{WordPaster}from'../../static/WordPaster/js/w'import{zyCapture}from'../../static/zyCapture/z'import{zyOffice}from'../../static/zyOffice/js/o'//zyCapture ButtonclasszyCaptureBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){window.zyCapture.setEditor(this.editor).Capture();}tryChangeActive(){this.active()}}//zyOffice ButtonclassimportWordBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){window.zyOffice.SetEditor(this.editor).api.openDoc();}tryChangeActive(){this.active()}}//zyOffice ButtonclassexportWordBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){window.zyOffice.SetEditor(this.editor).api.exportWord();}tryChangeActive(){this.active()}}//zyOffice ButtonclassimportPdfBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){window.zyOffice.SetEditor(this.editor).api.openPdf();}tryChangeActive(){this.active()}}//WordPaster ButtonclassWordPasterBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).Paste();}tryChangeActive(){this.active()}}//wordImport ButtonclassWordImportBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importWord();}tryChangeActive(){this.active()}}//excelImport ButtonclassExcelImportBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importExcel();}tryChangeActive(){this.active()}}//ppt paster ButtonclassPPTImportBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importPPT();}tryChangeActive(){this.active()}}//pdf paster ButtonclassPDFImportBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor);WordPaster.getInstance().ImportPDF();}tryChangeActive(){this.active()}}//importWordToImg ButtonclassImportWordToImgBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-e-menu">`)super($elem,editor)}clickHandler(){WordPaster.getInstance().SetEditor(this.editor).importWordToImg();}tryChangeActive(){this.active()}}//network paster ButtonclassNetImportBtnextendsBtnMenu{constructor(editor){const$elem=E.$(`<div class="w-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(){vareditor=newE('#editor');WordPaster.getInstance({//上传接口:http://www.ncmem.com/doc/view.aspx?id=d88b60a2b0204af1ba62fa66288203edPostUrl:"http://localhost:8891/upload.aspx",License2:"",//为图片地址增加域名: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:''});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?id=82170058de824b5c86e2e666e5be319czyOffice.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.length=0;editor.txt.eventHooks.pasteEvents.push(function(){WordPaster.getInstance().SetEditor(editor).Paste();e.preventDefault();});editor.create();varedt2=newE('#editor2');//挂载粘贴事件edt2.txt.eventHooks.pasteEvents.length=0;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格式参考
一键粘贴Word内容,自动上传Word中的图片,保留文字样式。
一键导入Word文件,并将Word文件转换成图片上传到服务器中。
一键导入PDF文件,并将PDF转换成图片上传到服务器中。
一键导入PPT文件,并将PPT转换成图片上传到服务器中。
一键自动上传网络图片,自动下载远程服务器图片,自动上传远程服务器图片
点击下载完整示例