代碼渣渣一枚,最近在實習(主要是javaweb后端),在實習期間,寫了一點網頁下載excel表格的代碼,趁着現在對他還有印象,記錄下來,方便以后用。第一次寫博客,一定會很差,各位看官不要見怪!!廢話就不多說了,下面正式開始介紹。
實現功能:網頁點擊下載,將參數傳到后端,根據參數查詢數據庫,將查到的數據導入excel表,並返回前端下載。
實現上述功能大體分為以下幾步:
一.查詢數據庫
這部分用spring框架實現,代碼十分簡單,不再贅述。由於我的功能實現中查詢到的數據很多條,因此將查詢到的數據封裝到ArrayList中,ArrayList中的元素是預先定義好的bean。
二.生成excel
這部分用的是jxl的WritableWorkbook生成excel,網上說poi也可以,查了一下,各有優缺點,poi效率高,但當寫入大量數據時,消耗內存大。用WritableWorkbook生成excel表格主要分為以下幾步:
1.從配置文件中讀取path和filename
這樣做的好處是當要更改excel文件的存放地址,直接在配置文件中更改,不用改動程序。另外,path和filename最好不好出現中文,避免亂碼,同時也顯得更加專業。據說出現中文會被批不專業甚至被boss罵。
另外,path=配置文件中讀取的固定路徑+程序中年月日生成的可變路徑,這樣做的好處是每天生成一個文件夾,用於存放今天下載的excel表格。方便管理和查找,同時也避免了大量的excel表格都存放在同一個文件夾中,增加查找困難。同理,為了區分不同的將要下載的excel表,filename=配置文件中讀取的固定exccel文件名+程序中小時分鍾生成的可變文件名+“.xls”,這樣做可以使同一天內的excel文件名保持不相同。
生成年月日的可變路徑的代碼如下:
java代碼
1 public static String getRelativeDir() { 2 //Date d = new Date(); 3 Calendar calendar = Calendar.getInstance(); 4 SimpleDateFormat s=new SimpleDateFormat("yyyy-MM-dd"); 5 String curDate = s.format(calendar.getTime()); //當前日期 6 return curDate; 7 }
生成小時分鍾的可變文件名的代碼如下:
java代碼
1 public static String hourMinuteStr() { 2 Calendar cal = Calendar.getInstance(); 3 //當前小時數 4 int time = cal.get(Calendar.HOUR_OF_DAY); 5 // 當前分鍾數 6 int MINUTE = cal.get(Calendar.MINUTE); 7 String randomnum = time+""+MINUTE; 8 //如果月份為7轉變為07 9 return randomnum.length()==3?"0"+randomnum:randomnum; 10 }
2.創建WritableWorkbook
在生成path和filenme后,就可以創建一個WritableWorkbook生成excel
java代碼
1 //以file為文件名來創建一個Workbook 2 File file = new File(path+"/"+filename); 3 WritableWorkbook wwb = Workbook.createWorkbook(file); 4 // 創建工作表 5 WritableSheet ws = wwb.createSheet("Test Shee 1", 0);
3.設置excel表的格式
如果不設置excel表的格式,excel將使用默認的格式。在最初,我並沒有設置excel表格的格式,然后發現excel表格不美觀,因此添加了設置excel表格格式的代碼。
java代碼
1 //給sheet電子版中所有的列設置默認的列的寬度; 2 ws.getSettings().setDefaultColumnWidth(10); 3 //給某一列設置特殊的寬度 4 ws.setColumnView(4, 20); 5 //設置字體; 6 WritableFont font1 = new WritableFont(WritableFont.ARIAL,9,WritableFont.BOLD,false,UnderlineStyle.NO_UNDERLINE,Colour.BLACK); 7 WritableCellFormat cellFormat1 = new WritableCellFormat(font1); 8 //設置文字居中對齊方式; cellFormat1.setAlignment(jxl.format.Alignment.CENTRE); 9 // 設置邊框線 10 cellFormat1.setBorder(Border.ALL, BorderLineStyle.THIN); 11 //設置背景顏色 12 cellFormat1.setBackground(jxl.format.Colour.YELLOW); 13 //設置自動換行; 14 cellFormat1.setWrap(true); 15 //設置垂直居中; 16 cellFormat1.setVerticalAlignment(VerticalAlignment.CENTRE);
4.生成excel表中的lable
設置了excel表格的樣式后,就可以生成excel表格的元素了
java代碼
1 //要插入到的Excel表格的列號,默認從0開始 2 Label label_serilaNum= new Label(0, 0, "序號",cellFormat1); 3 //表示第1行第2列的值 4 Label label_createdBy= new Label(1, 0, "負責人",cellFormat1); 5 Label label_province= new Label(2, 0, "區域",cellFormat1); 6 ws.addCell(label_serilaNum); 7 ws.addCell(label_createdBy); 8 ws.addCell(label_province);
如果不需要設置excel表的格式,在new Lable中去掉cellFormat1就可以了,這樣excel會選擇默認的格式
我們上面說到,從數據庫中查到的信息是存放在ArrayList中,上面的代碼只是生成了表格的標題行,ArrayList中存儲的信息並沒有添加到excel表格中,添加ArrayList中的信息到excel表格中,只需要遍歷ArrayList,像上面的代碼一樣,將ArrayList中的信息填寫在對應的label中就可以了。注意判斷ArrayList是否為null,否者系統會拋出錯誤
5.寫/關文檔
在將ArrayList中的信息寫入excel后,還需要完成以下兩步
java代碼
1 //寫進文檔 2 wwb.write(); 3 // 關閉Excel工作簿對象 4 wwb.close();
三.將生成的excel表格的文件路徑和文件名返回給前端
在上述excel文件生成后,將文件的路徑和文件名返回給前端,這就完成了網頁下載表格的一大半。另外需要注意的是,返回的路徑最好不要是絕對路徑,應該為相對路徑。此處返回的路徑=“/”+程序生成的年月日可變文件夾;這樣做的好處是下載請求端不知道存放文件的具體位置,確保了文件的安全。
四.網頁彈出下載excel文件的對話框
實現網頁下載excel還需要最后一步:接收參數filename和filepath,這兩個參數是第三步中傳給前端的文件路徑(相對)和文件名,為什么要如此麻煩,后端直接下載不更加簡潔?這是因為這樣可以確保當前用戶還是發出下載請求的用戶,而不是其他的用戶;另外還可以再次確認下載的excel是哪一個。
1.檢查文件路徑和文件名稱是否存在
在接收到前端傳來的filename和filepath時,第一步做的是檢測文件路徑和文件名稱是否存在,如果存在才進行下一步的下載,否則不下載。
java代碼
1 //檢查文件路徑 2 BaseResponse baseResponse = new BaseResponse(); 3 String loadDir=loadDir_prefix+filepath; 4 File exceldir=new File(loadDir); 5 if(!exceldir.isDirectory()) { 6 baseResponse.setMsg("待下載的文件路徑不對,請輸入正確的路徑"); 7 baseResponse.setCode(ResponseCode.PARAMETER_ERROR); 8 return baseResponse; 9 } 10 //檢查文件 11 String path=loadDir+"/"+filename; 12 File file = new File(path); 13 if(!file.exists()) { 14 baseResponse.setMsg("待下載的文件不存在,請輸入正確的文件名"); 15 baseResponse.setCode(ResponseCode.PARAMETER_ERROR); 16 return baseResponse; 17 }
注意:前端傳回的路徑是相對路徑(由年月日生成的文件夾),這樣做的好處前面已經提到了。
2.使用HttpServletResponse下載excel文件
文件路徑和文件檢查通過后,使用HttpServletResponse下載文件
1 String filenametemp=filename.substring(filename.length()-8, filename.length()-4); 2 //設置excel文件名 3 response.setHeader("Content-Disposition", "attachment; filename=" +URLEncoder.encode("eSIM芯片管理平台消息預警查詢及導出", "utf-8")+ "["+URLEncoder.encode("表樣","utf-8")+"]"+filenametemp+".xls"); 4 //4.獲取要下載的文件輸入流 5 InputStream in = new FileInputStream(new File(filepath+"/"+filename)); 6 int len = 0; 7 //5.創建數據緩沖區 8 byte[] buffer = new byte[1024]; 9 //6.通過response對象獲取OutputStream流 10 OutputStream out = response.getOutputStream(); 11 //7.將FileInputStream流寫入到buffer緩沖區 12 while ((len = in.read(buffer)) > 0) { 13 //8.使用OutputStream將緩沖區的數據輸出到客戶端瀏覽器 14 out.write(buffer,0,len); 15 } 16 in.close(); 17 out.flush(); 18 response.flushBuffer();//不可少 19 out.close(); 20 }
上訴代碼中的filenametemp是獲取的由小時分鍾生成的相對文件名。另外上訴也提到了,excel的文件名是英文,但在response.setHeader中設置的文件名與傳到前端的文件名不相同,這樣做是沒有問題的。response.setHeader參數中的文件名才是excel最后的下載名,之前叫什么完全沒有關系。對於response.setHeader中的filename還有一點需要注意的是如果文件名是中文,需要utf-8進行編碼,否則會出現亂碼,特殊字符(如[ ] @等)不能進行utf-8編碼,編碼反而會導致出現亂碼,直接將特殊字符添加在文件中就可以了。
最后的最后,response.setHeader要在檢查文件路徑和文件名之后再進行設置,因為一旦設置response.setHeader就意味着網頁一定會彈出下載的對話框,哪怕文件名和文件路徑都不存在。
結束語:
第一次寫博客,寫的不好大家多多見諒,同時也希望自己能夠堅持下去。