2011-07-29 156 views
2

我使用ajaxForm發送我的初始請求。該方法被調用並且所有的響應都被設置,但是當我嘗試打開窗口時,它又重新觸發請求。所以請求發送兩次。我的請求包含了。通過發送ajax請求下載Excel文件

$('#reportForm').ajaxForm({ 

     dataType :'json', 
     type :'POST', 
     url : 'report/initialRequest.html', 

       beforeSubmit :validateSearchField, 

       ifModified : true, 
       success :function(data, textStatus, jqXHR){}, 
       complete : function(jqXHR, textStatus) { 
              window.location.href = "report/initialRequest.html" + "?" + $('#reportForm').formSerialize(); 
          $.unblockUI(); 
              return false; 
       }  
     });  

是否有辦法阻止第二個請求被髮送。這樣做的全部目的是生成的報告太大,所以當用戶提交請求時,jasper報告需要很長時間才能獲取文件,因此用戶不知道文件何時返回。所以我使用了一個塊UI插件,當用戶點擊提交按鈕時,頁面被阻止,並且一旦文件返回,我就解除阻止頁面。

或者任何機構對如何實現這一點有更好的想法。

控制器代碼

@RequestMapping( 「/報告/ initialRequest.html」)

public @ResponseBody Map<String, Object> handleInitialRequest 
(HttpSession session, HttpServletRequest request, HttpServletResponse response ) { 


Collection<Results> results = getResults(); 

    Map<String,Object> requestMap = new HashMap<String,Object>();   
    try { 
getReportDataAsExcel(session, request, response , results); 
} catch (JRException e) { 
     e.printStackTrace(); 
} 


     requestMap.put("status", "SUCCESS"); 
     return requestMap; 
} 



@SuppressWarnings("unchecked") 

公共無效getReportDataAsExcel(HttpSession的會議,HttpServletRequest的請求,響應HttpServletResponse的,彙集的結果)拋出JRException {

JRDataSource reportSource = new JRBeanCollectionDataSource(results); 

    Map parameters = new HashMap(); 

    JRAbstractLRUVirtualizer virtualizer = null; 



// JRSwapFile swapFile = new JRSwapFile(getServletContext().getRealPath("/reports/"), 1024, 1024); 
    JRSwapFile swapFile = new JRSwapFile(getServletContext().getRealPath("/reports/operationalreports/"), 1024, 1024); 
    virtualizer = new JRSwapFileVirtualizer(2, swapFile, true); 

    parameters.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);  


    //logger.debug(reportUrl); 
    Resource mainReport = null; 
    JasperDesign design = null; 
    JasperReport compiledReport = null; 
    JasperPrint outputReport = null; 

    try { 
     mainReport = getApplicationContext().getResource(reportUrl); 

     if (!mainReport.exists()){ 
     throw new JRRuntimeException("File .jrxml was not found. The file must exists before compiling."); 
     } 

     InputStream reportInputStream = mainReport.getInputStream(); 
     design = JRXmlLoader.load(reportInputStream); 
     compiledReport = JasperCompileManager.compileReport(design); 


     long start = System.currentTimeMillis(); 
     logger.debug("Starting Time : " + start); 

     outputReport = JasperFillManager.fillReport(compiledReport, parameters, reportSource); 

    logger.debug("Filling time : " + (System.currentTimeMillis() - start)); 
    writeExcel(session, request, response,outputReport); 


    if (virtualizer != null) 
    { 
     virtualizer.cleanup(); 
    } 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

@SuppressWarnings("unchecked") 
public void writeExcel(HttpSession session,HttpServletRequest request, HttpServletResponse response, JasperPrint jasperPrint) {  


    ByteArrayOutputStream reportOutputStream = new ByteArrayOutputStream(OUTPUT_BYTE_ARRAY_INITIAL_SIZE); 

    JRExporter exporter = new JRXlsExporter(); 

    // Excel specific parameters 
    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); 
    exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, reportOutputStream); 
    try { 
     exporter.exportReport(); 
    } catch (JRException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 


    ServletOutputStream outputStream = null; 
    InputStream is = null; 
    byte[] res = reportOutputStream.toByteArray(); 

    try{ 
     response.setContentType(getResponseContentType()); 
    setResponseHeader(response); 

    response.setContentLength(reportOutputStream.size()); 

     outputStream = response.getOutputStream(); 
     is = new ByteArrayInputStream(res); 

     int iSize = 0; 

     byte[] oBuff = new byte[OUTPUT_BYTE_ARRAY_INITIAL_SIZE]; 

     while ((iSize = is.read(oBuff)) != -1) { 
      outputStream.write(oBuff, 0, iSize); 

     } 



     } catch (Exception e){ 
      e.printStackTrace(); 
     } 
     finally { 

      try { 
      outputStream.flush(); 
      outputStream.close(); 
      response.flushBuffer(); 


     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     } 

} 

回答

1

我們有一個完整的頁面請求來生成一個Excel文件。請求完成後,顯示屏將包含指向生成的Excel文件的鏈接。我改變了這個過程,通過Ajax調用Excel生成頁面,但是當這個過程完成時,它會將生成的Excel文件的URL返回給請求頁面。用戶通過鏈接獲得對話框,並且可以在不運行Excel生成請求兩次的情況下獲取文件。你可以改變你的過程像那樣運行嗎?

+0

您能否提供一個例子來說明您是如何實現的? – srinivas

+0

他意味着他生成了該文件,並使用唯一的名稱(或ID)保存它,然後使用該文件的直接鏈接獲取該文件。這可以在文件系統中完成,也可以在Web應用程序中使用下載腳本。 – Rafael

0

你不需要AJAX;只需使用document.location="yourpage.php"即可。

yourpage.php是您生成Excel文件的位置。