芯片制造企业如何解决CAD图纸粘贴到TinyMCE的矢量输出?

一、需求拆解与灵魂拷问

“老板说要给TinyMCE5加个Word一键转存功能,还要支持公式渲染和多终端适配,预算99元?这特么比用Excel算提成还刺激!”

(掏出祖传PHP手册和Vue3速成宝典)

二、技术选型与白嫖方案

  1. 前端插件

    • TinyMCE5官方powerpaste插件(商业版$300,卒)
    • 替代方案:tinymce-paste-image(GitHub开源)+ 自定义Word解析器
    • 公式渲染:KaTeX(CDN免费) + MathType兼容层
  2. 后端处理

    • PHP使用PhpOffice库解析DOCX(免费但坑多)
    • 图片上传:阿里云OSS SDK(免费额度够用)
    • 公式转换:Node.js服务(用99元预算租个学生机)

三、前端核心代码(Vue3 + TinyMCE5)

// src/components/Editor.vue



import { ref } from 'vue';
import Editor from '@tinymce/tinymce-vue';
import 'tinymce/plugins/paste';
import 'tinymce/plugins/table';
import 'tinymce/plugins/advlist';

const content = ref('');
const editorConfig = {
  plugins: 'paste table advlist',
  toolbar: 'paste wordpaste | formatselect | bold italic | table',
  setup: (editor) => {
    editor.ui.registry.addButton('wordpaste', {
      text: 'Word粘贴',
      onAction: () => {
        editor.execCommand('mceInsertClipboardContent', false, {
          content: '<div class="word-content">等待粘贴...</div>'
        });
      }
    });
  }
};

const handlePaste = (e) => {
  const clipboardData = e.clipboardData;
  if (!clipboardData) return;

  // 检测Word粘贴的特殊格式
  const wordHtml = clipboardData.getData('text/html');
  if (wordHtml.includes('mso-')) {
    // 调用后端API处理Word内容
    fetch('/api/parse-word', {
      method: 'POST',
      body: JSON.stringify({ html: wordHtml })
    })
    .then(res => res.json())
    .then(data => {
      content.value = data.processedHtml;
    });
  }
};

四、后端PHP处理(Laravel风格伪代码)

// app/Http/Controllers/WordParserController.php
public function parseWord(Request $request)
{
    $html = $request->input('html');
    
    // 1. 提取图片并上传OSS
    preg_match_all('/]+src="([^"]+)"/i', $html, $matches);
    foreach ($matches[1] as $imgUrl) {
        $imgData = file_get_contents($imgUrl);
        $ossPath = 'word_images/' . uniqid() . '.png';
        OSS::put($ossPath, $imgData);
        $html = str_replace($imgUrl, env('OSS_URL') . $ossPath, $html);
    }

    // 2. 公式转换(调用Node服务)
    $html = preg_replace_callback('/\\$(.*?)\\$/', function($matches) {
        $latex = urlencode($matches[1]);
        $nodeUrl = "http://node-service:3000/convert?latex={$latex}";
        $mathml = file_get_contents($nodeUrl);
        return $mathml;
    }, $html);

    // 3. 清理Word垃圾样式
    $html = strip_tags($html, '');
    $html = preg_replace('/style="[^"]*"/i', '', $html);

    return response()->json(['processedHtml' => $html]);
}

五、Node.js公式转换服务(99元预算专属)

// server.js (运行在回源带宽1Mbps的学生机上)
const express = require('express');
const katex = require('katex');
const app = express();

app.get('/convert', (req, res) => {
    try {
        const latex = decodeURIComponent(req.query.latex);
        const mathml = katex.renderToString(latex, {
            output: 'mathml',
            throwOnError: false
        });
        res.send(mathml);
    } catch (e) {
        res.status(400).send('公式解析失败');
    }
});

app.listen(3000, () => console.log('公式服务启动,每月省下200元奶茶钱!'));

六、生存指南与求职彩蛋

  1. 白嫖资源

    • 阿里云OSS学生套餐(6元/月)
    • 腾讯云轻量服务器(新用户99元/年)
    • GitHub Student Pack(免费JetBrains全家桶)
  2. 求职暗号

    • 群内喊"内推+学校"自动触发师哥师姐警报
    • 推荐简历模板:
      # 技能清单
      - 精通用99元预算完成9999元需求
      - 擅长在Vue3和PHP之间架起爱的桥梁
      - 阿里云OSS上传速度优化经验(实测3KB/s)
      
  3. 赚钱攻略

    • 群内推荐会员机制(实测日赚200元技巧):
      // 群机器人自动分账系统
      function calculateCommission(orderAmount) {
          const tiers = {
              bronze: 0.2,
              gold: 0.5  // 需要拉5个下线解锁
          };
          return orderAmount * tiers.bronze;
      }
      

七、最终效果展示

![效果图描述:TinyMCE编辑器中完美显示的Word文档,包含:

  1. 从Word粘贴的表格(带样式)
  2. KaTeX渲染的公式
  3. OSS存储的图片
  4. 移动端适配的响应式布局]

(实际效果取决于你的头发剩余量)


加入技术交流群获取完整源码

  • QQ群:223813913
  • 暗号:“我要用99元征服世界”
  • 群文件包含:
    • tinymce-word-paste-plugin.zip
    • php-word-parser.tar.gz
    • 《从0到1搭建传销…啊不,分销系统.pdf》

(温馨提示:本群不承诺月入过万,但保证能学会用Excel算提成)

复制插件

WordPaster插件文件夹

安装jquery

npm install jquery

在组件中引入

  // 引入tinymce-vue
  import Editor from '@tinymce/tinymce-vue'
  import {WordPaster} from '../../static/WordPaster/js/w'
  import {zyOffice} from '../../static/zyOffice/js/o'
  import {zyCapture} from '../../static/zyCapture/z'

添加工具栏

//添加导入excel工具栏按钮
(function () {
    'use strict';
    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
    function selectLocalImages(editor) {        
      WordPaster.getInstance().SetEditor(editor).importExcel()
    }

    var register$1 = function (editor) {
      editor.ui.registry.addButton('excelimport', {
        text: '',
        tooltip: '导入Excel文档',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
      editor.ui.registry.addMenuItem('excelimport', {
        text: '',
        tooltip: '导入Excel文档',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
    };
    var Buttons = { register: register$1 };
    function Plugin () {
      global.add('excelimport', function (editor) {        
        Buttons.register(editor);
      });
    }
    Plugin();
}());

//添加word转图片工具栏按钮
(function () {
    'use strict';
    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
    function selectLocalImages(editor) {        
      WordPaster.getInstance().SetEditor(editor);
      WordPaster.getInstance().importWordToImg()
    }

    var register$1 = function (editor) {
      editor.ui.registry.addButton('importwordtoimg', {
        text: '',
        tooltip: 'Word转图片',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
      editor.ui.registry.addMenuItem('importwordtoimg', {
        text: '',
        tooltip: 'Word转图片',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
    };
    var Buttons = { register: register$1 };
    function Plugin () {
      global.add('importwordtoimg', function (editor) {        
        Buttons.register(editor);
      });
    }
    Plugin();
}());

//添加粘贴网络图片工具栏按钮
(function () {
    'use strict';
    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
    function selectLocalImages(editor) {        
      WordPaster.getInstance().SetEditor(editor);
      WordPaster.getInstance().UploadNetImg()
    }

    var register$1 = function (editor) {
      editor.ui.registry.addButton('netpaster', {
        text: '',
        tooltip: '网络图片一键上传',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
      editor.ui.registry.addMenuItem('netpaster', {
        text: '',
        tooltip: '网络图片一键上传',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
    };
    var Buttons = { register: register$1 };
    function Plugin () {
      global.add('netpaster', function (editor) {        
        Buttons.register(editor);
      });
    }
    Plugin();
}());

//添加导入PDF按钮
(function () {
    'use strict';
    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
    function selectLocalImages(editor) {        
      WordPaster.getInstance().SetEditor(editor);
      WordPaster.getInstance().ImportPDF()
    }

    var register$1 = function (editor) {
      editor.ui.registry.addButton('pdfimport', {
        text: '',
        tooltip: '导入pdf文档',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
      editor.ui.registry.addMenuItem('pdfimport', {
        text: '',
        tooltip: '导入pdf文档',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
    };
    var Buttons = { register: register$1 };
    function Plugin () {
      global.add('pdfimport', function (editor) {        
        Buttons.register(editor);
      });
    }
    Plugin();
}());

//添加导入PPT按钮
(function () {
    'use strict';
    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
    function selectLocalImages(editor) {        
      WordPaster.getInstance().SetEditor(editor);
      WordPaster.getInstance().importPPT()
    }

    var register$1 = function (editor) {
      editor.ui.registry.addButton('pptimport', {
        text: '',
        tooltip: '导入PowerPoint文档',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
      editor.ui.registry.addMenuItem('pptimport', {
        text: '',
        tooltip: '导入PowerPoint文档',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
    };
    var Buttons = { register: register$1 };
    function Plugin () {
      global.add('pptimport', function (editor) {        
        Buttons.register(editor);
      });
    }
    Plugin();
}());

//添加导入WORD按钮
(function () {
    'use strict';
    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
    function selectLocalImages(editor) {        
      WordPaster.getInstance().SetEditor(editor).importWord()
    }

    var register$1 = function (editor) {
      editor.ui.registry.addButton('wordimport', {
        text: '',
        tooltip: '导入Word文档',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
      editor.ui.registry.addMenuItem('wordimport', {
        text: '',
        tooltip: '导入Word文档',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
    };
    var Buttons = { register: register$1 };
    function Plugin () {
      global.add('wordimport', function (editor) {        
        Buttons.register(editor);
      });
    }
    Plugin();
}());

//添加WORD粘贴按钮
(function () {
    'use strict';
    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
    var ico = "http://localhost:8080/static/WordPaster/plugin/word.png"
    function selectLocalImages(editor) {
      WordPaster.getInstance().SetEditor(editor).PasteManual()
    }

    var register$1 = function (editor) {
      editor.ui.registry.addButton('wordpaster', {
        text: '',
        tooltip: 'Word一键粘贴',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
      editor.ui.registry.addMenuItem('wordpaster', {
        text: '',
        tooltip: 'Word一键粘贴',
        onAction: function () {
          selectLocalImages(editor)
        }
      });
    };
    var Buttons = { register: register$1 };
    function Plugin () {
      global.add('wordpaster', function (editor) {        
        Buttons.register(editor);
      });
    }
    Plugin();
}());

在线代码:

添加插件

// 插件
      plugins: {
          type: [String, Array],
          // default: 'advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools importcss insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars'
          default: 'autoresize code autolink autosave image imagetools paste preview table powertables'
      },

点击查看在线代码

初始化组件

// 初始化
WordPaster.getInstance({
    // 上传接口:http://www.ncmem.com/doc/view.aspx?id=d88b60a2b0204af1ba62fa66288203ed
    PostUrl: 'http://localhost:8891/upload.aspx',
    // 为图片地址增加域名:http://www.ncmem.com/doc/view.aspx?id=704cd302ebd346b486adf39cf4553936
    ImageUrl: 'http://localhost:8891{url}',
    // 设置文件字段名称:http://www.ncmem.com/doc/view.aspx?id=c3ad06c2ae31454cb418ceb2b8da7c45
    FileFieldName: 'file',
    // 提取图片地址:http://www.ncmem.com/doc/view.aspx?id=07e3f323d22d4571ad213441ab8530d1
    ImageMatch: ''
})

在页面中引入组件


功能演示

编辑器

在编辑器中增加功能按钮
WordPaster-TinyMCE5

导入Word文档,支持doc,docx

粘贴Word和图片

导入Excel文档,支持xls,xlsx

粘贴Word和图片

粘贴Word

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

Word转图片

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

导入PDF

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

导入PPT

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

上传网络图片

一键自动上传网络图片。
自动上传网络图片

下载示例

点击下载完整示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值