2011-07-29 9 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; 
       }  
     });  

전송 된 두 번째 요청을 중지 할 수있는 방법이 있습니까? 이렇게하는 목적은 생성 된 보고서가 너무 커서 사용자가 요청을 제출할 때 재 스퍼 보고서가 파일을 가져 오는 데 오랜 시간이 걸리므로 사용자가 파일이 언제 정확하게 반환되는지 알 수 없기 때문입니다. 그래서 사용자가 제출 버튼을 클릭하면 페이지가 차단되고 파일이 돌아 오면 페이지를 차단 해제하는 블록 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)으로 저장 한 다음 해당 파일에 대한 직접 링크를 사용하여 파일을 가져 왔음을 의미합니다. 이 작업은 파일 시스템에서 수행하거나 웹 응용 프로그램에서 다운로드 스크립트를 사용하여 수행 할 수 있습니다. – Rafael

0

당신은 AJAX가 필요하지 않습니다. 그냥 document.location="yourpage.php"을 사용하십시오.

yourpage.php은 Excel 파일을 생성하는 곳입니다.

관련 문제