1. 程式人生 > >Java通過Spring MVC匯出批量Excel檔案壓縮包,並彈出下載框

Java通過Spring MVC匯出批量Excel檔案壓縮包,並彈出下載框

直接貼程式碼:

頁面jsp的部分程式碼,為表單提交的程式碼:

	<form id="exportForm"
		action="${pageContext.request.contextPath}/downLoad/exportFile.action"
		onsubmit="return download();" method="post">
		<div class="form-group" id="passwordDiv">
			<label>資料檔案支援:excel.</label><br> <br> 操作型別:<input
				name="export_type" id="export_type" placeholder=""
				class="abc input-default" value=""> <br> 檔案命名規則:<input
				name="export_name" id="export_name" placeholder=""
				class="abc input-default" value=""> 生效時間:<input
				name="export_time" id="export_time" placeholder="請輸入日期"
				class="laydate-icon"
				onClick="laydate({istime: true, format: 'YYYY/MM/DD'})">
		</div>
		<div class="progress progress-striped active" style="display: none">
			<div id="progressBar_export" name="progressBar_export"
					class="progress-bar progress-bar-info" role="progressbar"
					aria-valuemin="0" aria-valuenow="0" aria-valuemax="100"
					style="width: 0%"></div>
		</div>
			<div class="form-group">
					<input id="exportBtn" type="submit" name="exportBtn"
							class="btn btn-success" value="匯出檔案" />
			</div>
	</form>
js的表單提交校驗的程式碼:
function download(){
				
				var name=$("#export_name").val();
				if(name==''){
					alert("檔案的命名規則不能為空!");
					return false;
				}
				var type=$("#export_type").val();
				if(type==''){
					alert("操作型別不能為空!")
					return false;
				}
				var time=$("#export_time").val();
				if(time==''){
					alert("生效時間不能為空");
					return false;
				}
				return true;
			}
接下來編寫Controller的控制器:

@Controller
@RequestMapping("downLoad")
public class DownloadAction {
	@Autowired
	private DataSource dataSource;

	@RequestMapping(value = "exportFile")
	public String download(
			String export_type,String export_name,String export_time,
			HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("type", export_type);
		map.put("name", export_name);
		map.put("time", export_time);
		HttpSession session = request.getSession();
		int port = (int) session.getAttribute("port");
		
		Timestamp upTime = (Timestamp) session.getAttribute("upTime");
		
		String serverPath = "c:/資料/" + port + "/";// 壓縮包的檔案
		File file = new File(serverPath);
		if (!file.exists())
			file.mkdirs();
		List<File> srcfile = getExcelData(map, port, upTime);
		
		file=new File("c:/資料/" + port + "/"+port+".zip");
		FileOutputStream outStream=new FileOutputStream(file);
		ZipOutputStream toClient=new ZipOutputStream(outStream);
		zipFile(srcfile, toClient);
		toClient.close();
		outStream.close();
		downloadFile(file, response, true);
		for(int i=0;i<srcfile.size();i++) {
			File f=srcfile.get(i);
			f.delete();
		}
		return null;
	}

	private String sql = "select top 10000  m.mobile from ( "
			+ "	select ROW_NUMBER() OVER(order by pm.upLoadTime asc) oi,"
			+ " pm.mId,pm.pId,pm.upLoadTime from PM ) pm,Port p,Mobile m "
			+ " where pm.mId=m.mId and p.pId=pm.pId and oi>@begin ";

	/**
	 * 
	 * @param param
	 * @param port
	 * @param upTime
	 * @return
	 */
	private List<File> getExcelData(Map<String, Object> param, int port, Timestamp upTime) {
		String fileName = (String) param.get("name");
		String type = (String) param.get("type");
		String forceTime = (String) param.get("time");
		List<File> listFile = new ArrayList<>();
		Connection conn = null;
		PreparedStatement pStatement = null;
		ResultSet resultSet = null;

		Workbook wb = null;
		Sheet sheet = null;
		String excelPath = "c:/資料/" + port + "/";
		String[] title = { "手機號碼", "操作型別", "生效時間", "失效時間" };
		try {
			conn = dataSource.getConnection();
			int total = countInfo(port, upTime);// 匯出資料的數量
			int yu = total % 10000;
			int num = total / 10000;
			String s = requireSql(port, upTime, sql).toString();
			if (yu > 0)
				num += 1;
			for (int i = 1; i <= num; i++) {
				int begin = 0;
				File f = new File(excelPath + fileName + "_" + i + ".xlsx");
				wb = new XSSFWorkbook();
				sheet = wb.createSheet("Sheet1");
				Row row = sheet.createRow(0);
				row.setHeight((short) 500);
				Cell cell = row.createCell(0);
				CellStyle style=wb.createCellStyle();
				DataFormat fmat=wb.createDataFormat();
				style.setDataFormat(fmat.getFormat("yyyy/m/d"));
				cell.setCellStyle(style);
				for (int j = 0; j < title.length; j++) {
					cell = row.createCell(j);
					cell.setCellValue(title[j]);
					if(j==0)
						cell.setCellType(HSSFCell.CELL_TYPE_STRING);
					if(j==2||j==3) {
						cell.setCellStyle(style);
					}
					sheet.setColumnWidth(j, 20 * 256);
				}

				pStatement = conn.prepareStatement(s.replace("@begin", begin + ""));
				resultSet = pStatement.executeQuery();
				int index = 0;
				while (resultSet.next()) {
					String mobile = resultSet.getString("mobile");
					row = (Row) sheet.createRow(index + 1);
					row.setHeight((short) 500);
					Cell c0=row.createCell(0);
					c0.setCellType(HSSFCell.CELL_TYPE_STRING);
					c0.setCellValue(mobile);
					row.createCell(1).setCellValue(type);
					Cell c2=row.createCell(2);
					c2.setCellStyle(style);
					c2.setCellValue(forceTime);
					Cell c3=row.createCell(3);
					c3.setCellStyle(style);
					c3.setCellValue("2110/2/2");
					index++;
				}

				OutputStream outputStream = new FileOutputStream(excelPath + fileName + "_" + i + ".xlsx");
				wb.write(outputStream);
				outputStream.flush();
				outputStream.close();
				listFile.add(f);
				begin += 10000;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			JdbcUtil.closeResultSet(resultSet);
			JdbcUtil.closeStatement(pStatement);
			JdbcUtil.closeConnection(conn);
		}
		return listFile;
	}

	/**
	 * 符合查詢條件下,一共有多少條記錄
	 * 
	 * @param param
	 * @return
	 */
	private int countInfo(int port, Timestamp upTime) {
		StringBuilder sql = requireSql(port, upTime, countSql);
		Connection conn = null;
		PreparedStatement countSt = null;
		ResultSet resultSet = null;
		int count = 0;
		try {
			conn = dataSource.getConnection();
			System.out.println(">>>>>>>>>>>>> " + sql.toString());
			countSt = conn.prepareStatement(sql.toString());
			resultSet = countSt.executeQuery();
			if (resultSet.next())
				count = resultSet.getInt(1);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			JdbcUtil.closeResultSet(resultSet);
			JdbcUtil.closeStatement(countSt);
			JdbcUtil.closeConnection(conn);
		}
		return count;
	}

	private String countSql = "select count(0) from PM pm,Port p,Mobile m where pm.mId=m.mId and p.pId=pm.pId ";

	private StringBuilder requireSql(int port, Timestamp upTime, String sql) {
		StringBuilder sbuilder = new StringBuilder(sql);
		sbuilder.append(" and p.Port=" + port);
		sbuilder.append(" and pm.upLoadTime='" + upTime.toString()+"'");
		return sbuilder;
	}

	public static void zipFile(List<File> 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;
		}
	}

	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 = 50 * 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;
		}
	}

	public void downloadFile(File file,HttpServletResponse response,boolean isDelete) {
        try {
            // 以流的形式下載檔案。
            BufferedInputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + new String(file.getName().getBytes("UTF-8"),"ISO-8859-1"));
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
            if(isDelete)
            {
                file.delete();        //是否將生成的伺服器端檔案刪除
            }
         } 
         catch (IOException ex) {
            ex.printStackTrace();
        }
    }
	
}