【Java】Java实现批量打包文件Zip下载

版权声明:【本文为博主原创文章或收集整理,未经博主允许不得转载】 https://blog.csdn.net/zsq520520/article/details/72537635

有这样一个需求,需要将某个文件夹进行下载,而且该文件下包含多张图片,图片是存储于Linux服务器上的。故采用zip打包方式进行下载。在此并没有采用获取网络图片的方式进行下载,而是找到图片在服务器上存储路径进行打包下载。废话不多说,直接上代码吧!!

1、页面功能如下图:


2、JS代码如下:

/**
 * 点击下载当前文件夹
 * 
 */

function downloadFileImage(i){

	var fileTid = $(i).attr("fileTid");
	var fileName = $(i).attr("fileName");	
	$.ajax({
		url:'../../file/tofindImagesFiles.do',
        type : "post",
        dataType:'json',
        async : false,
        data:{tid:fileTid},
        success:function(data){
        	if(data.result=='no'){
                alert('该文件夹下没有图片信息');
            }else{
            	window.location.href='../../file/downLoadZipFile.do?tid='+fileTid+'&fileName='+fileName;
            }
        }
	});
	
}
3、Controller方法代码如下:

/**
	 * 单个文件打包(包含文件下的图片)下载
	 * @param request
	 * @param response
	 * @param model
	 * @param tid
	 * @return
	 * @author zhangsq
	 */
	@RequestMapping(value = "/downLoadZipFile.do")
	public @ResponseBody Map<String, Object> toHmFileSaveAs(HttpServletRequest request, HttpServletResponse response, 
			ModelMap model,String tid) throws IOException {
		Map<String, Object> map = new HashMap<String, Object>();
		// 获取项目webapp目录路径下的文件
        //String path = request.getSession().getServletContext().getRealPath("/");
		String path = properties.getProperty("file.acpath.server");
		//根据Tid获取文件信息
		HmFile files = hmFileService.findByTidFilesInfo(tid);
		
		String zipName = files.getFileName().concat(".zip");
		ZipOutputStream outputStream = new ZipOutputStream(response.getOutputStream());
		
		//根据tid=hid获取图片信息
		List<HmImage> imgList = hmImagesService.findByHidImageShow(files.getTid());
		if(imgList != null && imgList.size()>0){
			try {
				for(Iterator<HmImage> iterator = imgList.iterator();iterator.hasNext();){
					response.setContentType("APPLICATION/OCTET-STREAM");
					response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(zipName, "UTF-8"));
					HmImage img = iterator.next();
					String filePath = img.getFilePath().substring(0,img.getFilePath().indexOf("?"));
					String realname = filePath.substring(filePath.lastIndexOf("/")+1);
					String filedir =File.separator+ files.getFileSpell();
					String filelocationdir = path + filedir + File.separator + realname;
					ZipUtils.doCompress(filelocationdir, outputStream);
					response.flushBuffer();
				}
			} catch (Exception e) {
				e.printStackTrace();
				ServletOutputStream sos = null;
				try {
					response.setContentType("text/html;charset=utf-8");
					sos = response.getOutputStream();
					sos.write("<script>alert('下载失败,请与管理员联系~~');</script>".getBytes());
					sos.flush();
				} catch (IOException e1) {
					e1.printStackTrace();
				}finally{
					if(null != sos){
						try {
							sos.close();
						} catch (IOException e1) {
							e1.printStackTrace();
						}
					}
				}
			}finally{
	        	outputStream.close();
	        }
			
		}else{
			ZipUtils.doCompress(files.getFileName(), outputStream);
			response.flushBuffer();
			outputStream.close();
		}
		map.put("success",true);
		return map;
	}
其中:

file.acpath.server为配置文件中配置的服务器路径。


String zipName = files.getFileName().concat(".zip");为文件打包时候的包名。
doCompress为公共工具类ZipUtils中的方法。

3、公共工具类ZipUtils全部代码如下:

package com.zxct.edu.utils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;

/**
 * 压缩文件工具类
 * 
 * @author zhangsq 2017年4月10日 v1.0
 */
public class ZipUtils {

	public static void doCompress(String srcFile, String zipFile) throws Exception {
		doCompress(new File(srcFile), new File(zipFile));
	}

	/**
	 * 文件压缩
	 * 
	 * @param srcFile
	 *            目录或者单个文件
	 * @param destFile
	 *            压缩后的ZIP文件
	 */
	public static void doCompress(File srcFile, File destFile) throws Exception {
		ZipOutputStream out = new ZipOutputStream(new FileOutputStream(destFile));
		if (srcFile.isDirectory()) {
			File[] files = srcFile.listFiles();
			for (File file : files) {
				doCompress(file, out);
			}
		} else {
			doCompress(srcFile, out);
		}
	}

	public static void doCompress(String pathname, ZipOutputStream out) throws IOException {
		doCompress(new File(pathname), out);
	}

	public static void doCompress(File file, ZipOutputStream out) throws IOException {
		if (!file.exists()) {
			return;
		}
		byte[] buffer = new byte[1024];
		FileInputStream fis = new FileInputStream(file);
		out.putNextEntry(new ZipEntry(file.getName()));
		int len = 0;
		// 读取文件的内容,打包到zip文件
		while ((len = fis.read(buffer)) > 0) {
			out.write(buffer, 0, len);
		}
		out.flush();
		out.closeEntry();
		fis.close();
	}

	/**
	 * 压缩文件列表中的文件
	 * 
	 * @param files
	 * @param outputStream
	 * @throws IOException
	 */
	public static void zipFile(List files, ZipOutputStream outputStream) throws IOException, ServletException {
		try {
			int size = files.size();
			// 压缩列表中的文件
			for (int i = 0; i < size; i++) {
				File file = (File) files.get(i);
				zipFile(file, outputStream);
			}
		} catch (IOException e) {
			throw e;
		}
	}

	/**
	 * 将文件写入到zip文件中
	 * 
	 * @param inputFile
	 * @param outputstream
	 * @throws Exception
	 */
	public static void zipFile(File inputFile, ZipOutputStream outputstream) throws IOException, ServletException {
		try {
			if (inputFile.exists()) {
				if (inputFile.isFile()) {
					FileInputStream inStream = new FileInputStream(inputFile);
					BufferedInputStream bInStream = new BufferedInputStream(inStream);
					ZipEntry entry = new ZipEntry(inputFile.getName());
					outputstream.putNextEntry(entry);

					final int MAX_BYTE = 10 * 1024 * 1024; // 最大的流为10M
					long streamTotal = 0; // 接受流的容量
					int streamNum = 0; // 流需要分开的数量
					int leaveByte = 0; // 文件剩下的字符数
					byte[] inOutbyte; // byte数组接受文件的数据

					streamTotal = bInStream.available(); // 通过available方法取得流的最大字符数
					streamNum = (int) Math.floor(streamTotal / MAX_BYTE); // 取得流文件需要分开的数量
					leaveByte = (int) streamTotal % MAX_BYTE; // 分开文件之后,剩余的数量

					if (streamNum > 0) {
						for (int j = 0; j < streamNum; ++j) {
							inOutbyte = new byte[MAX_BYTE];
							// 读入流,保存在byte数组
							bInStream.read(inOutbyte, 0, MAX_BYTE);
							outputstream.write(inOutbyte, 0, MAX_BYTE); // 写出流
						}
					}
					// 写出剩下的流数据
					inOutbyte = new byte[leaveByte];
					bInStream.read(inOutbyte, 0, leaveByte);
					outputstream.write(inOutbyte);
					outputstream.closeEntry();
					bInStream.close(); // 关闭
					inStream.close();
				}
			} else {
				throw new ServletException("文件不存在!");
			}
		} catch (IOException e) {
			throw e;
		}
	}

}
这样就可以了,在浏览器端点击下载,如下图:


找到下载的文件夹,并解压:


打开解压后文件,就看到下载成功了。



猜你喜欢

转载自blog.csdn.net/zsq520520/article/details/72537635
今日推荐