当前位置: 首页 > news >正文

wangEditor pdf导入识别图表和文本高亮

📝 Word一键转存CMS升级手记

🚀 项目背景

大家好,我是江西某高校计算机专业大三的"代码狂魔",正在给我的CMS新闻管理系统做一次"整容手术"——添加Word一键转存功能!每次看到编辑部的妹子们手动复制Word内容到后台,图片还要一张张上传,我就心疼(主要是心疼她们的加班费都拿去喝奶茶了)

🕵️ 技术调研

需求拆解

  1. 前端:在wangEditor工具栏添加导入按钮
  2. 功能:支持Word/Excel/PPT/PDF → 保留格式 → 图片自动上传
  3. 兼容:Win + Mac双平台
  4. 预算:99元(毕竟学生党,得留着钱买泡面)

方案探索

方案1: mammoth.js (纯前端方案)
// 测试代码片段importmammothfrom"mammoth";mammoth.extractRawText({arrayBuffer:fileArrayBuffer}).then(function(result){console.log(result.value);// 纯文本内容}).done();

✔️ 优点:免费、轻量
❌ 缺点:只能提取文本,丢失格式和图片

方案2: docx-parser (收费)

💰 价格:$199 → 超预算!PASS!

方案3: 阿里云OSS官方SDK + phpWord
// PHP后端处理逻辑usePhpOffice\PhpWord\IOFactory;$phpWord=IOFactory::load($tempFilePath);$writer=IOFactory::createWriter($phpWord,'HTML');$writer->save('converted.html');

✔️ 优点:格式保留较好
❌ 缺点:PPT/PDF支持有限

🔧 最终方案:wangEditor + paste-extension + 自定义处理

前端实现 (Vue2)

import E from 'wangeditor' import 'wangeditor/release/wangEditor.min.css' export default { data() { return { editor: null } }, mounted() { this.initEditor() }, methods: { initEditor() { this.editor = new E(this.$refs.editor) // 自定义菜单 this.editor.config.menus = [ 'head', 'bold', 'italic', 'underline', 'strikeThrough', 'foreColor', 'backColor', 'link', 'list', 'justify', 'quote', 'table', 'code', 'undo', 'redo', 'importWord' // 自定义按钮 ] // 注册自定义按钮 this.editor.config.customAlert = (s) => { console.log(s) } this.editor.config.customMenu = { importWord: { text: '导入Office', className: 'icon-import-word', callback: () => { document.getElementById('word-upload').click() } } } this.editor.create() }, async handleFileUpload(e) { const file = e.target.files[0] if (!file) return try { const formData = new FormData() formData.append('file', file) const res = await this.$http.post('/api/office/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }) this.editor.txt.html(res.data.htmlContent) } catch (error) { console.error('文件上传失败:', error) } } } }

后端处理 (PHP)

ossClient=newOSS\OssClient(getenv('OSS_ACCESS_KEY_ID'),getenv('OSS_ACCESS_KEY_SECRET'),getenv('OSS_ENDPOINT'));$this->bucketName=getenv('OSS_BUCKET');}publicfunctionhandleUpload($file){$fileExt=strtolower(pathinfo($file['name'],PATHINFO_EXTENSION));$tempPath=$file['tmp_name'];switch($fileExt){case'doc':case'docx':return$this->processWord($tempPath);case'xls':case'xlsx':return$this->processExcel($tempPath);case'ppt':case'pptx':return$this->processPpt($tempPath);case'pdf':return$this->processPdf($tempPath);default:thrownewException("不支持的格式:$fileExt");}}privatefunctionprocessWord($filePath){$phpWord=\PhpOffice\PhpWord\IOFactory::load($filePath);$htmlWriter=new\PhpOffice\PhpWord\Writer\HTML($phpWord);// 处理图片$mediaElements=$phpWord->getMediaElements();foreach($mediaElementsas$element){$imagePath=$this->uploadImageToOSS($element['source'],$element['imageExtension']);// 替换HTML中的图片路径$htmlWriter->replaceImagePath($element['mediaIndex'],$imagePath);}$htmlContent=$htmlWriter->getContent();return['htmlContent'=>$htmlContent];}privatefunctionuploadImageToOSS($binaryData,$extension){$filename='uploads/'.uniqid().'.'.$extension;$this->ossClient->putObject($this->bucketName,$filename,$binaryData);return$this->ossClient->generatePresignedUrl($this->bucketName,$filename,3600);}// 其他格式处理方法类似...}?>

🎯 开发日志

Day1: 掉坑记

  1. 尝试用纯前端方案 → 图片处理被CORS拦路抢劫
  2. 试用phpWord → 发现PPT支持是个"半成品"
  3. 喝掉三罐红牛后决定:组合拳出击!

Day3: 突破性进展

  1. 发现阿里云OSS有文件处理服务(每月免费额度够用)
  2. 结合wangEditor的paste插件魔改成功
  3. 成功保留表格样式!(虽然颜色偶尔跑偏)

💡 技术要点总结

  1. 文件处理流程

    前端上传 → 后端识别格式 → 调用对应解析器 → 提取内容+图片 → 图片上传OSS → 生成HTML → 返回编辑器
  2. 成本控制技巧

    • 使用OSS免费额度
    • 用phpWord+phpExcel+phpPowerPoint组合替代商业库
    • 图片延迟加载减少流量消耗
  3. 兼容性hack

// 处理Mac系统差异constisMac=navigator.platform.toUpperCase().indexOf('MAC')>=0;if(isMac){// 调整某些API调用方式}

📚 推荐资源

  1. PHPOffice官方文档
  2. wangEditor扩展开发指南
  3. 阿里云OSS PHP SDK示例

🍻 结语

这个项目让我深刻体会到——“程序员的时间都去哪了?全花在找免费替代方案上了!” 欢迎加入QQ群223813913一起交流,群里不定期分享:

  • 熬夜不掉头发秘诀
  • 如何用学生认证白嫖各种云服务
  • 以及…我的完整项目代码!

(注:因篇幅限制,部分代码已简化,完整实现需要处理更多边界情况。需要详细代码可以进群@我)

复制插件文件


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

上传网络图片

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

下载示例

点击下载完整示例

http://www.jsqmd.com/news/200528/

相关文章:

  • 城市热岛效应研究:GLM-4.6V-Flash-WEB分析红外遥感数据
  • 存储型跨站脚本攻击剖析:HTML上下文(无编码防护)
  • 从Python到C++的无缝衔接:C++精灵库,开启少儿编程新篇章
  • 使用Flask包装GLM-4.6V-Flash-WEB模型提供HTTP服务
  • [Windows] 卸载软件Uninstall Tool3.8.0
  • 收藏!2025智能体元年:企业级AI平台构建12大核心经验全攻略
  • GLM-4.6V-Flash-WEB模型与LangChain框架集成的可能性分析
  • GLM-4.6V-Flash-WEB模型在文物数字化保护中的辅助作用
  • 噪声污染分布:GLM-4.6V-Flash-WEB关联街景与声学传感器
  • 架构设计必藏!知识图谱+向量数据库=GraphRAG:构建可扩展、可信AI系统的终极解决方案
  • 程序员必看!一文读懂LLM、RAG、Agent,建议收藏反复阅读
  • GLM-4.6V-Flash-WEB模型的安全性评估:是否存在隐私泄露风险?
  • 2026执业药师考试备考培训机构哪家好?这三家高口碑机构抓紧关注! - 医考机构品牌测评专家
  • WinForms + DevExpress中documentManager中的tites对象图片圆角
  • GLM-4.6V-Flash-WEB模型二次开发入门指南:接口调用与扩展建议
  • GLM-4.6V-Flash-WEB模型能否应用于盲人视觉辅助设备?
  • 2026执业药师考试备考培训哪家好?高口碑机构深度测评指南 - 医考机构品牌测评专家
  • [Windows] U盘扩容检测工具 ValiDrive v1.0.1
  • GLM-4.6V-Flash-WEB模型在儿童教育产品中的伦理考量
  • 2026 谷歌 Antigravity 安装+汉化+无限白嫖额度全攻略
  • GLM-4.6V-Flash-WEB模型对艺术作品的理解能力测评
  • 杉数科技首次登陆央视:以国产智能决策引擎,支撑“人工智能+”行动稳步推进
  • GLM-4.6V-Flash-WEB模型对模糊图像的容忍度实测报告
  • GLM-4.6V-Flash-WEB模型支持视频帧连续分析吗?技术探讨
  • 火箭发射台检查:GLM-4.6V-Flash-WEB识别耐热材料脱落
  • 2026年人工智能全景报告:从“福音传播”到“价值评估”的全球范式转移
  • 海草床生态系统:GLM-4.6V-Flash-WEB评估鱼类栖息适宜性
  • 收藏必备!2026年构建企业级AI Agent平台完整指南:3大开源工具选型与实战对比
  • 珊瑚礁健康检查:GLM-4.6V-Flash-WEB识别白化现象
  • 小白必看!一文搞懂Agent、Agentic、AI Agent和Agentic Systems区别(建议收藏)