Java+Jquery實現批量下載圖片實戰
阿新 • • 發佈:2018-12-25
Web端的批量下載圖片實戰
因為客戶提需求必須要圖片的批量下載功能,只能硬著頭皮做,公司還沒有前端,好吧…前後端一條龍操作。畢竟第一次做批量下載圖片,懵逼在所難免,整整花了3天,走了不少彎路,一定要記錄下來。
首先,如何實現批量下載功能。我的第一反應就是,獲取一堆Id然後依次下載。
就像這樣一個一個點,立馬推翻思路。(這就不叫批量操作了)
我試了在後臺接收所有要下載的id,然後用for迴圈。可是前端一下子就收不到這麼多圖片的二進位制流,好吧,又放棄了。
還有使用別人1.寫好的外掛去用,我在網上搜到一大堆,一是不會用,二是我不想用別人寫的東西。
最後終於鎖定了用將圖片在2.後臺打成壓縮包
說說批量下載的原理,這個在網上不好搜。
Java程式碼
1.從前端獲取需要的資料;(可以是唯一標識ID,或者是一個查詢條件,反正能讓你在後臺找到像要的資料就行)
2.生成一組Map,key是檔名,value是檔案的二進位制資料byte[ ];(byte[ ]是通過檔案物件轉成陣列的)
//自己寫一個FileUitl工具類
public static byte[] readToByte(File file) throws IOException {
long length = file.length();
if (length > Integer.MAX_VALUE)
throw new IOException("file too large");
byte[] b = null;
InputStream in = null;
try {
b = new byte[(int) length];
in = new FileInputStream(file);
int offset = 0, nRead = 0;
while (offset < b.length
&& (nRead = in.read(b, offset, b.length - offset)) != -1)
offset += nRead;
} catch (Exception e) {
} finally {
try {
if (in != null)
in.close();
} catch (IOException e) {
}
}
return b;
}
//根據code值獲取下載的圖片
String paras=request.getParameter("codes");
String[] codes=paras.split(",");
//檔名-位元組陣列的形式
Map<String, byte[]> files = new HashMap<String, byte[]>();
//迴圈生成key-value
for(int i=0;i<codes.length;i++){
//查詢資料庫,獲得實體
Picture picture =pictureService.queryEntityForUnique(Convert.toMap("code", codes[i]));
String imgType=picture.getPorig().split("\\.")[1];
//獲取檔名,key
String packageName=picture.getTi()+"."+imgType;
File file = new File(Profile.path() + File.separator+ picture.getPorig().replace(File.separator, "/"));
//File轉byte[ ]
byte[ ] f=FileUitl.readFile(file);
//二進位制資料,value
f = FileUtil.readToByte(file);
}
3.通過IO流將壓縮包輸出到瀏覽器
//設定下載的壓縮包名
String zipName = new Date().getTime() + ".zip";
//根據檔案,進行壓縮,批量下載
if(files.size() > 0){
downloadBatchByFile(response, files, zipName);
}
4.生成壓縮檔案的方法
/**
* 根據檔案,進行壓縮,批量下載
* @param response
* @param files
* @throws Exception
*/
private void downloadBatchByFile(HttpServletResponse response, Map<String, byte[]> files, String zipName){
try{
//設定響應訊息頭
response.setContentType("application/x-msdownload");
response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(zipName, "utf-8"));
//輸出、輸入流
ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
BufferedOutputStream bos = new BufferedOutputStream(zos);
for(Entry<String, byte[]> entry : files.entrySet()){
String fileName = entry.getKey(); //每個zip檔名
byte[] file = entry.getValue(); //這個zip檔案的位元組
BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(file));
zos.putNextEntry(new ZipEntry(fileName));
int len = 0;
byte[] buf = new byte[10 * 1024];
while( (len=bis.read(buf, 0, buf.length)) != -1){
bos.write(buf, 0, len);
}
bis.close();
bos.flush();
}
bos.close();
}catch(Exception e){
e.printStackTrace();
}
}
前端 JQuery
1.通過複選框獲取標識;
2.傳送請求.
// 全選或反選
var $all = $('input[name="pic-all"]').click(function() {
$item.prop('checked', $(this).is(':checked')).trigger('change');
});
var $item = $('input[name="pic-item"]').click(function() {
if ($item.length == $('input[name="pic-item"]:checked').length)
!$all.is(':checked') && $all.prop('checked', true).trigger('change');
else
$all.is(':checked') && $all.prop('checked', false).trigger('change');
});
$('.btn-imgDownload').click(function() {
// 選擇圖片
var $picChecked = $('input[name="pic-item"]:checked');
if ($picChecked.length == 0) {
dialog.tips('未選中圖片');
return false;
}
// 選擇圖片程式碼
var flag = $(this).attr('name'), codes = '';
$picChecked.each(function() {
codes += $(this).val() + ',';
});
/* 批量下載 */
$.ajax({
async:false,
url: 'picture/downloadMany/check.html',
data: 'codes='+codes,
dataType: 'json',
cache: false,
/* beforeSend: function() {
dialog.tips('正在提交...', 60, 'loading.gif');
}, */
success: function(series) {
if (series.status) {
var title = '確認總共消耗 ' + series.msg + ' 點積分下載原圖?';
dialog.confirm(title, function() {
// 消耗積分下載
location.href = 'picture/downloadMany.html?codes='+ codes +'&score='+ series.msg ;
});
} else {
dialog.tips(series.msg);
}
}
});
});
效果
通過選擇目標,經過後臺,前臺,最後生成壓縮包。