Plupload 是一个Web浏览器上的界面友好的文件上传模块,可显示上传进度、图像自动缩略和上传分块。可同时上传多个文件。
由于可以实现把文件分块上传,所以可以满足在某些限制了上传大小的环境上传大文件的需求。
plupload可以运行在多种环境下,如:html5,flash,siverlight,html等。下面是使用siverlight环境的简单配置:
var uploader = new plupload.Uploader({ runtimes : 'silverlight', browse_button : 'pickfiles', container : 'container', max_file_size : '20mb', url:"/"+CONTEXT_NAME+"/importFromExcelAction.uploadExcelFile.do", multipart: true, chunk_size : '10mb',//把大文件分割 unique_names : true, urlstream_upload : true, multiple_queues : false, filters : [{title : "Excel文件", extensions : "xls,xlsx"}], silverlight_xap_url : '/'+CONTEXT_NAME+'/modules/common/attach/plupload/script/plupload.silverlight.xap' }); uploader.bind("Init",function(up,params){ $J('#filelist').html("<div>Current runtime: " + params.runtime + "</div>"); }); uploader.bind("FilesAdded",function(up,files){ $J.each(files, function(i, file) { $J('#filelist').append( '<div id="' + file.id + '">' + file.name + ' (' + plupload.formatSize(file.size) + ') <b></b>' + '</div>'); }); up.refresh(); }); $J("#uploadfiles").click(function(e){ uploader.start(); e.preventDefault(); }) uploader.bind('UploadProgress', function(up, file) { $J('#' + file.id + " b").html(file.percent + "%"); }); uploader.bind('Error', function(up, err) { $J('#filelist').append("<div>Error: " + err.code + ", Message: " + err.message + (err.file ? ", File: " + err.file.name : "") + "</div>" ); up.refresh(); // Reposition Flash/Silverlight }); uploader.bind('FileUploaded', function(up, file) { $J('#' + file.id + " b").html("100%"); $J('#filelist').append("<span>上传成功...</span><br/>"); $J('#filelist').append("<span>开始处理Excel数据...</span><br/>"); var request = $J.ajax({ url:'/'+CONTEXT_NAME+'/importFromExcelAction.importExcel.do', type:"post", data:{ template:$J("#selectTemplate").val(), fileName:file.name } }); // 定时获取导入状态 var task = window.setInterval("getImportStatus()",5000); request.done(function(data){ $J('#filelist').append("<span>success:"+data.success+",msg:"+data.msg+"</span><br/>"); window.clearInterval(task); }); request.fail(function(jqXHR, textStatus){ $J('#filelist').append("<span>请求处理Excel数据失败:"+textStatus+"</span><br />"); window.clearInterval(task); }); }); uploader.init();
而后台,可以使用FileInputStream的构造方法追加文件内容。new FileOutputStream(fullName,isAppend)
plupload使用“multipart/form-data”这种表单上传文件,其中每一个分块会发出一次请求,表单中有两个字段,分别是“chunk”和“chunks”,其中“chunk”是当前正在处理的文件分块的序号(从0开始计数),而“chunks”则是文件的分块总数。具体的实现:
/** * <p>使用plupload组件上传文件</p> * @param request * @param response * @param rePath 保存文件的相对路径,以WebRoot为根 * @return */ public static String uploadFiles(HttpServletRequest request,HttpServletResponse response, String rePath){ String filename = null; int chunk = 0;// 当前正在处理的文件分块序号 int chunks = 0;//分块上传总数 boolean isMultipart = ServletFileUpload.isMultipartContent(request); // 判断当前表单是否为"multipart/form-data" if (isMultipart) { ServletFileUpload upload = new ServletFileUpload(); //webroot绝对路径 String webRootPath = FileHelper.getServerWebRoot(); try { FileItemIterator iter = upload.getItemIterator(request); while (iter.hasNext()) { FileItemStream item = iter.next(); String name = item.getFieldName(); InputStream input = item.openStream(); if("chunk".equals(name)) { chunk = Integer.valueOf(Streams.asString(input)); continue; } if("chunks".equals(name)) { chunks = Integer.valueOf(Streams.asString(input)); continue; } // Handle a multi-part MIME encoded file. if (!item.isFormField()) { // 文件名 filename = item.getName(); // 保存文件目录绝对路径 File dir = new File(webRootPath+rePath); if(!dir.isDirectory() || !dir.exists()){ dir.mkdir(); } //保存文件绝对路径 String fullPath = webRootPath+rePath+"/"+filename; if(chunk == 0){ File file = new File(fullPath); if(file.exists()){ file.delete(); } //上传文件 FileHelper.uploadFile(input, fullPath); } if(chunk > 0){ //追加文件 FileHelper.uploadFile(input, fullPath, true); } if(chunk+1 == chunks || chunks == 0){ break; } } } } catch (Exception e) { log.error(e, e.fillInStackTrace()); e.printStackTrace(); } } return filename; }