前段时间做了个类似云盘文件上传的功能,要支持多文件上传及上传进度监听。
现在将主体功能分享给大家!
话不多说,直接上代码!
1、前段页面布局
<body>
<h1>多文件上传,兼容IE8及以下版本,支持上传进度监听</h1>
<div class="body-content sub-body-content buy-cart-cont clearfix">
<div class="bigContainer">
<div class="searchContainer">
<div class="leftContainer">
<input type="file" id="fileSelect" multiple style="display:none;"/>
<div class="button upload" id="upload">上传</div>
</div>
</div>
</div>
</div>
<div class="upload-mark">
<div class="upload-head">
<div class="head-title">文件上传</div>
<div class="upload-close"></div>
<div class="upload-show small"></div>
</div>
<div class="upload-content">
<div class="filelabel">
<div class='info'>
<div class='filename'>文件名</div>
<div class='filesize'>大小</div>
<div class='filepath'>上传位置</div>
<div class='filestatus'>状态</div>
</div>
</div>
<div class="uploadfileList" id="uploadfileList"></div>
</div>
</div>
</body>
2、前段JS
只引入jquery.js即可
var filePath = "";//记录当前目录
var uploadfileList = [];
$(function(){
//上传按钮点击事件
$('#upload').click(function(){
$("#fileSelect").click();
})
//文件上传窗口关闭事件
$(".upload-close").click(function(){
$(".upload-mark").slideUp(500);
$(".uploadfileList").html("");//清空列表
uploadfileList = [];
})
//文件上传窗口缩放事件
$(".upload-show").click(function(){
if($(this).hasClass("small")){
$(this).removeClass("small").addClass("big");
$(".upload-content").hide(500);
} else {
$(this).removeClass("big").addClass("small");
$(".upload-content").show(500);
}
})
$("#fileSelect").change(function(){
$(".upload-show").removeClass("big").addClass("small");
if($(".upload-mark").css("display","block")){
$(".upload-content").slideDown(500);
}
var list = this.files;//原生js获取文件
var length = 0;
for(var i=0; i<list.length; i++){
if(length<30){
if(list[i].size > 1024*1024*1024*100){
alert("文件"+list[i].name+"大于100M");
} else {
reviewFile(list[i]);
list[i]['status'] = 0;//标记该文件未上传
uploadfileList[uploadfileList.length] = list[i];
length++;
}
} else {
alert("单次最多上传30个文件");
break;
}
}
uploadFile();
})
});
//文件选择完毕,展示已选择的文件列表
function reviewFile(file){
var fd = new FileReader();//实例化fileReader
fd.readAsDataURL(file);//base64,调它的readAsDataURL并把原生File对象传给它
fd.onload = function(){//监听它的onload事件
var filesize = "";
if(file.size < 1024){
filesize = file.size + "B";
} else if(file.size >= 1024 && file.size < 1024*1024){
filesize = parseInt(file.size/1024*10)/10 + "KB";
} else if(file.size >= 1024*1024 && file.size < 1024*1024*1024){
filesize = parseInt(file.size/1024/1024*10)/10 + "MB";
}
var html = "<div class='fileitem' id='"+file.name+"'>" +
"<div class='process'></div>" +
"<div class='info'>" +
"<div class='filename' title='"+file.name+"'>"+file.name+"</div>" +
"<div class='filesize'>"+filesize+"</div>" +
"<div class='filepath' title='"+filePath+"/'>"+filePath+"/</div>" +
"<div class='filestatus'>等待中...</div>" +
"</div>" +
"</div>";
$(".uploadfileList").append(html);
var height = $(".filelabel").height() + $(".uploadfileList").height();
$('.upload-content').eq(0).animate({scrollTop: height+'px'});//滚动条置于最底部
}
}
function uploadFile(){
if(uploadfileList.length>0){
for(var i=0; i<uploadfileList.length; i++){
if(uploadfileList[i]['status'] == 0){
var index = i;
var formData = new FormData();
formData.append('file',uploadfileList[i]);
formData.append('filePath',filePath);
$.ajax({
url:'<%= path %>/index',
type:'post',
data:formData,
dataType:'json',
processData:false,//用于对data参数进行序列化处理 这里必须false
contentType:false,//必须
xhr:xhrOnProgress(function(e){
var percent=e.loaded/e.total;//文件上传百分比,100%表示文件已上传至服务器,此时可能需要等待服务器处理结果
$(".fileitem").eq(index).children(".info").eq(0).children(".filestatus").eq(0).html(parseInt(percent*100)+"%");
$(".fileitem").eq(index).children(".info").eq(0).children(".filestatus").eq(0).css("color","#666");
$(".fileitem").eq(index).children(".process").eq(0).css("width",parseInt(percent*100)+"%");
}),
success:function(result){//服务器处理后对文件状态的标记
if(result != "" && result != []){
if(result.returnCode == 1){
uploadfileList[index]['status'] = 1;//标记该文件已上传
$(".fileitem").eq(index).children(".info").eq(0).children(".filestatus").eq(0).html("<div class='success' title='上传成功'></div>");
} else {
uploadfileList[index]['status'] = -1;//标记该文件上传失败
$(".fileitem").eq(index).children(".info").eq(0).children(".filestatus").eq(0).html("<div class='fail' title='"+result['message']+"'></div>");
}
} else {
uploadfileList[index]['status'] = -1;//标记该文件上传失败
$(".fileitem").eq(index).children(".info").eq(0).children(".filestatus").eq(0).html("<div class='fail' title='上传失败'></div>");
}
$(".fileitem").eq(index).children(".process").eq(0).css("width","0px");
uploadFile();//迭代调用,直到所有文件全部标记为上传成功或失败
},
error:function(){
uploadfileList[index]['status'] = -1;//标记该文件上传失败
$(".fileitem").eq(index).children(".info").eq(0).children(".filestatus").eq(0).html("<div class='fail' title='上传失败'></div>");
$(".fileitem").eq(index).children(".process").eq(0).css("width","0px");
uploadFile();//迭代调用,直到所有文件全部标记为上传成功或失败
}
});
break;//单线上传
}
}
}else{
alert("请选择文件!")
}
}
//文件上传进度监听
function xhrOnProgress(fun) {
xhrOnProgress.onprogress = fun; //绑定监听
return function() {//使用闭包实现监听绑
var xhr = $.ajaxSettings.xhr();//通过$.ajaxSettings.xhr();获得XMLHttpRequest对象
if (typeof xhrOnProgress.onprogress !== 'function') {//判断监听函数是否为函数
return xhr;
}
if (xhrOnProgress.onprogress && xhr.upload) {//如果有监听函数并且xhr对象支持绑定时就把监听函数绑定上去
xhr.upload.onprogress = xhrOnProgress.onprogress;
}
return xhr;
}
}
//计算字符串长度(英文占1个字符,中文汉字占2个字符)
String.prototype.gblen = function() {
var len = 0;
for (var i=0; i<this.length; i++) {
if (this.charCodeAt(i)>127 || this.charCodeAt(i)==94) {
len += 2;
} else {
len ++;
}
}
return len;
}
//JS 截取字符串(中英文,一个中文相当于2个字符),str:被截取字符串,len:截取的中文长度
function cut_str(str, len){
var char_length = 0;
for (var i = 0; i < str.length; i++){
if (str.charCodeAt(i)>127 || str.charCodeAt(i)==94) {
char_length += 1;
} else {
char_length += 0.5;
}
if (parseInt(char_length-0.5) == len){
return str.substr(0, i);
break;
}
}
}
3、后端代码,使用Servlet
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
public class indexServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public indexServlet() {
super();
}
public void destroy() {
super.destroy();
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
MultipartHttpServletRequest multipartRequest = resolver.resolveMultipart(request);
Map<String,MultipartFile> filemap = multipartRequest.getFileMap();
if(filemap==null || filemap.size()==0){
response.getWriter().print("{\"returnCode\":-1}");
}else{
Object[] keyArray = filemap.keySet().toArray();
/*for (Object key : keyArray) {
System.out.println("文件key值:"+key);
}*/
MultipartFile file = (MultipartFile)filemap.get(keyArray[0]);
String srcName = file.getOriginalFilename(); //原文件名
srcName = new String(srcName.getBytes("iso-8859-1"),"utf-8"); //中文乱码处理
long size = file.getSize(); //文件大小
System.out.println("收到文件:" + srcName + ",文件大小: " + size);
try {
String realPath = this.getServletConfig().getServletContext().getRealPath("/"); //获取项目真实路径(E:\For_Test\MyEclipse\demo06-fileUpload\src\main\webapp\)
System.out.println("存储路径:"+realPath+"upload/"+srcName);
BufferedInputStream bis = new BufferedInputStream(file.getInputStream());
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(realPath+"upload/"+srcName)));
byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
}
bos.close();
bis.close();
response.getWriter().print("{\"returnCode\":1}");
} catch (IOException e) {
e.printStackTrace();
response.getWriter().print("{\"returnCode\":-1}");
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
public void init() throws ServletException {
}
}
看效果: