官网地址http://ueditor.baidu.com

Git 地址 https://github.com/fex-team/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/

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/

百度ueditor中复制word图文时图片转存任然保持灰色不可用的更多相关文章

  1. 百度UEditor编辑器关闭抓取远程图片功能(默认开启)

    这个坑娘的功能,开始时居然不知道如何触发,以为有个按钮,点击一下触发,翻阅了文档,没有发现,然后再网络上看到原来是复制粘贴非白名单内的图片到编辑框时触发,坑娘啊............... 问题又来 ...

  2. 百度UEditor编辑器从word粘贴公式

    官网地址http://ueditor.baidu.com Git 地址 https://github.com/fex-team/ueditor 参考博客地址 http://blog.ncmem.com ...

  3. 百度UEditor在线编辑器的配置和图片上传

    前言 最近在项目中使用了百度UEditor富文本编辑器,配置UEditor过程中遇到了几个问题,在此记录一下解决方案和使用方法,避免以后使用UEditor出现类似的错误. 基本配置 一.下载UEdit ...

  4. ueditor编辑器中从word中复制带图片的信息的操作演示

    我司需要做一个需求,就是使用富文本编辑器时,不要以上传附件的形式上传图片,而是以复制粘贴的形式上传图片. 在网上找了一下,有一个插件支持这个功能. WordPaster 安装方式如下: 直接使用Wor ...

  5. 关于富文本复制word,里面掺杂图片上传的问题

    图片的复制无非有两种方法,一种是图片直接上传到服务器,另外一种转换成二进制流的base64码目前限chrome浏览器使用首先以um-editor的二进制流保存为例:打开umeditor.js,找到UM ...

  6. 在MyEclipse中复制web工程时要注意的事项

    有时候我们要在MyEclipse中将一个WEB工程进行复制,然后将工程名进行重命名,但这样还是会出错,因为只改变工程名还不够,一般在MyEclipse中WEB工程的[WebRoot]目录名和工程名是一 ...

  7. Android中 在显示ImageView时图片上面和下面都出现一段空白区间的解决办法

    开始的时候是在ScrollView中显示ImageView的时候出现这样的问题,以为是要对ScrollView进行设置的,后来发现单独显示一个ImageView的时候也会出现这样的问题,由此才知道是应 ...

  8. word图文混排复制到UEditor图片不显示

    word图片转存,是指UEditor为了解决用户从word中复制了一篇图文混排的文章粘贴到编辑器之后,word文章中的图片数据无法显示在编辑器中,也无法提交到服务器上的问题而开发的一个操作简便的图片转 ...

  9. 如何从word中复制内容到网站后台编辑器中

    word图片转存,是指UEditor为了解决用户从word中复制了一篇图文混排的文章粘贴到编辑器之后,word文章中的图片数据无法显示在编辑器中,也无法提交到服务器上的问题而开发的一个操作简便的图片转 ...

随机推荐

  1. python爬虫框架scrapy 豆瓣实战

    Scrapy 官方介绍是 An open source and collaborative framework for extracting the data you need from websit ...

  2. 【数据结构】Tournament Chart

    Tournament Chart 题目描述 In 21XX, an annual programming contest, Japan Algorithmist GrandPrix (JAG) has ...

  3. golang跨平台编译

    // 目标平台linux 64 SET CGO_ENABLED=0 SET GOOS=linux SET GOARCH=amd64 go build //目标平台windows SET CGO_ENA ...

  4. javascript 写一个ajax 自动拦截,并下载数据

    <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8&quo ...

  5. MySQL 字段类型介绍

    MySQL 基础篇 三范式 MySQL 军规 MySQL 配置 MySQL 用户管理和权限设置 MySQL 常用函数介绍 MySQL 字段类型介绍 MySQL 多列排序 MySQL 行转列 列转行 M ...

  6. Abp SSO

    官方的文档有个坑. 首先建立的应该是 .net core  MPA版本. 把文档上的startup.cs配置写入 MVC 项目中. 这样测试才能通过.不然,测试项目     var disco = a ...

  7. 使用swagger在netcorewebapi项目中自动生成文档

    一.背景 随着前后端分离模式大行其道,我们需要将后端接口撰写成文档提供给前端,前端可以查看我们的接口,并测试,提高我们的开发效率,减少无效的沟通.在此情况下,通过代码自动生成文档,这种需求应运而生,s ...

  8. C++编译 C # 调用方法

    C++编译    C # 调用方法 编译时使用  public ref class ABC {   ... }; 调用时  右键---引用 --- 添加dll引用  即可

  9. C++ raw string literal

    raw string literal 以   R"(  开头, )" 结束,是可以跨越多行的字符串字面值,转义字符如 \t\n 在raw string literal中是普通的文本 ...

  10. React/react相关小结

    React React组件由React元素组成,React组件使用React.Component或React.PureComponent来生成:React元素使用JSX的语法来编写或使用React.c ...