C语言 Finder 学生排队 Nginx 人工智能 TCP连接 air click事件 jquery去除空格 jquery使用ajax nodejs后端开发 matlab求向量的模 java循环语句 java学习平台 liunx命令大全 pushstate 俄罗斯方块c语言代码 java程序设计基础 html特殊字符 隐藏进程 英雄联盟体验服转换器 魔兽地图七个人 烧饼修改器打不开 微信猜拳 pdf密码移除 不屑表情包 ios删除描述文件 0x000007a lrc软件 xlwt maya骨骼绑定教程 lol改皮肤软件 c语言小游戏代码 啊哈c语言 远程桌面管理工具 dbgview rdpwrap 豌豆代理 getdata软件 护魂者的命运
当前位置: 首页 > 学习教程  > 编程语言

百度ueditor 等在线编辑器是怎么实现支持 WORD 的粘贴的?

2020/7/24 10:00:47 文章标签:

1.4.2之后官方并没有做功能的改动,1.4.2在word复制这块没有bug,其他版本会出现手动无法转存的情况

本文使用的后台是Java。前端为Jsp(前端都一样,后台如果语言不通得自己做 Base64编码解码)

因为公司业务需要支持IE8 ,网上其实有很多富文本框,效果都很好。

例如www.wangEditor.com  但试了一圈都不支持IE8 。

所以回到Ueditor,由于官方没有维护,新的neuditor 也不知道什么时候能支持word自动转存,只能自己想办法。

如果没有必要,不建议使用ueditor。我也是没有办法。

改动过后的插件只适合IE8。

这里要说明的一点是百度官方的编辑器不支持word图片批量转存,粘贴word后需要手动选择图片再进行上传一次操作。网上找到的大部分的示例都是这个操作。如果需要自动批量上传word图片的话可以使用WordPaster这个控件。

 

1.IE设置

在受信任站点里添加信任网站。

这里本机测试使用的直接是   http://localhost

因为需要读取客户端的文件,所以需要设置允许访问数据源。

ActiveXObject设置可以去网上参考,这里不列举了。

前面的

到这里 IE 的准备工作完成了。

修改ueditor.all.js关键代码

14006行附近,如果是其他版本的ueditor,在功能正常的情况下,可以拷贝下面代码。

var imgPath = attrs.src;

var imgUrl = attrs.src;

if (navigator.appName === 'Microsoft Internet Explorer') { //判断是否是IE浏览器

    if (navigator.userAgent.match(/Trident/i) && navigator.userAgent.match(/MSIE 8.0/i)) { //判断浏览器内核是否为Trident内核IE8.0

        var realPath = imgPath.substring(8, imgPath.length);

        var filename = imgPath.substring(imgPath.lastIndexOf('/') + 1, imgPath.length);

        var result = UploadForIE.saveAttachment(filename, realPath);

        if (result) {

            var json = eval('(' + result + ')');

            imgUrl = json.url;

        }

    }

}

img.setAttr({

 

    width: attrs.width,

    height: attrs.height,

    alt: attrs.alt,

    word_img: attrs.src,

    src: imgUrl,

    'style': 'background:url(' + (flag ? opt.themePath + opt.theme + '/images/word.gif': opt.langPath + opt.lang + '/images/localimage.png') + ') no-repeat center center;border:1px solid #ddd'

})

 

uploadForIE.js。

var UploadForIE = {

    // 保存到xml附件,并且通过ajax 上传

    saveAttachment: function(upload_filename, localFilePath) {

        //后台接受图片保存的方法。

        var upload_target_url = "uploadImg";

        var strTempFile = localFilePath;

        // 创建XML对象,组合XML文档数据

        var xml_dom = UploadForIE.createDocument();

        xml_dom.loadXML('<?xml version="1.0" encoding="GBK" ?> <root/>');

        // 创建ADODB.Stream对象

        var ado_stream = new ActiveXObject("adodb.stream");

        // 设置流数据类型为二进制类型

        ado_stream.Type = 1; // adTypeBinary

        // 打开ADODB.Stream对象

        ado_stream.Open();

        // 将本地文件装载到ADODB.Stream对象中

        ado_stream.LoadFromFile(strTempFile);

        // 获取文件大小(以字节为单位)

        var byte_size = ado_stream.Size;

        // 设置数据传输单元大小为1KB

        var byte_unit = 1024;

        // 获取文件分割数据单元的数量

        var read_count = parseInt((byte_size / byte_unit).toString()) + parseInt(((byte_size % byte_unit) == 0) ? 0 : 1);

 

        // 创建XML元素节点,保存上传文件名称

        var node = xml_dom.createElement("uploadFilename");

        node.text = upload_filename.toString();

        var root = xml_dom.documentElement;

        root.appendChild(node);

 

        // 创建XML元素节点,保存上传文件大小

        var node = xml_dom.createElement("uploadFileSize");

        node.text = byte_size.toString();

        root.appendChild(node);

 

        // 创建XML元素节点,保存上传文件内容

        for (var i = 0; i < read_count; i++) {

            var node = xml_dom.createElement("uploadContent");

            // 文件内容编码方式为Base64

            node.dataType = "bin.base64";

            // 判断当前保存的数据节点大小,根据条件进行分类操作

            if ((parseInt(byte_size % byte_unit) != 0) && (i == parseInt(read_count - 1))) {

                // 当数据包大小不是数据单元的整数倍时,读取最后剩余的小于数据单元的所有数据

                node.nodeTypedValue = ado_stream.Read();

            } else {

                // 读取一个完整数据单元的数据

                node.nodeTypedValue = ado_stream.Read(byte_unit);

            }

            root.appendChild(node);

        }

 

        // 关闭ADODB.Stream对象

        ado_stream.Close();

        delete ado_stream;

        // 创建Microsoft.XMLHTTP对象

        // var xmlhttp = new ActiveXObject("microsoft.xmlhttp");

        var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHttp");

        // 打开Microsoft.XMLHTP对象

        xmlhttp.open("post", upload_target_url, false);

        // 使用Microsoft.XMLHTP对象上传文件

        xmlhttp.send(xml_dom);

        var state = xmlhttp.readyState;

        var success_state = true;

        if (state != 4) {

            success_state = false;

        }

        var result = xmlhttp.responseText;

 

        delete xmlhttp;

        return result;

    },

 

    // 创建DOMdocuemnt

    createDocument: function() {

        var xmldom;

        var versions = ["MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.5.0", "MSXML2.DOMDocument.4.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument"],

        i,

        len;

        for (i = 0, len = versions.length; i < len; i++) {

            try {

                xmldom = new ActiveXObject(versions[i]);

                if (xmldom != null) break;

            } catch(ex) {

                //跳过

                alert("创建document对象失败!");

            }

        }

        return xmldom;

    }

}

 

UEditorAction保存图片方法

@RequestMapping("/uploadImg")

    public void uploadADO(HttpServletRequest request, HttpServletResponse response) {

        String path1 = request.getContextPath();

        String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() +path1;

 

        String rootPath = request.getServletContext().getRealPath("/");

        // 设置数据传输单元大小为1KB

        int unit_size = 1024;

        // 初始化xml文件大小(以字节为单位)

        int xmlFileSize = 0;

        // 初始化上传文件名称(完整文件名)

        String xmlFilename = "";

        // 初始化上传文件保存路径(绝对物理路径)

        String xmlFilepath = "";

        // 声明文件存储字节数组

        byte[] xmlFileBytes = null;

        try {

            // 初始化 SAX 串行xml文件解析器

            SAXBuilder builder = new SAXBuilder();

            Document doc = builder.build(request.getInputStream());

            Element eRoot = doc.getRootElement();

            // 获取上传文件的完整名称

            Iterator it_name = eRoot.getChildren("uploadFilename").iterator();

            if (it_name.hasNext()) {

                xmlFilename = ((Element) it_name.next()).getText();

            }

            //存放的相对路径目录

            String  relativePath = "/temp/"+EditorUtil.getToday()+"/";

            xmlFilepath = rootPath+ relativePath;

 

            // 获取上传文件的大小

            Iterator it_size = eRoot.getChildren("uploadFileSize").iterator();

            if (it_size.hasNext()) {

                xmlFileSize = Integer.parseInt(((Element) it_size.next())

                        .getText());

                if (xmlFileSize > 0) {

                    int unit_count = 0;

                    // 为存储文件内容的字节数组分配存储空间

                    xmlFileBytes = new byte[xmlFileSize];

                    // 循环读取文件内容,并保存到字节数组中

                    Iterator it_content = eRoot.getChildren("uploadContent")

                            .iterator();

                    while (it_content.hasNext()) {

                        // 初始化Base64编码解码器

                        BASE64Decoder base64 = new BASE64Decoder();

                        byte[] xmlNodeByteArray = base64

                                .decodeBuffer(((Element) it_content.next())

                                        .getText());

                        if (xmlNodeByteArray.length >= unit_size) {

                            // 读取一个完整数据单元的数据

                            System.arraycopy(xmlNodeByteArray, 0, xmlFileBytes,

                                    unit_count * unit_size, unit_size);

                        } else {

                            // 读取小于一个数据单元的所有数据

                            System.arraycopy(xmlNodeByteArray, 0, xmlFileBytes,

                                    unit_count * unit_size, xmlFileSize

                                            % unit_size);

                        }

                        // 继续向下读取文件内容

                        unit_count++;

                    }

                }

            }

 

            // 保存路径

            File path = new File(xmlFilepath);

            if(!path.exists()){

                path.mkdirs();

            }

            // 保存文件 word粘贴图片的名称

            File file = new File(path,xmlFilename);

            // 创建文件输入输出流

            FileOutputStream fos = new FileOutputStream(file);

            // 写入文件内容

            fos.write(xmlFileBytes);

            fos.flush();

            // 关闭文件输入输出流

            fos.close();

 

            ReturnUploadImage rui = new ReturnUploadImage();

            rui.setTitle(xmlFilename);//这里需要设置文件名称如:xxx.jpg

            rui.setOriginal(xmlFilename);//这里需要设置文件名称如:xxx.jpg

            rui.setState("SUCCESS");

            rui.setUrl(basePath +relativePath+xmlFilename);

 

            JSONObject json = new JSONObject(rui);

            String result = json.toString();//这边就是为了返回给UEditor做的格式转换

            response.getWriter().write(result);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

优化后的代码:

upload.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<%@ page contentType="text/html;charset=utf-8"%>

<%@ page import = "Xproer.*" %>

<%@ page import="org.apache.commons.lang.StringUtils" %>

<%@ page import="org.apache.commons.fileupload.*" %>

<%@ page import="org.apache.commons.fileupload.disk.*" %>

<%@ page import="org.apache.commons.fileupload.servlet.*" %>

<%out.clear();

/* 

    更新记录:

        2013-01-25 取消对SmartUpload的使用,改用commons-fileupload组件。因为测试发现SmartUpload有内存泄露的问题。

*/

//String path = request.getContextPath();

//String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

 

String uname = "";//        = request.getParameter("uid");

String upass = "";//        = request.getParameter("fid");

 

// Check that we have a file upload request

boolean isMultipart = ServletFileUpload.isMultipartContent(request);

FileItemFactory factory = new DiskFileItemFactory();  

ServletFileUpload upload = new ServletFileUpload(factory);

//upload.setSizeMax(262144);//256KB

List files = null;

try

{

    files = upload.parseRequest(request);

}

catch (FileUploadException e)

{// 处理文件尺寸过大异常 

    out.println("上传文件异常:"+e.toString());

    return;

  

}

 

FileItem imgFile = null;

// 得到所有上传的文件

Iterator fileItr = files.iterator();

// 循环处理所有文件

while (fileItr.hasNext())

{

    // 得到当前文件

    imgFile = (FileItem) fileItr.next();

    // 忽略简单form字段而不是上传域的文件域(<input type="text" />等)

    if(imgFile.isFormField())

    {

        String fn = imgFile.getFieldName();

        String fv = imgFile.getString();

        if(fn.equals("uname")) uname = fv;

        if(fn.equals("upass")) upass = fv;

    }

    else

    {

        break;

    }

}

Uploader up = new Uploader(pageContext,request);

up.SaveFile(imgFile);

String url = up.GetFilePathRel();

out.write(url);

response.setHeader("Content-Length",url.length()+"");//返回Content-length标记,以便控件正确读取返回地址。

%>

 

剩下的后台功能和js参考下载文件中的UEditorAction 和 uploadForIE.js。

下面是我安装的依赖pom结构,可以根据自己的进行调整。

  <dependency>

            <groupId>com.baidu</groupId>

            <artifactId>ueditor</artifactId>

            <version>1.1.0</version>

        </dependency>

 

基于springboot 和idea ,这里只提取了自动转存功能出来,功能还没测试,git代码没做公开,等后续测试好了再公开。

可以先使用csdn下载查看代码。

pom里引用了ueditor.jar

需要根据各自情况安装jar包

1.4.2中的jar包版本是1.1.0

mvn install:install-file -DgroupId=com.baidu -DartifactId=ueditor -Dversion=1.1.0 -Dpackaging=jar -Dfile=\ueditor\jsp\lib\ueditor-1.1.0.jar

运行

UeditorApplication的main方法

然后访问http://localhost:8088/ueditor/ 就可以测试了。

 

完成后的效果:

图片自动批量上传,不需要手动一张张选择图片上传,用户体验比百度ueditor自带的更好,传图效率更高。

 

上传成功后,图片地址自动替换成服务器地址

 

图片自动保存在服务器中

 

详细资料可以参考这篇文章:

http://blog.ncmem.com/wordpress/2019/08/12/ueditor-word%E5%9B%BE%E7%89%87%E8%BD%AC%E5%AD%98%E4%BA%A4%E4%BA%92/

 

讨论群:223813913


本文链接: http://www.dtmao.cc/news_show_50190.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?