JXL生成的excel文件+JAVA文件下載功能

jopen 9年前發布 | 6K 次閱讀 Java

一個需求,用戶點擊下載按鈕,將指定的excel的報表模板使用數據庫數據渲染,然后下載到用戶本地;

通常而言,對于一個文件的下載,可以有以下幾種方式:

window.location.href=文件名稱URL全路徑;

window.open(文件名稱URL全路徑);

這種方式不友好的地方在于服務器的目錄結構直接暴露出去,而且在IE下很有可能會報錯權限問題等,甚至firefox中會觸發那個年代久遠而依然沒有解決的bug。所以這里不推薦。

 

對于jxl生成excel文件,有兩種方式,一種是生成文件保存到磁盤,另一種是直接保存到輸出流中。

對于上述需求,如果生成的文件保存到磁盤,隨著系統運行,磁盤會主鍵被占用,需要手動去刪除。由于文件都較小,所以這里采用第二種方式,直接在內存中生成文件,然后提供給用戶下載的時候response回去。

 

看一個例子:

用于響應下載請求的controller

    /**

     * 下載個人訂單 
     * @param request 
     * @param response 
     * @param modelMap 
     */  
    @RequestMapping(value="/download.do", method=RequestMethod.GET)  
    public void processDownload(HttpServletRequest request,HttpServletResponse response  
            , ModelMap modelMap) {  
        long userId = getUserId(request);  
        String ids = request.getParameter("ids");  
        try {  
            Long[] idarray = getIdsFromStringArray(ids.split(","));  
            if (null == idarray || 0 == idarray.length) {  
                return;  
            }  
            // 直接往response的輸出流中寫excel  
            OutputStream outputStream = response.getOutputStream();  
            // 獲取文件名稱  
            String fileName = getUserFileName(userId);  
            // 下載格式設置  
            response.setContentType("APPLICATION/OCTET-STREAM");  
            response.setHeader("Content-Disposition", "attachment; filename=/"" + fileName + "/"");  

            // 讀取數據渲染模板并寫入outputstream中  
            List<PhAdvertiseOrderDO> advertiseOrderList = phAdvertiseOrderService.getAdvertiseOrderByIds(idarray, userId);  
            outputStream = excelFileService.generalExcelFileInOutputStream(outputStream, advertiseOrderList);  

            outputStream.close();  
        } catch (Exception e) {  
            logger.error("下載報表發生異常!", e);  
        }  
    }  </pre> 


其中調用到的文件服務

    /* (non-Javadoc)

     * @see com.netease.photography.service.ExcelFileService#generalExcelFileInOutputStream(java.lang.String, java.io.OutputStream, java.util.List) 
     */  
    public OutputStream generalExcelFileInOutputStream(OutputStream outputStream, List<PhAdvertiseOrderDO> advertiseOrderList) throws BiffException, IOException, WriteException {  
        // 檢查參數是否合法  
        checkParam(tempalteFile,"no File",advertiseOrderList);  

        // 獲取模板  
        Workbook templatebook = Workbook.getWorkbook(new File(tempalteFile));  
        WritableWorkbook writeableWorkbook = Workbook.createWorkbook(outputStream, templatebook);  
        // 讀取數據寫入模板  
        readDataAndWriteTemplate(templatebook, writeableWorkbook, advertiseOrderList);  

        return outputStream;  
    }  </pre> 


其中的重點就在于

    WritableWorkbook writeableWorkbook = Workbook.createWorkbook(outputStream, templatebook);  

這句話指定了寫入的數據到輸出流中。

 

頁面調用很簡單

    function getOrderFileNoDirect() {  
        var ids ="";  
        for(var i=0;i<30;i++){  
            if($("choose"+i) != null && $("choose"+i).checked == true) {  
                ids += $("choose"+i).value;  
                ids += ",";  
            }  
        }  
        if(ids==""){  
            alert('不能建立空報表!');  
            return;  
        }  
        window.open("download.do?ids="+ids);  
    }  

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!