• xhEditor上传图片word


    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({

        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=ueditorjsplibueditor-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

  • 相关阅读:
    随机森林算法参数调优
    BAYES和朴素BAYES
    阿里云 金融接口 token PHP
    PHP mysql 按时间分组 表格table 跨度 rowspan
    MySql按周,按月,按日分组统计数据
    PHP 获取今日、昨日、本周、上周、本月的等等常用的起始时间戳和结束时间戳的时间处理类
    thinkphp5 tp5 会话控制 session 登录 退出 检查检验登录 判断是否应该跳转到上次url
    微信 模板消息
    php 腾讯 地图 api 计算 坐标 两点 距离 微信 网页 WebService API
    php添加http头禁止浏览器缓存
  • 原文地址:https://www.cnblogs.com/songsu/p/13637322.html
Copyright © 2020-2023  润新知