簡單介紹下我實現的功能,首先是我的excel上傳,它是以blob字段存儲在oracel數據庫中的,我實現的是循環遍歷blob字段並使用io流進行打包下載,如有需要可自行修改
使用技術有,springMVC,mabits , bootstrap
1.前台
這里給出主要代碼塊
<div class="row"> <div class="col-md-12 "> <a href="tab-trainer-info.htm?status=1" class="btn btn-danger" title='#springMessage("back")'> <i class="glyphicon glyphicon-step-backward"></i></a> <a href="downloadPreHomeWorkZIP.htm?sessionId=$!sessionId" class="btn btn-info downloadPreZip" title='#springMessage("preWorkZip")'> <i class="glyphicon glyphicon-download-alt"></i> #springMessage("preWorkZip")</a> <a href="downloadAfterHomeWorkZIP.htm?sessionId=$!sessionId" class="btn btn-info downloadAfterZip" title='#springMessage("afterWorkZip")'> <i class="glyphicon glyphicon-download-alt"></i> #springMessage("afterWorkZip")</a> </div> </div>
注意這里點擊按鈕時用的超鏈接,不要用的ajax提交,ajax慎用,我自己一開始使用的ajax,最后無法下載,搞了半天,后來百度,說ajax下載無法調用瀏覽器的下載機制,如果有必要也可以使用(要用form封裝,我這里不再具體介紹,有嘗試的小伙伴,可以共享一下,哈哈)
2. Controller 讀取數據
@RequestMapping(value = "downloadPreHomeWorkZIP") public void downloadLetterZIP(trainTraineeWorkModel query, HttpServletResponse response, HttpServletRequest request) throws IOException, SQLException { String serverPath = request.getSession().getServletContext().getRealPath("/") + "\\upload\\tempExcel"; //設置下載excel的臨時文件夾 List<File> srcfile = new ArrayList<File>(); //聲明一個集合,用來存放多個Excel文件路徑及名稱 // 得到路徑下的文件,如果不存在創建文件夾 File file = new File(serverPath); if (!file.exists()) { file.mkdir(); } List<Map> employees = employeeService // 查詢學員上傳的課前課后作業 (這里根據自己的需要獲取數據,寫入流中) .getMapTraineesBySessionId(query.getSessionId()); if (employees.size() != 0) { for (Map map : employees) { BLOB blob = (BLOB) map.get("BEFORECLASS_WORK"); if (blob != null && blob.length() != 0) { String employeeCode = (String) map.get("EMPLOYEE_CODE"); String filename = employeeCode + "_" + DateUtil.getExportDate(); //定義現在excel文件名稱,注意這里不是壓縮包的名稱 ZipUtils.execute(serverPath +"\\"+ filename+ ".xls", blob); //ZipUtils是我自己定義的一個工具類,因為用到的下載太多了,往下看 String encodedfileName = new String(filename.getBytes(), "UTF-8"); srcfile.add(new File(serverPath + "\\" + encodedfileName + ".xls")); //存放到List集合中 } } // 將服務器上存放Excel的文件夾打成zip包 File zipfile = new File(serverPath+"\\" + "PreWork" + ".zip"); ZipUtils.zipFiles(srcfile, zipfile);// 實現將多個excel打包成zip文件 //下載 ZipUtils.downFile(response, serverPath, "PreWork" + ".zip"); //實現將壓縮包寫入流中,下載到本地,並刪除臨時文件中的壓縮包及文件 } }
3.使用工具類
這里是我第二步說的自己定義的工具類,我用的maven,需要導入一些Io流包
package common.util; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import javax.servlet.http.HttpServletResponse; import oracle.sql.BLOB; public class ZipUtils { /** * 將多個Excel打包成zip文件 * @param srcfile * @param zipfile */ public static void zipFiles(List<File> srcfile, File zipfile) { byte[] buf = new byte[1024]; try { // Create the ZIP file ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipfile)); // Compress the files for (int i = 0; i < srcfile.size(); i++) { File file = srcfile.get(i); FileInputStream in = new FileInputStream(file); // Add ZIP entry to output stream. out.putNextEntry(new ZipEntry(file.getName())); // Transfer bytes from the file to the ZIP file int len; while ((len = in.read(buf)) > 0) { out.write(buf, 0, len); } // Complete the entry out.closeEntry(); in.close(); } // Complete the ZIP file out.close(); } catch (IOException e) { e.printStackTrace(); } } //filename為單個excel的路徑和excel的名稱,blob就是獲取的blob數據 public static int execute(String filename, BLOB blob) { int success = 1; try { File blobFile = new File(filename); FileOutputStream outStream = new FileOutputStream(blobFile); InputStream inStream = blob.getBinaryStream(); int length = -1; int size = blob.getBufferSize(); byte[] buffer = new byte[size]; while ((length = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, length); outStream.flush(); } inStream.close(); outStream.close(); } catch (Exception e) { e.printStackTrace(); success = 0; } finally { return success; } } /** * 刪除目錄下所有的文件; * @param path */ public static boolean deleteExcelPath(File file){ String[] files = null; if(file != null){ files = file.list(); } if(file.isDirectory()){ for(int i =0;i<files.length;i++){ boolean bol = deleteExcelPath(new File(file,files[i])); if(bol){ System.out.println("刪除成功!"); }else{ System.out.println("刪除失敗!"); } } } return file.delete(); } public static void downFile(HttpServletResponse response,String serverPath, String str) { //下面注釋代碼雖然少,但是慎用,如果使用,壓縮包能下載,但是下載之后臨時文件夾會被鎖住被jvm占用,不能刪除 // response.setCharacterEncoding("utf-8"); // try { // File file=new File(serverPath,str); // response.setHeader("Content-Disposition", // "attachment; filename="+ StringUtil.encodingFileName(str)); // response.setContentType("application/octet-stream; charset=utf-8"); // InputStream in1 =new FileInputStream(file.getPath()); // IOUtils.copy(in1, response.getOutputStream()); // // } // catch (IOException ex) { // ex.printStackTrace(); // } try { String path = serverPath +"\\"+ str; File file = new File(path); if (file.exists()) { InputStream ins = new FileInputStream(path); BufferedInputStream bins = new BufferedInputStream(ins);// 放到緩沖流里面 OutputStream outs = response.getOutputStream();// 獲取文件輸出IO流 BufferedOutputStream bouts = new BufferedOutputStream(outs); response.setContentType("application/ostet-stream");// 設置response內容的類型 response.setHeader( "Content-disposition", "attachment;filename=" + URLEncoder.encode(str, "UTF-8"));// 設置頭部信息 int bytesRead = 0; byte[] buffer = new byte[8192]; //開始向網絡傳輸文件流 while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) { bouts.write(buffer, 0, bytesRead); } bouts.flush();// 這里一定要調用flush()方法 ins.close(); bins.close(); outs.close(); bouts.close(); } else { response.sendRedirect("../error.jsp"); } } catch (IOException e) { e.printStackTrace(); }finally{ File file1=new File(serverPath); deleteExcelPath(file1); //刪除臨時目錄 } } }