
重 点:文件读取、文件打包
难 点:文件下载
内 容:登录成功后,下载文件。

图1 点击下载页面
在index.js文件中添加downloadFileSelect()和downloadFile()两种方式下载文件,当触发事件时,调用download()方法,向后台请求下载数据,代码如下所示;
1)当选中文件后,点击下载按钮所触发的事件,代码如下所示;
function downloadFileSelect(obj){
var $download = $("input:checked");
var downPath = "";
$.each($download.parent().next().children(),function(i,n){
downPath += "&downPath=" + $(this).text();
});
if($download.length <= 0){
alert("必须选择一个");
$download.removeAttr("checked");
}else{
return download(obj, downPath);
}
}2)点击对应文件后的下载图标所触发对事件,代码如下所示;
function downloadFile(obj){
$file = $(obj).parent().prev().prev().children();
var path = $file.attr("path");
if(path==null){
path = $file.text();
}
return download(obj, "&downPath="+ encodeURI(path));
}3)在触发事件中,调用download()方法向后台提交下载申请,代码如下所示;
function download(obj, path){
var url = "file/download.action?";
url += ("currentPath=" + encodeURI(currentPath));
url += path;
$(obj).attr("href", url);
return true;
}1. 在FileController类中添加download()方法,用于处理下载数据的请求并返回下载的结果给前台,代码如下所示;
/**
* 文件下载
*
* @param currentPath
* 当前路径
* @param downPath
* 文件名
* @param username
* 用户名
* @return 文件下载流
*/
@RequestMapping("/download")
public ResponseEntity<byte[]> download(String currentPath,String[] downPath, String username) {
try {
String down = request.getParameter("downPath");
File downloadFile = fileService.downPackage(request, currentPath,downPath, username);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
String fileName = new String(downloadFile.getName().getBytes("utf-8"), "iso-8859-1");
headers.setContentDispositionFormData("attachment", fileName);
byte[] fileToByteArray = org.apache.commons.io.FileUtils.readFileToByteArray(downloadFile);
fileService.deleteDownPackage(downloadFile);
return new ResponseEntity<byte[]>(fileToByteArray, headers, HttpStatus.CREATED);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}2. 在FileService类中添加downPackage()方法,来判断用户是单一文件下载还是多个文件下载,代码如下所示;
public File downPackage(HttpServletRequest request, String currentPath, String[] fileNames, String username) throws Exception {
File downloadFile = null;
if (currentPath == null) {
currentPath = "";
}
/单文件length为1
if (fileNames.length == 1) {
downloadFile = new File(getFileName(request, currentPath, username), fileNames[0]);
if (downloadFile.isFile()) {
return downloadFile;
}
}
String[] sourcePath = new String[fileNames.length];
for (int i = 0; i < fileNames.length; i++) {
sourcePath[i] = getFileName(request, currentPath, username) + File.separator + fileNames[i];
}
String packageZipName = packageZip(sourcePath);
downloadFile = new File(packageZipName);
return downloadFile;
}2. 处理多个文件下载
当需要一次下载多个文件时,将对多个文件进行打包,然后再下载,下载完成后再将临时zip包删除。
在FileService下添加packageZip()和writeZos()方法,功能分别如下:
1)当下载多文件时,在该用户的服务器目录下,将需下载的文件临时打包,并命名为“xxx等n个文件.zip”,代码如下所示;
/**
* 压缩文件
*
* @param sourcePath
* @return
* @throws Exception
*/
private String packageZip(String[] sourcePath) throws Exception {
String zipName = sourcePath[0] + (sourcePath.length == 1 ? "" : "等" + sourcePath.length + "个文件") + ".zip";
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(new FileOutputStream(zipName));
for (String string : sourcePath) {
writeZos(new File(string), "", zos);
}
} finally {
if (zos != null) {
zos.close();
}
}
return zipName;
}2)FileService中定义writeZos()方法,用于压缩文件,代码如下所示;
/**
* 写入文件到压缩包
*
* @param file
* @param basePath
* @param zos
* @throws IOException
*/
private void writeZos(File file, String basePath, ZipOutputStream zos) throws IOException {
if (!file.exists()) {
throw new FileNotFoundException();
}
if (file.isDirectory()) {
File[] listFiles = file.listFiles();
if (listFiles.length != 0) {
for (File childFile : listFiles) {
writeZos(childFile, basePath + file.getName() + File.separator, zos);
}
}
} else {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
ZipEntry entry = new ZipEntry(basePath + file.getName());
zos.putNextEntry(entry);
int count = 0;
byte data[] = new byte[1024];
while ((count = bis.read(data)) != -1) {
zos.write(data, 0, count);
}
bis.close();
}
}3)当成功下载“xxx等n个文件.zip”时,在该用户服务器目录下删除此临时zip包,代码如下所示;
/**
* 删除压缩文件包
*
* @param downloadFile
*/
public void deleteDownPackage(File downloadFile) {
if (downloadFile.getName().endsWith("个文件.zip")) {
downloadFile.delete();
}
}