WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件。在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流IE浏览器,沿用原来的FLASH运行时,兼容IE6+,iOS 6+, android 4+。两套运行时,同样的调用方式,可供用户任意选用。
jsp代码
1 <div class="upload_buttoncontainer">
2 <button class="upload_accredit"
3 onclick="showuploadimagesPage('upload','fade')">//onclik是打开一个窗口
4 <label>批量上传</label>
5 </button>
6 </div>
js代码
1 (function( $ ){
2 // 当domReady的时候开始初始化
3 $(function() {
4 var $wrap = $('#uploader'),
5
6 // 图片容器
7 $queue = $( '<ul id="filelist" class="filelist"></ul>' )
8 .appendTo( $wrap.find( '.queueList' ) ),
9
10 // 状态栏,包括进度和控制按钮
11 $statusBar = $wrap.find( '.statusBar' ),
12
13 // 文件总体选择信息。
14 $info = $statusBar.find( '.info' ),
15
16 // 上传按钮
17 $upload = $wrap.find( '.uploadBtn' ),
18
19 // 没选择文件之前的内容。
20 $placeHolder = $wrap.find( '.placeholder' ),
21
22 $progress = $statusBar.find( '.progress' ).hide(),
23
24 // 添加的文件数量
25 fileCount = 0,
26
27 // 添加的文件总大小
28 fileSize = 0,
29
30 // 优化retina, 在retina下这个值是2
31 ratio = window.devicePixelRatio || 1,
32
33 // 缩略图大小
34 thumbnailWidth = 110 * ratio,
35 thumbnailHeight = 110 * ratio,
36
37 // 可能有pedding, ready, uploading, confirm, done.
38 state = 'pedding',
39
40 // 所有文件的进度信息,key为file id
41 percentages = {},
42 // 判断浏览器是否支持图片的base64
43 isSupportBase64 = ( function() {
44 var data = new Image();
45 var support = true;
46 data.onload = data.onerror = function() {
47 if( this.width != 1 || this.height != 1 ) {
48 support = false;
49 }
50 }
51 data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
52 return support;
53 } )(),
54
55 // 检测是否已经安装flash,检测flash的版本
56 flashVersion = ( function() {
57 var version;
58
59 try {
60 version = navigator.plugins[ 'Shockwave Flash' ];
61 version = version.description;
62 } catch ( ex ) {
63 try {
64 version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash')
65 .GetVariable('$version');
66 } catch ( ex2 ) {
67 version = '0.0';
68 }
69 }
70 version = version.match( /\d+/g );
71 return parseFloat( version[ 0 ] + '.' + version[ 1 ], 10 );
72 } )(),
73
74 supportTransition = (function(){
75 var s = document.createElement('p').style,
76 r = 'transition' in s ||
77 'WebkitTransition' in s ||
78 'MozTransition' in s ||
79 'msTransition' in s ||
80 'OTransition' in s;
81 s = null;
82 return r;
83 })(),
84
85 // WebUploader实例
86 uploader;
87
88 if ( !WebUploader.Uploader.support('flash') && WebUploader.browser.ie ) {
89
90 // flash 安装了但是版本过低。
91 if (flashVersion) {
92 (function(container) {
93 window['expressinstallcallback'] = function( state ) {
94 switch(state) {
95 case 'Download.Cancelled':
96 alert('您取消了更新!')
97 break;
98
99 case 'Download.Failed':
100 alert('安装失败')
101 break;
102
103 default:
104 alert('安装已成功,请刷新!');
105 break;
106 }
107 delete window['expressinstallcallback'];
108 };
109
110 var swf = './expressInstall.swf';
111 // insert flash object
112 var html = '<object type="application/' +
113 'x-shockwave-flash" data="' + swf + '" ';
114
115 if (WebUploader.browser.ie) {
116 html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
117 }
118
119 html += 'width="100%" height="100%" style="outline:0">' +
120 '<param name="movie" value="' + swf + '" />' +
121 '<param name="wmode" value="transparent" />' +
122 '<param name="allowscriptaccess" value="always" />' +
123 '</object>';
124
125 container.html(html);
126
127 })($wrap);
128
129 // 压根就没有安转。
130 } else {
131 $wrap.html('<a href="http://www.adobe.com/go/getflashplayer" target="_blank" border="0"><img alt="get flash player" src="http://www.adobe.com/macromedia/style_guide/images/160x41_Get_Flash_Player.jpg" /></a>');
132 }
133
134 return;
135 } else if (!WebUploader.Uploader.support()) {
136 alert( 'Web Uploader 不支持您的浏览器!');
137 return;
138 }
139
140 // 实例化
141 uploader = WebUploader.create({
142 pick: {
143 id: '#filePicker',
144 label: '点击选择文件'
145 },
146 formData: {
147 uid: 123
148 },
149 compress: false,//不启用压缩
150 resize: false,//尺寸不改变
151 dnd: '#dndArea',
152 paste: '#uploader',
153 swf: '../js/Uploader.swf',
154 server: ‘后台’,
155 method:'POST',
156
157
158
159 // runtimeOrder: 'flash',
160
161 accept: {
162 title: 'Images',
163 extensions: 'gif,jpg,jpeg,bmp,png',
164 mimeTypes: 'image/*'
165 },
166
167 // 禁掉全局的拖拽功能。这样不会出现图片拖进页面的时候,把图片打开。
168 disableGlobalDnd: true,
169 fileNumLimit: 300,
170 fileSizeLimit: 2000 * 1024 * 1024, // 200 M
171 fileSingleSizeLimit: 500 * 1024 * 1024 // 50 M
172 });
173
174 // 拖拽时不接受 js, txt 文件。
175 uploader.on( 'dndAccept', function( items ) {
176 var denied = false,
177 len = items.length,
178 i = 0,
179 // 修改js类型
180 unAllowed = 'text/plain;application/javascript ';
181
182 for ( ; i < len; i++ ) {
183 // 如果在列表里面
184 if ( ~unAllowed.indexOf( items[ i ].type ) ) {
185 denied = true;
186 break;
187 }
188 }
189
190 return !denied;
191 });
192
193 // uploader.on('filesQueued', function() {
194 // uploader.sort(function( a, b ) {
195 // if ( < )
196 // return -1;
197 // if ( > )
198 // return 1;
199 // return 0;
200 // });
201 // });
202
203 // 添加“添加文件”的按钮,
204 uploader.addButton({
205 id: '#filePicker2',
206 label: '继续添加'
207 });
208 // 添加“添加下一个”模型的按钮,
209 /*uploader.addButton({
210 id: '#addModel',
211 label: '添加下一个'
212 });*/
213 uploader.on('ready', function() {
214 window.uploader = uploader;
215 });
216
217 // 当有文件添加进来时执行,负责view的创建
218 function addFile( file ) {
219 var $li = $( '<li id="' + file.id + '"><div class="item">' +
220 '<p class="title">' + + '</p>' +
221 '<p class="imgWrap"></p>'+
222 '<p class="progress"><span></span></p>' +
223 '</div></li>' ),
224
225 $btns = $('<div class="file-panel">' +
226 '<span class="cancel">删除</span>' +
227 '<span class="rotateRight">向右旋转</span>' +
228 '<span class="rotateLeft">向左旋转</span></div>').appendTo( $li.find('.item') ),
229 $prgress = $li.find('p.progress span'),
230 $wrap = $li.find( 'p.imgWrap' ),
231 $info = $('<p class="error"></p>'),
232
233 showError = function( code ) {
234 switch( code ) {
235 case 'exceed_size':
236 text = '文件大小超出';
237 break;
238
239 case 'interrupt':
240 text = '上传暂停';
241 break;
242
243 default:
244 text = '上传失败,请重试';
245 break;
246 }
247
248 $info.text( text ).appendTo( $li );
249 };
250
251 if ( file.getStatus() === 'invalid' ) {
252 showError( file.statusText );
253 } else {
254 // @todo lazyload
255 $wrap.text( '预览中' );
256 uploader.makeThumb( file, function( error, src ) {
257 var img;
258
259 if ( error ) {
260 $wrap.text( '不能预览' );
261 return;
262 }
263
264 if( isSupportBase64 ) {
265 img = $('<img src="'+src+'">');
266 $wrap.empty().append( img );
267 }
268 }, thumbnailWidth, thumbnailHeight );
269
270 percentages[ file.id ] = [ file.size, 0 ];
271 file.rotation = 0;
272 }
273
274 file.on('statuschange', function( cur, prev ) {
275 if ( prev === 'progress' ) {
276 $prgress.hide().width(0);
277 } else if ( prev === 'queued' ) {
278 $li.off( 'mouseenter mouseleave' );
279 $btns.remove();
280 }
281
282 // 成功
283 if ( cur === 'error' || cur === 'invalid' ) {
284 console.log( file.statusText );
285 showError( file.statusText );
286 percentages[ file.id ][ 1 ] = 1;
287 } else if ( cur === 'interrupt' ) {
288 showError( 'interrupt' );
289 } else if ( cur === 'queued' ) {
290 percentages[ file.id ][ 1 ] = 0;
291 } else if ( cur === 'progress' ) {
292 $info.remove();
293 $prgress.css('display', 'block');
294 } else if ( cur === 'complete' ) {
295 $li.append( '<span class="success"></span>' );
296 }
297
298 $li.removeClass( 'state-' + prev ).addClass( 'state-' + cur );
299 });
300
301 $li.on( 'mouseenter', function() {
302 $btns.stop().animate({height: 30});
303 });
304
305 $li.on( 'mouseleave', function() {
306 $btns.stop().animate({height: 0});
307 });
308
309 $btns.on( 'click', 'span', function() {
310 var index = $(this).index(),
311 deg;
312
313 switch ( index ) {
314 case 0:
315 uploader.removeFile( file );
316 return;
317
318 case 1:
319 file.rotation += 90;
320 break;
321
322 case 2:
323 file.rotation -= 90;
324 break;
325 }
326
327 if ( supportTransition ) {
328 deg = 'rotate(' + file.rotation + 'deg)';
329 $wrap.css({
330 '-webkit-transform': deg,
331 '-mos-transform': deg,
332 '-o-transform': deg,
333 'transform': deg
334 });
335 } else {
336 $wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')');
337 // use jquery animate to rotation
338 // $({
339 // rotation: rotation
340 // }).animate({
341 // rotation: file.rotation
342 // }, {
343 // easing: 'linear',
344 // step: function( now ) {
345 // now = now * Math.PI / 180;
346
347 // var cos = Math.cos( now ),
348 // sin = Math.sin( now );
349
350 // $wrap.css( 'filter', "progid:DXImageTransform.Microsoft.Matrix(M11=" + cos + ",M12=" + (-sin) + ",M21=" + sin + ",M22=" + cos + ",SizingMethod='auto expand')");
351 // }
352 // });
353 }
354
355
356 });
357
358 $li.appendTo( $queue );
359 $('.filelist').sortable();
360 }
361
362 // 负责view的销毁
363 function removeFile( file ) {
364 var $li = $('#'+file.id);
365
366 delete percentages[ file.id ];
367 updateTotalProgress();
368 $li.off().find('.file-panel').off().end().remove();
369 }
370
371 function updateTotalProgress() {
372 var loaded = 0,
373 total = 0,
374 spans = $progress.children(),
375 percent;
376
377 $.each( percentages, function( k, v ) {
378 total += v[ 0 ];
379 loaded += v[ 0 ] * v[ 1 ];
380 } );
381
382 percent = total ? loaded / total : 0;
383
384
385 spans.eq( 0 ).text( Math.round( percent * 100 ) + '%' );
386 spans.eq( 1 ).css( 'width', Math.round( percent * 100 ) + '%' );
387 updateStatus();
388 }
389
390 function updateStatus() {
391 var text = '', stats;
392
393 if ( state === 'ready' ) {
394 text = '选中' + fileCount + '张图片,共' +
395 WebUploader.formatSize( fileSize ) + '。';
396 } else if ( state === 'confirm' ) {
397 stats = uploader.getStats();
398 if ( stats.uploadFailNum ) {
399 text = '已成功上传' + stats.successNum+ '文件,'+
400 stats.uploadFailNum + '文件上传失败,<a class="retry" href="#">重新上传</a>失败或<a class="ignore" href="#">忽略</a>'
401 }
402
403 } else {
404 stats = uploader.getStats();
405 text = '共' + fileCount + '个(' +
406 WebUploader.formatSize( fileSize ) +
407 '),已上传' + (stats.successNum+1) + '个';
408
409 if ( stats.uploadFailNum ) {
410 text += ',失败' + stats.uploadFailNum + '个';
411 }
412 }
413
414 $info.html( text );
415 }
416
417 function setState( val ) {
418 var file, stats;
419
420 if ( val === state ) {
421 return;
422 }
423
424 $upload.removeClass( 'state-' + state );
425 $upload.addClass( 'state-' + val );
426 state = val;
427
428 switch ( state ) {
429 case 'pedding':
430 $placeHolder.removeClass( 'element-invisible' );
431 $queue.hide();
432 $statusBar.addClass( 'element-invisible' );
433 uploader.refresh();
434 break;
435
436 case 'ready':
437 $placeHolder.addClass( 'element-invisible' );
438 $( '#filePicker2' ).removeClass( 'element-invisible');
439 $queue.show();
440 $statusBar.removeClass('element-invisible');
441 uploader.refresh();
442 break;
443
444 case 'uploading':
445 $( '#filePicker2' ).addClass( 'element-invisible' );
446 $progress.show();
447 $upload.text( '暂停上传' );
448 break;
449
450 case 'paused':
451 $progress.show();
452 $upload.text( '继续上传' );
453 break;
454
455 case 'confirm':
456 $progress.hide();
457 $( '#filePicker2' ).removeClass( 'element-invisible' );
458 $upload.text( '开始上传' );
459 /*$('#filePicker2 + .uploadBtn').click(function () {
460 window.location.reload();
461 });*/
462 stats = uploader.getStats();
463 if ( stats.successNum && !stats.uploadFailNum ) {
464 setState( 'finish' );
465 return;
466 }
467 break;
468 case 'finish':
469 stats = uploader.getStats();
470 if ( stats.successNum ) {
471 document.getElementById("shareUrl").style.visibility = 'visible';
472 createQrcode();
473 } else {
474 // 没有成功的图片,重设
475 state = 'done';
476 location.reload();
477 }
478 break;
479 }
480
481 updateStatus();
482 }
483
484 uploader.onUploadProgress = function( file, percentage ) {
485 var $li = $('#'+file.id),
486 $percent = $li.find('.progress span');
487
488 $percent.css( 'width', percentage * 100 + '%' );
489 percentages[ file.id ][ 1 ] = percentage;
490 updateTotalProgress();
491 };
492
493 uploader.onFileQueued = function( file ) {
494 fileCount++;
495 fileSize += file.size;
496
497 if ( fileCount === 1 ) {
498 $placeHolder.addClass( 'element-invisible' );
499 $statusBar.show();
500 }
501
502 addFile( file );
503 setState( 'ready' );
504 updateTotalProgress();
505 };
506
507 uploader.onFileDequeued = function( file ) {
508 fileCount--;
509 fileSize -= file.size;
510
511 if ( !fileCount ) {
512 setState( 'pedding' );
513 }
514
515 removeFile( file );
516 updateTotalProgress();
517
518 };
519
520 uploader.on( 'all', function( type ) {
521 var stats;
522 switch( type ) {
523 case 'uploadFinished':
524 setState( 'confirm' );
525 break;
526
527 case 'startUpload':
528 setState( 'uploading' );
529 break;
530
531 case 'stopUpload':
532 setState( 'paused' );
533 break;
534
535 }
536 });
537
538 uploader.onError = function( code ) {
539 alert( '图片重复' );
540 };
541
542 $upload.on('click', function() {
543 if ( $(this).hasClass( 'disabled' ) ) {
544 return false;
545 }
546
547 if ( state === 'ready' ) {
548 uploader.upload();
549 } else if ( state === 'paused' ) {
550 uploader.upload();
551 } else if ( state === 'uploading' ) {
552 uploader.stop();
553 }
554 });
555
556 $info.on( 'click', '.retry', function() {
557 uploader.retry();
558 } );
559
560 $info.on( 'click', '.ignore', function() {
561 alert( 'todo' );
562 } );
563
564 $upload.addClass( 'state-' + state );
565 updateTotalProgress();
566 });
567
568 })( jQuery );
后台代码
MultipartFile 需要在配置文件中进行配置上传的文件的大小,在这里我就不贴出来了
1 public void uploadInformation(HttpServletRequest request,
2 HttpServletResponse response) {
3 System.out.println("收到图片!");
4 MultipartHttpServletRequest Murequest = (MultipartHttpServletRequest) request;
5 Map<String, MultipartFile> files = Murequest.getFileMap();// 得到文件map对象
6 String upaloadUrl = new File(this.getClass().getClassLoader().getResource("/").getPath()).getParentFile().getParentFile()
7 .getAbsolutePath()
8 + "/upload/";// 得到当前工程路径拼接上文件名
9 File dir = new File(upaloadUrl);
10 if (!dir.exists())// 目录不存在则创建
11 dir.mkdirs();
12 int counter = 0;
13 for (MultipartFile file : files.values()) {
14 counter++;
15 String fileName = file.getOriginalFilename();
16 File tagetFile = new File(upaloadUrl + fileName);// 创建文件对象
17 if (!tagetFile.exists()) {// 文件名不存在 则新建文件,并将文件复制到新建文件中
18 try {
19 tagetFile.createNewFile();
20 } catch (IOException e) {
21 e.printStackTrace();
22 }
23 try {
24 file.transferTo(tagetFile);
25 } catch (IllegalStateException e) {
26 e.printStackTrace();
27 } catch (IOException e) {
28 e.printStackTrace();
29 }
30 }
31
32 }
33 System.out.println("接收完毕");
34 }
这样图片批量上传的功能就实现了,当然也可以批量上传文件,只不过需要一些变动,有兴趣的可以去http://fex.baidu.com/webuploader/ 研究一下。接下来就是选择多张图片进行压缩并保存到指定路径下,关于图片在页面的显示 在这里就略过了。接下来是关于压缩文件的action代码
1 public void yasuoIamges(HttpServletRequest request,
2 HttpServletResponse response) throws Exception {
3 String selids = request.getParameter("selTids");//选中图片的ID组成的字符串
4 String date_format = "yyyy-MM-dd_HH_mm_ss";
5 SimpleDateFormat f = new
6 SimpleDateFormat(date_format);
7 List<File> filelist = new ArrayList<>();
8 String[] uid = selids.split(",");
9 for (int i = 0; i < uid.length; i++) {
10 Images du = imagesService.getoneimage(Long
11 .valueOf(uid[i]));
12 filelist.add(new File(new File(this.getClass().getClassLoader()
13 .getResource("/").getPath()).getParentFile()
14 .getParentFile().getAbsolutePath()
15 + "/" + du.getDupath()));
16 }
17 String icpath = new File(this.getClass().getClassLoader()
18 .getResource("/").getPath()).getParentFile().getParentFile()
19 .getAbsolutePath()
20 + "/compress/";
21 File dir = new File(icpath);
22 if (!dir.exists())// 目录不存在则创建
23 dir.mkdirs();
24 String filename = (f.format(new Date())) + ".rar";// 压缩包格式可以改
25 FileOutputStream fos = new FileOutputStream(icpath + filename);
26 ZipOutputStream zos = null;
27 try {
28 zos = new ZipOutputStream(fos);
29 for (File srcFile : filelist) {
30 byte[] buf = new byte[BUFFER_SIZE];
31 zos.putNextEntry(new ZipEntry(srcFile.getName()));
32 int len;
33 FileInputStream in = new FileInputStream(srcFile);
34 while ((len = in.read(buf)) != -1) {
35 zos.write(buf, 0, len);
36 }
37 zos.closeEntry();
38 in.close();
39 }
40 } catch (Exception e) {
41 throw new RuntimeException("zip error from ZipUtils", e);
42 } finally {
43 if (zos != null) {
44 try {
45 zos.close();
46 } catch (IOException e) {
47 e.printStackTrace();
48 }
49 }
50 }
51
52 }
第一次写博客很多东西不是很会说,请谅解,也希望大家能有所收获。
















