news 2026/4/3 4:51:44

农业遥感平台如何通过wangEditor实现GeoTIFF图像转存?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
农业遥感平台如何通过wangEditor实现GeoTIFF图像转存?

【开发手记:Word图片一键转存功能“闯关记”】

日期:2023年X月X日 星期X 天气:代码如山,我自岿然啃之

作为一名上海软件工程专业的大三学生,最近在给自己的CMS新闻管理系统“动手术”——目标是让后台编辑器(wangEditor 4)支持Word/Excel/PPT/PDF一键导入,图片自动上传到阿里云OSS,还要保留文档样式(表格、字体、颜色、公式图片一个都不能少)。预算99元,穷且益坚,但绝不向“手动复制粘贴”低头!


一、前期侦查:免费组件的“寻宝游戏”

  1. 前端编辑器扩展

    • wangEditor 4原生能力:先翻官方文档,发现它支持粘贴过滤,但对Word的复杂样式(如表格、公式)处理很“佛系”,图片直接变成[object Object],当场裂开。
    • 第三方插件摸底
      • mammoth.js:能解析Word文档,但只支持.docx,且对图片和表格的提取需要手动“缝补”,PASS。
      • docx.js:开源库,能解析Word内容,但API复杂到像在读天书,测试后发现对样式保留不完整,放弃。
      • pdf.js:Mozilla的PDF渲染库,能提取文本和图片,但无法直接生成wangEditor支持的HTML,得自己写转换逻辑,头大。
    • 结论:前端单独搞定太费劲,必须靠后端“兜底”。
  2. 后端方案筛选

    • PHP生态探索
      • PHPWord:能解析Word/Excel,但PPT/PDF得靠其他库,且图片提取需要自己处理路径,麻烦。
      • PHPExcel/PHPOffice:老牌库,但功能分散,文档老旧,测试时发现对.xlsx支持还行,但.docx的样式解析容易错乱。
      • Spire.Doc for PHP:商业库,试用版有水印,正式版价格劝退(预算99元,连零头都不够)。
      • unoconv + LibreOffice:通过命令行将Office文档转为HTML/PDF,再处理图片,但部署依赖多,服务器配置复杂,放弃。
    • 终极方案
      • PHPWord + pdf2image:用PHPWord处理Word/Excel,pdf2image(基于ImageMagick)将PDF转为图片,PPT暂时用截图工具手动处理(后期再优化)。
      • 图片处理:用PHP的GDImagick库提取文档中的图片,但发现效率低且容易内存溢出,转而用阿里云OSS SDK直接上传字节流,省时省力。

二、开发实战:从“崩溃”到“真香”

  1. 前端改造:给wangEditor加“外挂”

    • 自定义按钮:通过wangEditor的menus配置,在工具栏新增“导入文档”按钮,绑定点击事件。
    • 文件上传组件:用Vue2的el-upload(Element UI)实现文件选择,限制格式为.docx, .xlsx, .pptx, .pdf
    • 粘贴处理:监听paste事件,用mammoth.js过滤Word粘贴内容,保留基础样式(字体、颜色),复杂表格和图片交给后端处理。
  2. 后端集成:PHP的“魔法”

    • 文档解析
      • Word/Excel:用PHPWord加载文件,遍历段落、表格、图片等元素,提取HTML片段。
      • PDF:用pdf2image将每页转为图片,嵌入HTML中(牺牲文本可编辑性,但样式完美保留)。
    • 图片提取与上传
      • 将文档中的图片保存为临时文件,通过阿里云OSS SDK上传,生成带时效的URL后替换为``标签。
      • 优化:用md5_file()生成图片唯一标识,避免重复上传。
    • 跨格式支持
      • Word/Excel:PHPWord直接搞定。
      • PPT:先用LibreOffice转为PDF,再按PDF流程处理(自动化脚本安排上)。
      • PDFpdf2image+OSS上传,简单粗暴但有效。
  3. 阿里云OSS集成:99元预算的“云”梦想

    • 配置OSS SDK:在PHP中引用aliyun-oss-php-sdk,设置Endpoint、AccessKey和Bucket名称。
    • 安全优化
      • 限制上传文件类型(白名单:.docx, .xlsx, .pdf)。
      • 设置CORS规则,避免跨域问题。
      • 图片URL加签名,防止盗链。

三、测试与优化:从“能用”到“稳如老狗”

  1. 功能测试

    • Word导入:表格、字体、颜色、图片全部保留,连公式图片都能正常显示(PHPWord+OSS YYDS!)。
    • Excel导入:表格数据完美转换,样式基本一致。
    • PDF导入:文本丢失(意料之中),但图片和布局复现度90%。
    • PPT导入:通过LibreOffice转PDF后,图片质量略有下降,但勉强能用。
  2. 性能优化

    • 大文件处理:超过5MB的文件分块上传,避免PHP超时。
    • 异步加载:前端用Loading动画提示用户,后端用ignore_user_abort(true)防止连接中断。
  3. BUG修复

    • 图片路径错乱:PHPWord提取的图片路径是临时目录,改用内存流直接上传。
    • 样式冲突:wangEditor默认会过滤部分HTML标签,手动修改配置允许等标签通过。

四、总结与展望

  • 成果:花0元(PHPWord开源)+99元(预算未动,全靠白嫖)实现了需求,导师看了直呼“专业”!
  • 经验
    • 免费组件虽香,但关键功能得靠“组合技”(PHPWord+pdf2image+OSS)。
    • 前后端联调时,先用Postman测接口,再集成前端,避免“甩锅大战”。
  • 未来计划
    • 支持PPT直接解析(研究Apache POI的PHP版)。
    • 加入OCR功能,让PDF文本可编辑。
    • 优化前端体验,比如拖拽上传、实时预览。

最后:如果有同行也在折腾类似功能,欢迎加入QQ群223813913,一起交流避坑!毕竟,代码可以一个人写,但BUG不能一个人扛啊! 🚀

复制插件文件


安装jquery

npm install jquery

导入组件

importEfrom'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格式参考

为编辑器添加按钮

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转换成图片上传到服务器中。

上传网络图片

一键自动上传网络图片,自动下载远程服务器图片,自动上传远程服务器图片

下载示例

点击下载完整示例

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/26 22:09:40

Java毕设选题推荐:基于springboot的教师排课管理系统基于springboot课程排课管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/3/31 4:34:28

假期运营选题躺平指南|不费脑、高互动,断更焦虑退退退!

运营人的假期&#xff0c;从来都是“一半想摆烂&#xff0c;一半怕断更”。别人假期睡到大中午、打卡吃喝玩乐&#xff0c;我们却要在玩的时候惦记账号数据&#xff0c;熬夜想选题、赶文案&#xff0c;最后假期结束累得比上班还惨——更扎心的是&#xff0c;费劲吧啦更的内容&a…

作者头像 李华
网站建设 2026/3/27 11:40:37

cpu的fetch/prefetch

一句话总结Fetch 取当前要执行的指令&#xff08;必须取&#xff0c;不取就停&#xff09;Prefetch 提前取未来可能执行的指令&#xff08;预取&#xff0c;不影响当前执行&#xff0c;只为提速&#xff09;它们都是 ICU&#xff08;Instruction Cache Unit / Instruction Fe…

作者头像 李华
网站建设 2026/3/24 8:55:23

【SPIE、双刊号ISSNISBN、五届稳定EI检索】第六届数字信号与计算机通信国际学术会议(DSCC 2026)

第六届数字信号与计算机通信国际学术会议&#xff08;DSCC 2026&#xff09;拟于2026年4月10日至12日在中国昆明举行。DSCC 2026旨在汇聚领先的学术科学家、研究人员和研究学者&#xff0c;交流和分享他们在数字信号处理领域的经验和研究成果&#xff0c;为从事“数字信号与计算…

作者头像 李华
网站建设 2026/3/25 15:57:09

为什么需要RAG?推荐一个从零搭建RAG的项目,含教学视频

本文推荐LangChainAI官方出品的’rag-from-scratch’项目&#xff0c;包含从零实现的代码和教学视频。文章详细解释了RAG&#xff08;检索增强生成&#xff09;的必要性及三大组成部分&#xff1a;索引、检索和生成。RAG能扩展大模型知识边界&#xff0c;支持私有数据和最新信息…

作者头像 李华
网站建设 2026/3/30 10:52:10

Java计算机毕设之基于springboot的农村康养院敬老院平台的设计与实现(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华