我还是输给了免费富文本编辑器

简介: 我还是输给了免费富文本编辑器

前因后果



说说我做的一些努力


  1. 考虑给百度编辑器开发的一个二次插件,等下会进行说明如何使用改源码的方式开发二次插件
  2. 后端增加接口,接受word文档,转为html返回前台,前台再根据html内容对于富文本编辑框继续赋值和一些处理

然而,理想很美好,现实很骨感:


网络异常,图片无法展示
|


网络异常,图片无法展示
|


  1. 无法达到100%还原,word里面转译html会存在各种问题
  2. 有存在无法解析和翻译的部分
  3. 客户不会买账!(核心原因


如何解决word转译到富文本编辑的问题


这两天搜索了几乎所有的富文本编辑器(国内用的比较多的)似乎都没有解决这个问题。

然后几乎所有的带word导入粘贴的,几乎都是商业收费软件(还很贵)

无奈之下,BOSS决定掏钱升级ewebeditor并且怪为什么没有提早说百度编辑器实现不了。(经理&我:???)

所以最后结果就是:我瞎忙活了几天(内心一万个草泥马)。

既然知道了结果为什么还要写这篇文章,我其实很不甘心,一个方案被否决,我决定记录一下这个也许可行的数据方案。


JAVA&百度编辑器实现word粘贴(非完美)



不扯那么多,直接上菜:


1. 前端为百度编辑器自定义一个上传word的功能


网络异常,图片无法展示
|


  1. 搜索一下:UE.commands["setbordervisible"] = {

在它的下面加入如下的代码:


UE.commands["getword"] = {
    execCommand: function (Name) {
        if (window.FileReader) {   
            var inputObj=document.createElement('input')
            inputObj.setAttribute('id','my_inputObj');
            inputObj.setAttribute('type','file');
            //              inputObj.setAttribute('accept','application/msword');
            inputObj.setAttribute("style",'visibility:hidden');
            document.body.appendChild(inputObj);
            inputObj.onchange = function(){
                //拿取上传的文档
                var fileData = inputObj.files[0]
                if(fileData.type.indexOf('word')>-1){
                    if(fileData.size>1048576){  //控制在1M以内
                        alert('您上传的文件大于1MB,请上传1MB以内的word文件')
                        return;
                    }  
                    console.log(fileData)
                }else{
                    alert('请选择一个word文件')
                }
            }
            inputObj.click();
        }
    }
};
复制代码


  1. 增加一个命令叫做:getword
  2. 模拟一个input file,并且模拟一次点击文件上传
  3. 如果上传了具体文件,触发onchange,并且进行word的各种判断
  4. 然后将文件的内容传到后台的接口(具体怎么做根据自己的语言来处理)
  5. 加入自定义的命令:getword


网络异常,图片无法展示
|


//为工具栏添加按钮,以下都是统一的按钮触发命令,所以写在一起
    var btnCmds = ['undo', 'redo', 'formatmatch',
        'bold', 'italic', 'underline', 'fontborder', 'touppercase', 'tolowercase',
        'strikethrough', 'subscript', 'superscript', 'source', 'indent', 'outdent',
        'blockquote', 'pasteplain', 'pagebreak',
        'selectall', 'print','horizontal', 'removeformat', 'time', 'date', 'unlink',
        'insertparagraphbeforetable', 'insertrow', 'insertcol', 'mergeright', 'mergedown', 'deleterow',
        'deletecol', 'splittorows', 'splittocols', 'splittocells', 'mergecells', 'deletetable', 'drafts','getword'];
复制代码


注意到最后一个getword了么,这就是刚刚加进去的

  1. Lang/zh-cn/zh-cn.js文件当中,增加按钮说明,直接照着截图加就行


网络异常,图片无法展示
|


,'getword':'获取word'
复制代码


为了防止图裂,还是写一下,搜一下``scrawl:'涂鸦'`,基本可以找到大概的位置

  1. 修改ueditor.config.js文件,增加新的按钮


网络异常,图片无法展示
|


help的后面加一个getword就好了,注意以下json格式,逗号不能少

  1. 增加样式,修改Themes/default/ueditor.css,直接在最底下增加


.edui-default .edui-toolbar .edui-for-getword .edui-icon {
    background-image: url(../images/wordT1.png);
    background-repeat: no-repeat;
    width: 20px !important;
    background-size: 18px;
    background-position: center;
}
复制代码


Tip:wordT1.png 是一个word的小图标,这里就不提供了

才怪:Themes/default/images/wordT1.png

网络异常,图片无法展示
|

gitee.com/lazyTimes/i…

上面这一套做完之后,基本上在百度编辑器里面会多出一个图标,接下来需要后端开发接口,对接这个插件的行为和操作


2. 后端为word文件做转化为html的操作,然后将html原文返回给前端


做这个接口要特别的小心,需要防止接口被滥用,拖垮服务器资源,因为转化和图片存储的代价还是不小的,需要控制可以转化的大小

前文也说了,老板都出钱升级了,我还玩你个鬼的百度编辑器,溜了溜了,用ewebeidor,下面是网上搜下来的一个word转html的工具方法,需要apach-poi的支持,我用的是3.12版本,具体的内容看自己。


注意以下:docx 和 doc 在poi里面是需要用不同的对象进行操作的,后续自己也会补一补这一块的内容

poi 还是挺强的,很牛逼,把巨硬的那一套治的服服帖帖


import org.apache.commons.io.FileUtils;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.converter.PicturesManager;
import org.apache.poi.hwpf.converter.WordToHtmlConverter;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.hwpf.model.PAPX;
import org.apache.poi.hwpf.usermodel.Picture;
import org.apache.poi.hwpf.usermodel.PictureType;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFNumbering;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
 * 根据poi写的word帮助类
 * @Date 2020/10/12 18:26
 **/
public class WordHelper {
    public static void parseDocx2Html() throws Throwable {
        final String path = "D:\\zxd\\mark\\罗湖兼容性\\20201012word导出必备\\";
        final String file = "4403080004_深圳盐田政府在线_20200927_11064.doc";
        InputStream input = new FileInputStream(path + file);
        String suffix = file.substring(file.indexOf(".")+1);// //截取文件格式名
        //实例化WordToHtmlConverter,为图片等资源文件做准备
        WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(
                DocumentBuilderFactory.newInstance().newDocumentBuilder()
                        .newDocument());
        wordToHtmlConverter.setPicturesManager(new PicturesManager() {
            @Override
            public String savePicture(byte[] content, PictureType pictureType,
                                      String suggestedName, float widthInches, float heightInches) {
                return suggestedName;
            }
        });
        if ("doc".equals(suffix.toLowerCase())) {
            // docx
            HWPFDocument wordDocument = new HWPFDocument(input);
            wordToHtmlConverter.processDocument(wordDocument);
            //处理图片,会在同目录下生成 image/media/ 路径并保存图片
            List pics = wordDocument.getPicturesTable().getAllPictures();
            if (pics != null) {
                for (int i = 0; i < pics.size(); i++) {
                    Picture pic = (Picture) pics.get(i);
                    try {
                        pic.writeImageContent(new FileOutputStream(path
                                + pic.suggestFullFileName()));
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        // 转换
        Document htmlDocument = wordToHtmlConverter.getDocument();
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        DOMSource domSource = new DOMSource(htmlDocument);
        StreamResult streamResult = new StreamResult(outStream);
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer serializer = tf.newTransformer();
        serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");//编码格式
        serializer.setOutputProperty(OutputKeys.INDENT, "yes");//是否用空白分割
        serializer.setOutputProperty(OutputKeys.METHOD, "html");//输出类型
        serializer.transform(domSource, streamResult);
        outStream.close();
        String content = new String(outStream.toByteArray());
        System.err.println(content);
        FileUtils.writeStringToFile(new File(path, "interface.html"), content,
                "utf-8");
    }
    public static void main(String[] args) throws Throwable {
        WordHelper.parseDocx2Html();
    }
}
复制代码


后续



滚回去继续升级ewebeditor了,擦公司的前辈居然有人做了一个一键排版和文章重排,直接动了源代码,有时间研究一下,果然老系统出神仙。

PS:老系统代码里面老板的名字在上面,老板是大公司程序员出身,挺好。


总结:



永远不要小看任何细节的点,看似平平无奇的功能,其实真正考虑要实现的时候。

一个简单的复制粘贴其实也并不简单。word的复制和原样粘贴要实现其实不太容易。

那么这种word转译的exe插件,他们是怎么做到的,我现在产生了无限的思考......

相关文章
|
9月前
|
人工智能 前端开发 安全
免费的才是最贵的:阿里AntD圣诞节“踩蛋”事件
Ant Design 是由蚂蚁金服开源的一款前端设计框架。使用开源框架的好处就是我们之前提过的“避免重复造轮子”,可以很轻松地搭建出美观易用的网页/移动页面。比如按钮,它会给你很多预设好的按钮样式选择,拿来就用,无需你自己去费时间设计和实现。
|
10月前
|
编解码 Linux Windows
5款免费开源软件推荐,总有一款适合你
最近后台收到好多小伙伴的私信,今天继续推荐五款小工具,都是免费使用的,大家可以去试试看。
782 1
|
数据安全/隐私保护 计算机视觉
推荐五款实用的良心软件,无广告无弹窗
分享是一种神奇的东西,它使快乐增大,它使悲伤减小。
99 0
推荐五款实用的良心软件,无广告无弹窗
|
数据采集 文字识别 索引
安利5款体积小、无广告、超实用的软件
大家好,我又来啦,今天给大家带来的几款软件,共同特点都是体积小、无广告、超实用,大家观看完可以自行搜索下载哦。
151 0
安利5款体积小、无广告、超实用的软件
|
Web App开发 黑灰产治理 CDN
压箱底!8个珍藏多年的Chrome插件高速下载网站
Chrome插件以轻量化、使用方便倍受欢迎,我之前也曾经很多篇文章介绍过不少好用的Chrome插件。其中,不乏一些名气很大、功能很强的插件。
压箱底!8个珍藏多年的Chrome插件高速下载网站
【Unity 资源分享】☀️ | Unity 华丽炫酷特效资源分享!万年魂环拿到手软,让你直达封号斗罗~
目录 📢前言 🎄Unity特效展示 🏳️‍🌈魂环系列特效 🏳️‍🌈光剑特效 🏳️‍🌈球形特效 🏳️‍🌈爆炸特效 🎁资源下载
【Unity 资源分享】☀️ | Unity 华丽炫酷特效资源分享!万年魂环拿到手软,让你直达封号斗罗~
|
人工智能 运维 Cloud Native
1024程序员鼓励节来啦!限量手办、机械键盘、独家PDF下载等多重福利等你来!
1024程序员节,开发者社区为各位程序员准备了多种活动,精美礼品、技术干货任你挑选!
1024程序员鼓励节来啦!限量手办、机械键盘、独家PDF下载等多重福利等你来!
|
移动开发 开发工具 双11
你知道现在很火的APP推广神器Deeplink是什么吗?
Deeplink,又叫深度链接技术,是指在App/短信/广告里点击链接,能直接跳转到目标App具体位置的技术,深度链接打破了网站与App间的壁垒,成为实现网站与App相互跳转的桥梁。
|
算法 持续交付 UED
免费下载 | 为了提升你的煲剧体验,我们有一整本书的质保秘籍!
你看剧,我保障!阿里文娱全新推出《超级详实的优酷质量保障秘籍》,从体系建设、算法实践和研发效能,3大角度6个专项,全面剖析优酷各业务线保障能力。
8887 0
免费下载 | 为了提升你的煲剧体验,我们有一整本书的质保秘籍!