1. 程式人生 > 其它 >百度編輯器貼上圖片自動上傳到伺服器(Java版)

百度編輯器貼上圖片自動上傳到伺服器(Java版)

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=newActiveXObject("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?newXMLHttpRequest():newActiveXObject("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;

returnresult;

},

//建立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=newActiveXObject(versions[i]);

if(xmldom!=null)break;

}catch(ex){

//跳過

alert("建立document物件失敗!");

}

}

returnxmldom;

}

}

UEditorAction儲存圖片方法

@RequestMapping("/uploadImg")

publicvoiduploadADO(HttpServletRequest request,HttpServletResponse response){

String path1=request.getContextPath();

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

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

//設定資料傳輸單元大小為1KB

intunit_size=1024;

//初始化xml檔案大小(以位元組為單位)

intxmlFileSize=0;

//初始化上傳檔名稱(完整檔名)

String xmlFilename="";

//初始化上傳檔案儲存路徑(絕對物理路徑)

String xmlFilepath="";

//宣告檔案儲存位元組陣列

byte[]xmlFileBytes=null;

try{

//初始化 SAX 序列xml檔案解析器

SAXBuilder builder=newSAXBuilder();

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

intunit_count=0;

//為儲存檔案內容的位元組陣列分配儲存空間

xmlFileBytes=newbyte[xmlFileSize];

//迴圈讀取檔案內容,並儲存到位元組陣列中

Iterator it_content=eRoot.getChildren("uploadContent")

.iterator();

while(it_content.hasNext()){

//初始化Base64編碼解碼器

BASE64Decoder base64=newBASE64Decoder();

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=newFile(xmlFilepath);

if(!path.exists()){

path.mkdirs();

}

//儲存檔案 word貼上圖片的名稱

File file=newFile(path,xmlFilename);

//建立檔案輸入輸出流

FileOutputStream fos=newFileOutputStream(file);

//寫入檔案內容

fos.write(xmlFileBytes);

fos.flush();

//關閉檔案輸入輸出流

fos.close();

ReturnUploadImage rui=newReturnUploadImage();

rui.setTitle(xmlFilename);//這裡需要設定檔名稱如:xxx.jpg

rui.setOriginal(xmlFilename);//這裡需要設定檔名稱如:xxx.jpg

rui.setState("SUCCESS");

rui.setUrl(basePath+relativePath+xmlFilename);

JSONObject json=newJSONObject(rui);

String result=json.toString();//這邊就是為了返回給UEditor做的格式轉換

response.getWriter().write(result);

}catch(Exception e){

e.printStackTrace();

}

}

優化後的程式碼:

upload.jsp

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

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

<%@pageimport="Xproer.*"%>

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

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

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

<%@pageimport="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

booleanisMultipart = ServletFileUpload.isMultipartContent(request);

FileItemFactory factory =newDiskFileItemFactory();

ServletFileUpload upload =newServletFileUpload(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 =newUploader(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自帶的更好,傳圖效率更高。

上傳成功後,圖片地址自動替換成伺服器地址

圖片自動儲存在伺服器中

詳細資料可以參考這篇文章:

Ueditor Word圖片轉存互動 – 澤優軟體部落格

討論群:223813913