是否有KindEditor粘贴Word图片的源码示例或API调用教程?

一个北京JAVA程序员的CMS官网逆袭之路:Word导入插件开发全记录

前言:从"要饭"到"躺赚"的奇妙旅程

各位老铁们好!我是老王,一个在北京中关村敲代码的"码农"。最近接了个CMS企业官网的外包项目,客户爸爸提出了个"变态"需求:要在KindEditor里实现Word/Excel/PPT/PDF一键导入,还要保留所有样式和公式!

这需求一出来,我差点把键盘摔了——这特么是要让我用JSP实现Office全家桶啊?但看到客户那期待的眼神,再摸摸自己瘪瘪的钱包,我咬咬牙:干!

第一章:需求分析——客户爸爸的"五彩斑斓黑"

客户的核心需求就三个字:简单、强、省钱

  • 要简单:插件形式,工具栏加个按钮就能用
  • 要强大:支持Office全家桶+公众号内容导入,公式图片样式全保留
  • 要省钱:预算680元(这价格在北京连顿火锅都吃不上)

最坑的是:网上开源方案都拉胯!emz/wmz公式图片不支持,LaTeX公式显示成狗屎,图片还得手动上传…

第二章:技术选型——穷人的智慧

前端部分

  • 框架:Vue3 CLI(客户指定)
  • 编辑器:KindEditor4(老古董了,但客户在用)
  • 插件方案:改造KindEditor的paste插件

后端部分

  • 语言:JAVA(JSP,客户遗留系统)
  • 工具:Eclipse JEE(比IDEA卡,但免费)
  • 存储:阿里云OSS(客户已有)

关键技术点

  1. Office文档解析:用Apache POI处理Word/Excel,PPT用Tika,PDF用PDFBox
  2. 公式处理:用MathJax处理LaTeX转MathML
  3. 图片处理:用Thumbnailator压缩图片,自动上传OSS
  4. 跨终端显示:MathML+SVG方案

第三章:代码实现——从0到1的奇迹

前端插件代码(Vue3版)

// src/plugins/kindEditorWordImport.js
import KindEditor from 'kindeditor'

export default {
  install(app) {
    // 扩展KindEditor
    KindEditor.plugin('wordimport', function(K) {
      var self = this, name = 'wordimport';
      
      // 添加工具栏按钮
      self.clickToolbar(name, function() {
        // 调用文件选择对话框
        const input = document.createElement('input')
        input.type = 'file'
        input.accept = '.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.html,.txt'
        input.onchange = async (e) => {
          const file = e.target.files[0]
          if (!file) return
          
          // 显示加载动画
          self.loading(1)
          
          try {
            // 调用后端API处理文件
            const formData = new FormData()
            formData.append('file', file)
            
            const res = await fetch('/api/office/import', {
              method: 'POST',
              body: formData
            })
            
            const { html, error } = await res.json()
            if (error) {
              alert('导入失败: ' + error)
              return
            }
            
            // 插入处理后的HTML
            self.insertHtml(html)
          } catch (e) {
            console.error('导入错误:', e)
            alert('导入过程中发生错误')
          } finally {
            self.loading(0)
          }
        }
        input.click()
      })
      
      // 添加按钮到工具栏
      self.afterSetToolbar(function() {
        if (!self.toolbar[name]) {
          self.toolbar.push({
            name: name,
            cmd: name,
            title: '导入Word/Excel/PPT/PDF'
          })
        }
      })
    })
  }
}

后端JSP处理代码

<%-- /api/office/import.jsp --%>
<%@ page import="org.apache.poi.*, org.apache.poi.xwpf.*, org.apache.commons.io.*" %>
<%@ page import="com.aliyun.oss.*, com.aliyun.oss.model.*" %>
<%@ page import="org.jsoup.*, org.jsoup.nodes.*" %>
<%@ page import="java.util.*, java.io.*, java.util.regex.*" %>

<%
// 配置信息
String endpoint = "your-oss-endpoint";
String accessKeyId = "your-access-key";
String accessKeySecret = "your-secret-key";
String bucketName = "your-bucket";
String ossFolder = "uploads/office/";

// 初始化OSS客户端
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

try {
    // 获取上传的文件
    Part filePart = request.getPart("file");
    String fileName = filePart.getSubmittedFileName();
    String fileExt = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
    
    // 根据文件类型处理
    String htmlContent = "";
    if (fileExt.equals("docx") || fileExt.equals("doc")) {
        htmlContent = processWord(filePart.getInputStream());
    } else if (fileExt.equals("xlsx") || fileExt.equals("xls")) {
        htmlContent = processExcel(filePart.getInputStream());
    } else if (fileExt.equals("pptx") || fileExt.equals("ppt")) {
        htmlContent = processPPT(filePart.getInputStream());
    } else if (fileExt.equals("pdf")) {
        htmlContent = processPDF(filePart.getInputStream());
    } else {
        throw new Exception("不支持的文件类型");
    }
    
    // 处理图片上传到OSS
    htmlContent = uploadImagesToOSS(htmlContent, ossClient, bucketName, ossFolder);
    
    // 处理LaTeX公式转MathML
    htmlContent = convertLatexToMathML(htmlContent);
    
    // 返回结果
    response.setContentType("application/json");
    response.getWriter().write("{\"html\":\"" + escapeJson(htmlContent) + "\"}");
    
} catch (Exception e) {
    response.setContentType("application/json");
    response.getWriter().write("{\"error\":\"" + escapeJson(e.getMessage()) + "\"}");
} finally {
    ossClient.shutdown();
}

// 处理Word文档
String processWord(InputStream is) throws Exception {
    XWPFDocument doc = new XWPFDocument(is);
    XWPFWordConverter converter = new XWPFWordConverter(doc);
    StringWriter writer = new StringWriter();
    converter.process(writer);
    return writer.toString();
}

// 处理Excel文档(简化版)
String processExcel(InputStream is) throws Exception {
    // 实际项目中需要更复杂的处理
    return "Excel内容处理(简化示例)";
}

// 处理PPT文档(简化版)
String processPPT(InputStream is) throws Exception {
    // 实际项目中需要更复杂的处理
    return "PPT内容处理(简化示例)";
}

// 处理PDF文档
String processPDF(InputStream is) throws Exception {
    // 使用PDFBox或其他库处理
    // 实际项目中需要更完整的实现
    return "PDF内容处理(简化示例)";
}

// 图片上传到OSS
String uploadImagesToOSS(String html, OSS ossClient, String bucketName, String ossFolder) {
    Document doc = Jsoup.parse(html);
    Elements images = doc.select("img");
    
    for (Element img : images) {
        String src = img.attr("src");
        if (src.startsWith("data:image/")) {
            // 提取base64数据
            String base64Data = src.substring(src.indexOf(",") + 1);
            byte[] imageBytes = Base64.getDecoder().decode(base64Data);
            
            // 生成唯一文件名
            String fileName = UUID.randomUUID().toString() + ".png";
            String ossPath = ossFolder + fileName;
            
            // 上传到OSS
            ossClient.putObject(new PutObjectRequest(bucketName, ossPath, new ByteArrayInputStream(imageBytes)));
            
            // 替换为OSS URL
            String ossUrl = "https://" + bucketName + "." + endpoint.replace("https://", "") + "/" + ossPath;
            img.attr("src", ossUrl);
        }
    }
    
    return doc.body().html();
}

// LaTeX转MathML(简化版)
String convertLatexToMathML(String html) {
    // 实际项目中应该使用MathJax或KaTeX的服务器端转换
    // 这里只是示例,实际需要更完整的实现
    return html.replaceAll("\\$(\\S+?)\\$", "$1");
}

// JSON转义
String escapeJson(String str) {
    return str.replace("\\", "\\\\")
              .replace("\"", "\\\"")
              .replace("\n", "\\n")
              .replace("\r", "\\r");
}
%>

第四章:部署与测试——从崩溃到起飞

部署步骤

  1. 把前端插件放到Vue项目的plugins目录
  2. 在main.js中引入插件
  3. 把JSP文件放到Web应用的api/office目录
  4. 配置阿里云OSS参数
  5. 重启应用服务器

测试用例

// 测试代码(在Vue组件中)
import { ref, onMounted } from 'vue'
import KindEditor from 'kindeditor'
import 'kindeditor/themes/default/default.css'
import WordImportPlugin from '@/plugins/kindEditorWordImport'

export default {
  setup() {
    const editorRef = ref(null)
    
    onMounted(() => {
      const app = { $el: document.getElementById('editor-container') }
      WordImportPlugin.install(app)
      
      editorRef.value = KindEditor.create('#editor-container', {
        plugins: ['wordimport'],
        items: [
          'wordimport', 'fontname', 'fontsize', '|', 
          'forecolor', 'hilitecolor', 'bold', 'italic', 'underline'
        ]
      })
    })
    
    return { editorRef }
  }
}

第五章:赚钱攻略——从码农到斜杠青年

QQ群运营秘籍

  1. 新人福利:加群送1-99元红包(实际成本0.5元/人,用支付宝红包)
  2. 内容为王
    • 每天分享一个技术小技巧
    • 每周一次项目复盘直播
    • 每月一次外包项目接单培训
  3. 裂变机制
    • 推荐新人得20%提成
    • 群成员接单成功,推荐人得5%奖励
    • 每月群内接单冠军奖励200元

推广话术

"兄弟们,还在为找不到外包项目发愁吗?还在为技术提升慢苦恼吗?加入我们的QQ群:223813913,这里有:

  • 实时更新的外包项目信息
  • 大厂内推机会
  • 独家技术教程
  • 每天红包雨
  • 推荐奖励拿到手软

现在加入还送《JAVA外包接单秘籍》电子书,前100名免费咨询技术方案!"

第六章:未来展望——从680到680万

这个项目虽然预算只有680元,但背后隐藏着巨大的商机:

  1. 标准化产品:把插件打包成可销售的产品
  2. SaaS服务:提供在线文档转换服务
  3. 企业定制:为政府、学校等机构提供定制解决方案

目前我已经通过这个方案接了3个外包项目,总收入突破2万元!而这一切,都始于那个"变态"的需求和680元的预算。

结语:代码改变命运

兄弟们,在这个内卷的时代,我们码农不能只会写代码,更要学会:

  1. 把技术变成产品
  2. 把产品变成流量
  3. 把流量变成现金

加入我们的QQ群:223813913,让我们一起:

  • 交流技术
  • 分享项目
  • 赚外快
  • 实现财务自由

记住:在互联网时代,最贵的不是代码,而是连接人的能力!

(PS:群文件里有完整源代码和部署文档,新人还有惊喜福利哦~)

上传工具栏插件文件夹

插件目录

上传插件文件夹

WordPaster目录

控件初始化

在head中引入组件文件
注意,不要重复引入jquery,如果您的页面已经引入了jquery这里就不要再引入jquery 1.4了。


    
    WordPaster For KindEditor-4.x
    
    
    
    
    
    
    
    
    

 
# 初始化组件
    
    
    
        WordPaster.getInstance({
            ui:{render:"wdpst"}//目标容器,一般为div
        });
    

设置快捷键

将插件添加到工具栏,并挂载KindEditor的Ctrl+V快捷键事件
初始化和设置快捷键

	    var editor;
	    KindEditor.ready(function (K)
	    {
	        editor = K.create('#content1'
			,
			{ items: [
                'wordpaster','importwordtoimg','netpaster','wordimport','excelimport','pptimport','pdfimport', '|',
                'importword','exportword','importpdf','|'
                
            ]
			, afterCreate: function ()
			{
			    WordPaster.getInstance().SetEditor(this);
			    var self = this;
			    //自定义 Ctrl + V 事件。
			    KindEditor.ctrl(self.edit.doc, 'V', function () { WordPaster.getInstance().Paste(); });
			}
			});
	    });

注意

1.如果接口字段名称不是file,请配置FileFieldName。

文件字段名称
点击查看教程

2.如果接口返回JSON,请配置ImageMatch

图片匹配规则
点击查看教程

3.如果接口返回的图片地址没有域名,请配置ImageUrl

图片域名
点击查看教程

整合效果

整合效果

效果

编辑器界面

image

导入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、付费专栏及课程。

余额充值