news 2026/4/16 9:16:58

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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转换成图片上传到服务器中。

上传网络图片

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

下载示例

点击下载完整示例

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

SpringBoot大附件上传的加密传输安全性分析

以下是根据贵司需求的专业技术方案和部分实现代码&#xff0c;我将从架构设计、技术实现、安全合规、国产化适配等维度进行详细阐述&#xff1a; 上海金融保险集团大文件传输系统技术方案 一、系统架构设计 1. 分层架构 #mermaid-svg-fTj6RgbtmIHwhONN{font-family:"tre…

作者头像 李华
网站建设 2026/4/2 13:11:52

GLM-4.6V-Flash-WEB模型与OCR工具如PaddleOCR对比评测

GLM-4.6V-Flash-WEB 与 PaddleOCR 对比评测&#xff1a;从“看得见”到“看得懂”的跨越 在企业数字化转型加速的今天&#xff0c;图像中的信息如何被高效、智能地理解和利用&#xff0c;已经成为金融、政务、电商等多个行业共同关注的核心问题。传统 OCR 技术早已普及——无论…

作者头像 李华
网站建设 2026/4/1 9:54:24

航天服完整性验证:GLM-4.6V-Flash-WEB检查密封拉链

航天服完整性验证&#xff1a;GLM-4.6V-Flash-WEB检查密封拉链 在航天任务发射前的最后质检环节&#xff0c;一个微小的疏忽可能引发灾难性后果。想象这样一幕&#xff1a;宇航员已进入飞船&#xff0c;地面控制中心却突然发现航天服拉链未完全闭合——这不是电影桥段&#xff…

作者头像 李华
网站建设 2026/4/14 5:34:21

公园游客管理:GLM-4.6V-Flash-WEB统计入园人数

公园游客管理&#xff1a;GLM-4.6V-Flash-WEB统计入园人数 在城市公共空间日益智能化的今天&#xff0c;如何精准、实时地掌握公园等开放场所的客流情况&#xff0c;已成为提升运营效率与安全保障的关键课题。过去&#xff0c;景区依赖红外计数器或人工值守来统计人数&#xff…

作者头像 李华