扩展ExtJS htmlEditor,支持插入网络图片、本地上传图片功能,并能设置图片显示的宽高
自定义扩展js
/** * 扩展ExtJS htmlEditor插件,支持插入网络图片、本地上传图片功能 * * @author hzp */ Ext.namespace('Ext.ux','Ext.ux.plugins'); Ext.ux.plugins.ImageDialog=function(config){ config=config||{}; Ext.apply(this,config); var htmlEditorObj; this.init=function(htmlEditor) { this.editor=htmlEditor; htmlEditorObj=htmlEditor; this.editor.on('render',onRender,this); }; function onRender(){ if( ! Ext.isSafari){ this.editor.tb.add({ itemId : 'htmlEditorImage', cls : 'x-btn-icon x-edit-insertimage', enableToggle : false, scope : this, handler : function(){ this.imageWin(); }, clickEvent : 'mousedown', tooltip : config.buttonTip || { title : '插入图片', text : '插入图片到编辑器', cls : 'x-html-editor-tip' }, tabIndex :- 1 }); } } var win; //插入图片主窗口 this.imageWin=function(){ win=new Ext.Window({ title:'插入图片', width:400, height:260, resizable:false, closeAction:'hide', autoDestroy:false, items:[{ xtype:'tabpanel', anchor:'100%', border: false, activeTab: 0, items:[ //网络图片 webImg, //本地上传 uploadImage ] }] }); win.show() } //网络图片选项卡 var webImg=new Ext.form.FormPanel({ title:'网络图片', anchor:'100%', //height:200, autoHeight:true, labelWidth: 80, labelAlign: 'right', border: false, autoDestroy:false, bodyStyle : 'padding-top:30px;', items:[{ xtype:'textfield', id:'wimgWidth', fieldLabel:'显示宽度', name:'width', anchor:'90%' },{ xtype:'textfield', id:'wimgHeight', fieldLabel:'显示高度', name:'height', anchor:'90%' },{ xtype:'textfield', id:'wimgUrl', fieldLabel:'图片网址', anchor:'90%', emptyText:'http://', allowBlank:false, blankText:'图片网址不能为空' }], buttons:[{ text:'确定', handler:function(){ if(webImg.form.isValid()){ //确定插入网络图片 var img="<img src='"+Ext.getCmp('wimgUrl').getValue()+"'"; //高度不为空 if(""!=Ext.getCmp('wimgHeight').getValue()){ img+= " height="+Ext.getCmp('wimgHeight').getValue(); } //宽度不为空 if(""!=Ext.getCmp('wimgWidth').getValue()){ img+= " width="+Ext.getCmp('wimgWidth').getValue() } img+= " />"; //插入图片 htmlEditorObj.insertAtCursor(img); } } },{ text:'取消', handler:function(){ Ext.getCmp('wimgUrl').reset(); Ext.getCmp('wimgHeight').reset(); Ext.getCmp('wimgWidth').reset(); win.hide(); } }] }); //上传图片选项卡 var uploadImage=new Ext.form.FormPanel({ title:'本地上传', anchor:'100%', //height:200, autoHeight:true, labelWidth: 80, labelAlign: 'right', border: false, autoDestroy:false, bodyStyle : 'padding-top:30px;', items:[{ xtype:'textfield', id:'imgWidth', fieldLabel:'显示宽度', name:'width', anchor:'90%' },{ xtype:'textfield', id:'imgHeight', fieldLabel:'显示高度', name:'height', anchor:'90%' },{ xtype:'textfield', id:'imgUrl', fieldLabel:'本地上传', name:'height', anchor:'90%', readOnly:true, allowBlank:false, blankText:'请点击文本框上传本地图片', listeners:{ focus:function(obj){ upload(obj); } } }], buttons:[{ text:'确定', handler:function(){ //确定插入上传的图片 var img="<img src='"+Ext.getCmp('imgUrl').getValue()+"'"; //高度不为空 if(""!=Ext.getCmp('imgHeight').getValue()){ img+= " height="+Ext.getCmp('imgHeight').getValue(); } //宽度不为空 if(""!=Ext.getCmp('imgWidth').getValue()){ img+= " width="+Ext.getCmp('imgWidth').getValue() } img+= " />"; //插入图片 htmlEditorObj.insertAtCursor(img); } },{ text:'取消', handler:function(){ Ext.getCmp('imgUrl').reset(); Ext.getCmp('imgHeight').reset(); Ext.getCmp('imgWidth').reset(); win.hide(); } }] }); function upload(obj) { var dialog = new Ext.ux.UploadDialog.Dialog({ title:config.title || '图片上传', url: config.url || '', post_var_name: config.post_var_name || 'file', reset_on_hide: config.reset_on_hide || false, modal: config.modal || true, draggable: config.draggable || true, proxyDrag: config.proxyDrag || true, resizable: config.resizable || true, constraintoviewport: true, permitted_extensions: config.permitted_extensions || ['JPG','jpg','GIF','gif','PNG','png'], allow_close_on_upload: config.allow_close_on_upload || false, upload_autostart: config.upload_autostart || true //是否自动上传 }); dialog.show(); //上传成功后回调函数 dialog.on('uploadsuccess',function(dialog, filename, resp_data, record){ //把上传成功的图片相对路径赋值到imgUrl框中 Ext.getCmp('imgUrl').setValue(resp_data.data.msg); dialog.hide(); }); } }
引用页面
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <link rel="stylesheet" type="text/css" href="extjs2.3/resources/css/ext-all.css" /> <script type="text/javascript" src="extjs2.3/adapter/ext/ext-base.js"></script> <script type="text/javascript" src="extjs2.3/ext-all.js"></script> <script type="text/javascript" src="extjs2.3/ux/upload/js/Ext.ux.UploadDialog.js" ></script> <script type="text/javascript" src="extjs2.3/ux/upload/js/Ext.ux.UploadDialog.packed.js"></script> <link rel="stylesheet" type="text/css" href="extjs2.3/ux/upload/css/Ext.ux.UploadDialog.css"/> <script type="text/javascript" src="customer.js" ></script> <script type="text/javascript" src="Ext.ux.UploadDialog.zh-cn.js" ></script> <script type="text/javascript"> Ext.onReady(function(){ Ext.QuickTips.init(); new Ext.form.HtmlEditor({ renderTo: 'form', id:'content', width: 650, height: 350, plugins: new Ext.ux.plugins.ImageDialog ({ url: '/ExtjsTest/upload.action', post_var_name:'imageUpload' }) }); }); </script> </head> <body> <div id="form"></div> </body> </html>
上传服务端处理
package com.hzp;
import java.io.File;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport{
//图片上传
private File imageUpload;
private String imageUploadContentType;
private String imageUploadFileName;
//图片上传,并重新赋值imageUrl为上传后的相对路径
public String uploadImage()throws Exception{
HttpServletResponse response=ServletActionContext.getResponse();
response.setContentType("text/html;charset=UTF-8");
PrintWriter pw=response.getWriter();
String result="{success:false}";
try {
// 先判断是否有上传图片,有则上传
if (null != imageUpload) {
String path = FileSystem.uploadFile(this.imageUpload,getExtention(imageUploadFileName));
// 上传成功,则返回路径
if (null != path) {
String img=FileSystem.getFileSystemFileRootPath()+path;
result="{success:true,data:{msg:'"+img+"'}}";
}
}
pw.print(result);
return null;
} catch (Exception e) {
e.printStackTrace();
pw.print(result);
return null;
}finally{
pw.flush();
pw.close();
}
}
//获取文件的类型 如: .txt
private String getExtention(String fileName) {
int pos = fileName.lastIndexOf( "." );
return fileName.substring(pos).toString();
}
public File getImageUpload() {
return imageUpload;
}
public void setImageUpload(File imageUpload) {
this.imageUpload = imageUpload;
}
public String getImageUploadContentType() {
return imageUploadContentType;
}
public void setImageUploadContentType(String imageUploadContentType) {
this.imageUploadContentType = imageUploadContentType;
}
public String getImageUploadFileName() {
return imageUploadFileName;
}
public void setImageUploadFileName(String imageUploadFileName) {
this.imageUploadFileName = imageUploadFileName;
}
}
文件服务器通信工具类
package com.hzp;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import javax.servlet.http.HttpServletResponse;
import com.sun.xml.internal.ws.util.StringUtils;
/**
* 文件服务器操作工具类 负责与文件服务器通信,并进行上传、下载等操作
*
* @author hzp
*
*/
public class FileSystem {
// 加载文件服务器相关配置信息
private static InputStream in = FileSystem.class.getClassLoader()
.getResourceAsStream("fileSystem.properties");
private static Properties p = new Properties();
// 服务器的url前缀(ip与端口)
private static String path = "http://localhost:"
+ ServletActionContext.getRequest().getLocalPort();
// 获取文件服务器文件存放的路径
public static String getFileSystemFileRootPath() throws Exception {
p.load(in);
String root = path + p.getProperty("file_root_path");
return root;
}
// 获取文件服务器文件上传servlet的路径
public static String getFileSystemUploadServletPath() throws Exception {
p.load(in);
String root = path + p.getProperty("upload_servlet");
return root;
}
// 获取文件服务器文件下载servlet的路径
public static String getFileSystemDownloadServletPath() throws Exception {
p.load(in);
String root = path + p.getProperty("download_servlet");
return root;
}
/**
* 文件上传 已封装文件重命名逻辑
*
* @param upload
* 要上传的文件
* @param fileType
* 文件类型,如 .txt .jpg
* @return 上传成功则返回文件保存的相对路径,否则为null
* @throws Exception
*/
public static String uploadFile(File upload, String fileType)
throws Exception {
InputStream is = null;
OutputStream os = null;
HttpURLConnection conn = null;
String filePath = null;
try {
// 上传文件的子文件夹,默认为当前日期的子文件夹
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String savePath = "/" + sdf.format(new Date());
// 重命名上传的文件
String newFileName = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss")
.format(new Date()) + fileType;
// 上传文件的完整相对路径
filePath = savePath + "/" + newFileName;
String url = getFileSystemUploadServletPath() + "?savePath="
+ savePath + "&newFileName=" + newFileName;
// *********与文件服务器通信,并传递数据********//
URL u = new URL(url);
conn = (HttpURLConnection) u.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setConnectTimeout(10000);
conn.setUseCaches(false);
conn.setInstanceFollowRedirects(true);
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
conn.setChunkedStreamingMode(64);
conn.connect();
os = conn.getOutputStream();
is = new BufferedInputStream(new FileInputStream(upload));
// 设置缓存
byte[] buffer = new byte[8192];
int length = 0;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
os.flush();
conn.getInputStream();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
// 关闭资源
if (null != is) {
is.close();
}
if (null != os) {
os.close();
}
if (null != conn) {
conn.disconnect();
}
}
// 调用文件服务器进行上传文件操作成功,则返回文件的相对路径
if (conn.getResponseCode() == HttpServletResponse.SC_OK) {
return filePath;
} else {
return null;
}
}
/**
* 文件上传 已封装文件重命名逻辑
*
* @param bytes
* 要上传的文件的二进制流
*
* @param fileType
* 文件类型,如 .txt .jpg
* @return 上传成功则返回文件保存的相对路径,否则为null
* @throws Exception
*/
public static String uploadFile(byte[] bytes, String fileType)
throws Exception {
OutputStream os = null;
HttpURLConnection conn = null;
String filePath = null;
try {
// 上传文件的子文件夹,默认为当前日期的子文件夹
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String savePath = "/" + sdf.format(new Date());
// 重命名上传的文件
String newFileName = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss")
.format(new Date()) + fileType;
// 上传文件的完整相对路径
filePath = savePath + "/" + newFileName;
String url = getFileSystemUploadServletPath() + "?savePath="
+ savePath + "&newFileName=" + newFileName;
// *********与文件服务器通信,并传递数据********//
URL u = new URL(url);
conn = (HttpURLConnection) u.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setConnectTimeout(10000);
conn.setUseCaches(false);
conn.setInstanceFollowRedirects(true);
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
conn.setChunkedStreamingMode(64);
conn.connect();
os = conn.getOutputStream();
os.write(bytes);
os.flush();
conn.getInputStream();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
// 关闭资源
if (null != os) {
os.close();
}
if (null != conn) {
conn.disconnect();
}
}
// 调用文件服务器进行上传文件操作成功,则返回文件的相对路径
if (conn.getResponseCode() == HttpServletResponse.SC_OK) {
return filePath;
} else {
return null;
}
}
/**
* 下载文件
*
* @param filePath
* 文件存储的相对路径
*
*
* @return
* @throws Exception
*/
public static InputStream downloadFile(String filePath) throws Exception {
HttpURLConnection conn = null;
String url = getFileSystemDownloadServletPath() + "?filePath="
+ filePath;
// *********与文件服务器通信********//
URL u = new URL(url);
conn = (HttpURLConnection) u.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setConnectTimeout(10000);
conn.setRequestMethod("POST");
conn.connect();
BufferedInputStream is = new BufferedInputStream(conn.getInputStream());
// 调用文件服务器进行上传文件操作成功,则返回文件的流
if (conn.getResponseCode() == HttpServletResponse.SC_OK) {
return is;
} else {
return null;
}
}
/**
* 获取文件后缀
*
* <p>
* 从文件名中获取文件后缀,获取后的后缀形式形如:“.txt”、“.jpg”等,并且后缀全部转换为小写字母。<br/>
* 另外:如果文件没有后缀名,则返回一个空字符串;如果文件名为空,则返回<code>null</code>。
* </p>
*
* @param fileName
* 文件名
*
* @return <code>postfix</code> 文件后缀
*/
public static String getFilePostfix(String fileName) {
String postfix = null;
if (fileName==null || fileName=="") {
return postfix;
}
fileName = fileName.trim();
int pos = fileName.lastIndexOf(".");
if (pos == -1) {
postfix = "";
return "";
} else {
postfix = fileName.substring(pos).toString().toLowerCase();
}
return postfix;
}
}