云计算百科
云计算领域专业知识百科平台

互联网平台使用CKEDITOR处理Word图文混排需注意哪些兼容问题?

企业网站后台管理系统功能扩展项目记录

作为北京某国企的项目负责人,近期我负责的企业网站后台管理系统文章发布模块迎来了新的需求挑战。客户要求增加 Word 粘贴功能、Word 文档导入功能以及微信公众号内容粘贴功能(自动下载公众号文章图片并上传至服务器)。以下是我针对此需求展开的一系列工作记录。

一、需求分析

功能需求

  • Word 粘贴功能:支持从 Word 复制内容粘贴到网站编辑器,粘贴后图片自动上传至单独存储服务器(后期可升级至阿里云、华为云 OBS 等对象存储),使用二进制文件存储图片,保留文档中的形状、形状组、表格、字体、字号、大小、颜色、Latex 公式、MathType 公式等样式信息。
  • Word 文档导入功能:支持导入 Word、Excel、PPT、PDF 文档,并保留文档中的图片和样式。
  • 微信公众号内容粘贴功能:自动下载公众号文章的图片并上传到服务器。
  • 环境需求

  • 信创国产化环境:操作系统支持 Windows、macOS、Linux、RedHat、CentOS、Ubuntu、中标麒麟、银河麒麟、统信 UOS;浏览器支持包含 IE8 在内的所有浏览器,以及奇安信安全浏览器、龙芯浏览器、红莲花安全浏览器等信创国产浏览器;CPU 支持 x86(Intel、AMD、兆芯、海光)、arm(鲲鹏、飞腾)、龙芯(mips、LoongArch)。
  • 自主可控与信息安全:公司领导希望买断产品源代码,预算在 88 万以内,以确保在公司产品线和项目中不受限制使用,满足政府和国企对自主可控及信息数据安全的要求。
  • 二、产品查找与评估

    查找过程

    我在各大技术论坛、开源社区以及专业软件评测网站上进行搜索,同时联系了一些知名的软件供应商和开发团队,收集了多款可能满足需求的产品和解决方案。

    综合评估

  • 开源解决方案:
    • 优点:成本低,可自由修改和定制,符合自主可控的要求。
    • 缺点:功能可能不够完善,需要投入大量人力进行二次开发和测试,且文档和支持相对较少,开发周期可能较长。
  • 商业软件:
    • 优点:功能相对成熟,有专业的技术支持团队,开发周期可能较短。
    • 缺点:部分软件价格较高,且可能存在授权限制,不符合公司买断源代码的需求。
  • 经过综合评估,考虑到项目的复杂度、时间成本以及公司的长期发展需求,我决定选择一款开源的富文本编辑器插件进行二次开发,同时结合一些开源的文档处理库来实现所需功能。

    三、开发过程

    技术选型

  • 前端:基于现有的 vue2 – cli 框架和 ckeditor 4 编辑器,选择合适的插件进行集成和开发。
  • 后端:使用 JSP 框架,结合 Apache POI 等开源库处理文档导入功能。
  • 存储:初期使用单独的存储服务器,后期可无缝迁移至阿里云 OSS 对象存储。
  • 具体开发步骤

    前端开发
  • 集成 Word 粘贴和微信公众号内容粘贴插件:
    • 在 ckeditor 4 中查找并集成支持 Word 粘贴和图片自动上传的插件,如 ckeditor – wordpaste 插件。
    • 对插件进行配置和修改,确保图片能够自动上传至指定的存储服务器,并保留文档样式。
    • 以下是部分前端代码示例:
  • export default {
    mounted() {
    CKEDITOR.replace('editor', {
    extraPlugins: 'wordpaste', // 引入 Word 粘贴插件
    filebrowserUploadUrl: '/upload', // 图片上传接口
    // 其他配置项
    });
    }
    }

  • 开发文档导入功能界面:
    • 使用 Vue 组件开发一个文档导入的界面,用户可以选择要导入的文档类型(Word、Excel、PPT、PDF)并上传文件。
    • 以下是部分前端代码示例:
  • export default {
    data() {
    return {
    selectedFile: null
    };
    },
    methods: {
    handleFileChange(event) {
    this.selectedFile = event.target.files[0];
    },
    importDocument() {
    if (this.selectedFile) {
    const formData = new FormData();
    formData.append('file', this.selectedFile);
    // 调用后端接口上传文件
    fetch('/import', {
    method: 'POST',
    body: formData
    })
    .then(response => response.json())
    .then(data => {
    // 处理导入结果
    console.log(data);
    })
    .catch(error => {
    console.error('导入文档失败:', error);
    });
    }
    }
    }
    }

    后端开发
  • 实现图片上传接口:
    • 使用 JSP 开发图片上传接口,接收前端上传的图片文件,并将其存储到指定的服务器或阿里云 OSS 对象存储中。
    • 以下是部分后端代码示例:
  • <%@ page import="java.io.*, java.util.*, javax.servlet.*" %>
    <%@ page import="org.apache.commons.fileupload.*" %>
    <%@ page import="org.apache.commons.fileupload.disk.*" %>
    <%@ page import="org.apache.commons.fileupload.servlet.*" %>
    <%@ page import="com.aliyun.oss.*" %>
    <%@ page import="com.aliyun.oss.model.*" %>

    <%
    // 配置阿里云 OSS 相关信息
    String endpoint = "your-oss-endpoint";
    String accessKeyId = "your-access-key-id";
    String accessKeySecret = "your-access-key-secret";
    String bucketName = "your-bucket-name";

    // 创建 OSS 客户端
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

    // 检查是否为多媒体上传请求
    boolean isMultipart = ServletFileUpload.isMultipartContent(request);
    if (isMultipart) {
    // 创建文件上传处理器
    DiskFileItemFactory factory = new DiskFileItemFactory();
    ServletFileUpload upload = new ServletFileUpload(factory);

    try {
    // 解析请求
    List items = upload.parseRequest(request);
    for (FileItem item : items) {
    if (!item.isFormField()) {
    // 获取文件名
    String fileName = item.getName();

    // 生成唯一文件名
    String uniqueFileName = UUID.randomUUID().toString() + "_" + fileName;

    // 上传文件到阿里云 OSS
    ossClient.putObject(bucketName, uniqueFileName, item.getInputStream());

    // 返回文件访问 URL
    String fileUrl = "https://" + bucketName + "." + endpoint + "/" + uniqueFileName;
    out.println("{\\"url\\":\\"" + fileUrl + "\\"}");
    }
    }
    } catch (Exception e) {
    e.printStackTrace();
    out.println("{\\"error\\":\\"上传失败\\"}");
    }
    } else {
    out.println("{\\"error\\":\\"不是文件上传请求\\"}");
    }

    // 关闭 OSS 客户端
    ossClient.shutdown();
    %>

  • 实现文档导入接口:
    • 使用 Apache POI 等开源库解析用户上传的文档文件,提取其中的内容和样式信息,并将其转换为 HTML 格式返回给前端,以便在编辑器中显示。
    • 以下是部分后端代码示例(以 Word 文档导入为例):
  • <%@ page import="java.io.*, org.apache.poi.xwpf.usermodel.*" %>

    <%
    // 获取上传的文件
    InputStream inputStream = request.getInputStream();

    try {
    // 创建 XWPFDocument 对象
    XWPFDocument document = new XWPFDocument(inputStream);

    // 提取文档内容
    StringBuilder htmlContent = new StringBuilder();
    htmlContent.append("");

    // 遍历段落
    for (XWPFParagraph paragraph : document.getParagraphs()) {
    htmlContent.append("");
    for (XWPFRun run : paragraph.getRuns()) {
    String text = run.getText(0);
    if (text != null) {
    // 设置字体样式
    String fontFamily = run.getFontFamily();
    int fontSize = run.getFontSize();
    String color = run.getColor();

    htmlContent.append("").append(text).append("");
    }
    }
    htmlContent.append("");
    }

    // 遍历表格
    for (XWPFTable table : document.getTables()) {
    htmlContent.append("");
    for (XWPFTableRow row : table.getRows()) {
    htmlContent.append("");
    for (XWPFTableCell cell : row.getTableCells()) {
    htmlContent.append("");
    }
    htmlContent.append("");
    }
    htmlContent.append("");
    for (XWPFParagraph paragraph : cell.getParagraphs()) {
    for (XWPFRun run : paragraph.getRuns()) {
    String text = run.getText(0);
    if (text != null) {
    htmlContent.append(text);
    }
    }
    }
    htmlContent.append("");
    }

    htmlContent.append("");

    // 返回 HTML 内容
    out.println("{\\"html\\":\\"" + htmlContent.toString() + "\\"}");

    } catch (Exception e) {
    e.printStackTrace();
    out.println("{\\"error\\":\\"导入文档失败\\"}");
    } finally {
    if (inputStream != null) {
    try {
    inputStream.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    %>

    测试与优化

  • 功能测试:在不同浏览器和操作系统环境下对开发完成的功能进行全面测试,确保各项功能正常运行,图片能够正确上传和显示,文档样式能够完整保留。
  • 性能优化:对代码进行优化,提高系统的响应速度和稳定性,特别是在处理大型文档时,确保系统不会出现卡顿或崩溃的情况。
  • 安全测试:对系统进行安全测试,防范潜在的安全漏洞,如文件上传漏洞、跨站脚本攻击(XSS)等。
  • 四、总结与展望

    通过本次项目开发,我们成功在企业网站后台管理系统的文章发布模块中增加了 Word 粘贴功能、Word 文档导入功能以及微信公众号内容粘贴功能,满足了客户的需求。在开发过程中,我们充分考虑了信创国产化环境和信息安全要求,选择了合适的技术方案和开源库进行开发,确保了系统的兼容性和自主可控性。

    未来,我们将继续关注技术的发展和客户的需求变化,不断优化和完善系统功能,提高系统的性能和安全性,为公司的发展和客户的业务提供更有力的支持。同时,我们也将积累本次项目的经验,为后续类似项目的开发提供参考和借鉴。

    复制插件

    说明:此教程以CKEditor4.x为例,使用其他编辑器的查看对应教程。 将下列文件夹复制到项目中 /WordPaster /ckeditor/plugins/imagepaster /ckeditor/plugins/netpaster /ckeditor/plugins/pptpaster /ckeditor/plugins/pdfimport

    上传插件

    wordpaster文件夹

    上传插件文件夹

    将imagepaster,netpaster文件夹上传到现有项目ckeditor/plugins目录中 插件文件夹

    在工具栏中增加插件按钮

    插件按钮

    CKEDITOR.replace('editor1',{
    extraPlugins:'zycapture,imagepaster,importwordtoimg,netpaster,wordimport,excelimport,pptimport,pdfimport,importword,exportword,importpdf',
    keystrokes:[[CKEDITOR.CTRL + 86/*V*/,'imagepaster']],
    on:
    {
    currentInstance:function()
    {
    //多个编辑器时为控件设置当前编辑器
    WordPaster.getInstance().SetEditor(CKEDITOR.currentInstance);
    window.zyCapture.setEditor(this);
    window.zyOffice.SetEditor(this);
    }
    },
    //https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_config.html#cfg-allowedContent
    allowedContent:true//不过滤样式
    });

    引用js

    引用JS

    初始化控件

    WordPaster.getInstance({
    //上传接口:http://www.ncmem.com/doc/view.aspx?id=d88b60a2b0204af1ba62fa66288203ed
    PostUrl: api,
    //为图片地址增加域名:http://www.ncmem.com/doc/view.aspx?id=704cd302ebd346b486adf39cf4553936
    ImageUrl: "",
    //设置文件字段名称:http://www.ncmem.com/doc/view.aspx?id=c3ad06c2ae31454cb418ceb2b8da7c45
    FileFieldName: "file",
    //提取图片地址:http://www.ncmem.com/doc/view.aspx?id=07e3f323d22d4571ad213441ab8530d1
    ImageMatch: '',
    Cookie: 'PHPSESSID='
    });//加载控件

    配置上传接口

    初始化控件

    WordPaster.getInstance({
    //上传接口:http://www.ncmem.com/doc/view.aspx?id=d88b60a2b0204af1ba62fa66288203ed
    PostUrl:api,
    //为图片地址增加域名:http://www.ncmem.com/doc/view.aspx?id=704cd302ebd346b486adf39cf4553936
    ImageUrl: "",
    //设置文件字段名称:http://www.ncmem.com/doc/view.aspx?id=c3ad06c2ae31454cb418ceb2b8da7c45
    FileFieldName: "file",
    //提取图片地址:http://www.ncmem.com/doc/view.aspx?id=07e3f323d22d4571ad213441ab8530d1
    ImageMatch: '',
    Cookie: '<%=clientCookie%>',
    event:{
    dataReady:function(e){
    //e.word,
    //e.imgs:tag1,tag2,tag3
    console.log(e.imgs)
    }
    }
    });//加载控件

    注意

    1.如果接口字段名称不是file,请配置FileFieldName。ueditor接口中使用的upfile字段 字段名称 点击查看详细教程

    配置ImageMatch

    用于匹配JSON数据, 匹配地址 点击查看详细教程

    配置ImageUrl

    用于为图片增加域名前缀 自定义域名 点击查看详细教程

    配置Session

    如果接口有权限验证(登陆验证,SESSION验证),请配置COOKIE。或取消权限验证。 参考:点击查看详细教程

    说明

    1.请先测试您的接口:点击查看详细教程

    功能演示

    编辑器界面

    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转图片

    上传网络图片

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

    下载示例

    点击下载完整示例

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 互联网平台使用CKEDITOR处理Word图文混排需注意哪些兼容问题?
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!