2015-03-19 69 views
22

我有一個需求:我正在發送一個AJAX請求以將一些數據傳遞給服務器。在我的服務器中,我正在使用該數據創建一個文件。如何從Liferay serveResource( - , - )方法中的AJAX請求下載文件

「現在問題是文件沒有下載到客戶端」。

(我使用Apache POI API從給定數據創建excel文件)。 任何人都可以幫助我做到這一點?

這裏是我的代碼:

(代碼以使AJAX請求)

<script> 
    function downloadUploadedBacklogs() { 

     try { 
      var table_data = []; 

      var count = jQuery("#backlogTable tr:first td").length; 
      jQuery("#<portlet:namespace/>noOfColumns").val(count); 
      var index = 0; 
      jQuery('tr').each(function(){ 

       var row_data = ''; 
       jQuery('td', this).each(function(){ 
        row_data += jQuery(this).text() + '='; 
       }); 
       table_data.push(row_data+";"); 

      }); 
      jQuery("#<portlet:namespace/>backlogDataForDownload").val(table_data); 
      jQuery("#<portlet:namespace/>cmd").val("downloadUploadedBacklogs"); 
      alert('cmd: ' + jQuery("#<portlet:namespace/>cmd").val()); 
      var formData = jQuery('#<portlet:namespace/>backlogImportForm').serialize(); 

      jQuery.ajax({ 
       url:'<%=resourceURL%>', 
       data:formData, 
       type: "post", 
       success: function(data) { 

       } 
      }); 
      alert('form submitted'); 

     } catch(e) { 
      alert('eroor: ' + e); 
     } 
    }; 
</script> 

Java代碼的serveResource( - , - )方法

/* 
* serveResource(-, -) method to process the client request 
*/ 
public void serveResource(ResourceRequest resourceRequest, 
      ResourceResponse resourceResponse) throws IOException, 
      PortletException { 


     String cmd = ParamUtil.getString(resourceRequest,"cmd"); 
     System.out.println("**********************cmd*************"+cmd); 

     if(cmd!="") { 
      if("downloadUploadedBacklogs".equalsIgnoreCase(cmd)){ 

       String backlogData = ParamUtil.getString(resourceRequest, "backlogDataForDownload"); 
       ImportBulkDataUtil.downloadUploaded("Backlogs", resourceRequest,resourceResponse); 
      } 
     } 
} 

/ * ImportBulkDataUtil.downloadUploaded( - , - , - )方法創建Excel文件 /

public static void downloadUploaded(String schema, ResourceRequest resourceRequest,ResourceResponse resourceResponse) { 

     String excelSheetName = ParamUtil.getString(resourceRequest,"excelSheetName"); 

     try { 
      resourceResponse.setContentType("application/vnd.ms-excel"); 
      resourceResponse.addProperty(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="+excelSheetName+"_Template.xls"); 

      OutputStream outputStream=resourceResponse.getPortletOutputStream(); 
      //converting the POI object as excel readble object 
      HSSFWorkbook objHSSFWorkbook=new HSSFWorkbook(); 
      HSSFSheet objHSSFSheet=objHSSFWorkbook.createSheet(excelSheetName+"_Template"); 

      //set the name of the workbook 
      Name name=objHSSFWorkbook.createName(); 
      name.setNameName(excelSheetName+"_Template"); 

      objHSSFSheet.autoSizeColumn((short)2); 

      // create freeze pane (locking) top row 
      objHSSFSheet.createFreezePane(0, 1); 

      // Setting column width 
      String excelData = StringPool.BLANK; 
      if((schema.equalsIgnoreCase("Backlogs"))){ 
       System.out.println("Inside BacklogsCreation.........."); 
       objHSSFSheet.setColumnWidth(0, 10000); 
       objHSSFSheet.setColumnWidth(1, 7000); 
       objHSSFSheet.setColumnWidth(2, 7000); 
       objHSSFSheet.setColumnWidth(3, 7000); 
       objHSSFSheet.setColumnWidth(4, 7000); 
       objHSSFSheet.setColumnWidth(5, 5000); 
       objHSSFSheet.setColumnWidth(6, 5000); 
       objHSSFSheet.setColumnWidth(7, 7000); 
       objHSSFSheet.setColumnWidth(8, 7000); 
       excelData = ParamUtil.getString(resourceRequest,"backlogDataForDownload"); 
      } 
      System.out.println("downloadUploaded excelTableData: " + excelData); 

      // Header creation logic 

      HSSFRow objHSSFRowHeader = objHSSFSheet.createRow(0); 
      objHSSFRowHeader.setHeightInPoints((2*objHSSFSheet.getDefaultRowHeightInPoints())); 
      CellStyle objHssfCellStyleHeader = objHSSFWorkbook.createCellStyle(); 
      objHssfCellStyleHeader.setFillBackgroundColor((short)135); 
      objHssfCellStyleHeader.setAlignment(objHssfCellStyleHeader.ALIGN_CENTER); 
      objHssfCellStyleHeader.setWrapText(true); 

      // Apply font styles to cell styles 
      HSSFFont objHssfFontHeader = objHSSFWorkbook.createFont(); 
      objHssfFontHeader.setFontName("Arial"); 
      objHssfFontHeader.setColor(HSSFColor.WHITE.index); 

      HSSFColor lightGrayHeader = setColor(objHSSFWorkbook,(byte) 0x00, (byte)0x20,(byte) 0x60); 
      objHssfCellStyleHeader.setFillForegroundColor(lightGrayHeader.getIndex()); 
      objHssfCellStyleHeader.setFillPattern(CellStyle.SOLID_FOREGROUND); 

      objHssfFontHeader.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); 
      objHssfFontHeader.setFontHeightInPoints((short)12); 
      objHssfCellStyleHeader.setFont(objHssfFontHeader); 
      objHssfCellStyleHeader.setWrapText(true); 

      // first column about Backlog title 
      HSSFCell objBacklogTitleCell = objHSSFRowHeader.createCell(0); 
      objBacklogTitleCell.setCellValue("Backlog"); 
      objBacklogTitleCell.setCellStyle(objHssfCellStyleHeader); 

      // second column about Description 
      HSSFCell objBacklogDescCell = objHSSFRowHeader.createCell(1); 
      objBacklogDescCell.setCellValue("Description"); 
      objBacklogDescCell.setCellStyle(objHssfCellStyleHeader); 

      // third column about Project 
      HSSFCell objProjectNameCell = objHSSFRowHeader.createCell(2); 
      objProjectNameCell.setCellValue("Project"); 
      objProjectNameCell.setCellStyle(objHssfCellStyleHeader); 
      setComment("Project which the backlog belongs to", objProjectNameCell); 

      // fourth column about Category 
      HSSFCell objCategoryNameCell = objHSSFRowHeader.createCell(3); 
      objCategoryNameCell.setCellValue("Category"); 
      objCategoryNameCell.setCellStyle(objHssfCellStyleHeader); 
      setComment("Category which the backlog belongs to (i.e. Bug, New Requirement, Enhancement)", objCategoryNameCell); 

      // fifth column about Group 
      HSSFCell objGroupNameCell = objHSSFRowHeader.createCell(4); 
      objGroupNameCell.setCellValue("Group"); 
      objGroupNameCell.setCellStyle(objHssfCellStyleHeader); 
      setComment("Group which the backlog belongs to", objGroupNameCell); 

      // sixth column about Est. Start Date 
      HSSFCell objEstStartDtCell = objHSSFRowHeader.createCell(5); 
      objEstStartDtCell.setCellValue("Est. Start Date"); 
      objEstStartDtCell.setCellStyle(objHssfCellStyleHeader); 
      setComment("Date Format: dd/mm/yyyy", objEstStartDtCell); 

      // seventh column about Est. End Date 
      HSSFCell objEstEndDtCell = objHSSFRowHeader.createCell(6); 
      objEstEndDtCell.setCellValue("Est. End Date"); 
      objEstEndDtCell.setCellStyle(objHssfCellStyleHeader); 
      setComment("Date Format: dd/mm/yyyy", objEstEndDtCell); 

      // fifth column about Group 
      HSSFCell objStatusCell = objHSSFRowHeader.createCell(7); 
      objStatusCell.setCellValue("Status"); 
      objStatusCell.setCellStyle(objHssfCellStyleHeader); 

      String excelTableDataRecords[] = excelData.split(";"); 
      for(int i=1; i<excelTableDataRecords.length; i++) { 

       HSSFRow objHSSFRow = objHSSFSheet.createRow(i); 
       objHSSFRow.setHeightInPoints((2*objHSSFSheet.getDefaultRowHeightInPoints())); 

       excelTableDataRecords[i] = excelTableDataRecords[i].substring(0, (excelTableDataRecords[i].length()-2)); 
       if(excelTableDataRecords[i].charAt(0) == ',') { 
        excelTableDataRecords[i] = excelTableDataRecords[i].substring(1, (excelTableDataRecords[i].length())); 
       } 
       String excelTableColumns[] = excelTableDataRecords[i].split("::"); 

       for(int j=0; j<excelTableColumns.length; j++) { 

         // Apply font styles to cell styles 
         HSSFFont objHssfFont = objHSSFWorkbook.createFont(); 
         objHssfFont.setFontName("Arial"); 
         CellStyle objHssfCellStyle = objHSSFWorkbook.createCellStyle(); 
         objHssfFont.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); 
         objHssfFont.setColor(HSSFColor.BLACK.index); 
         objHssfFont.setFontHeightInPoints((short)10); 

         objHssfCellStyle.setWrapText(true); 
         objHssfCellStyle.setFont(objHssfFont); 
         // other column about Backlog title 
         HSSFCell objNewHSSFCellFirstNameAdd = objHSSFRow.createCell(j); 
         objNewHSSFCellFirstNameAdd.setCellValue(excelTableColumns[j]); 
         objNewHSSFCellFirstNameAdd.setCellStyle(objHssfCellStyle); 
       } 
      } 

      objHSSFWorkbook.write(outputStream); 
     } catch (IOException e) { 
      e.printStackTrace(); 
      System.out.println("Exception raised in downloadUploaded() method to download uploaded excel data"); 
     } 
    } 

誰能幫助我?

PortletResponseUtil.sendFile(resourceRequest, resourceResponse, "FILENAME", byteStream.toByteArray(), "CONTENT_TYPE"); 

,而不是直接寫的:

+0

** [請參見本:Java Servlet的下載文件示例](http://www.codejava.net/java-ee/servlet/java-servlet-download-file-example)** – 2015-03-19 08:15:44

+0

我也試過與resourceURL相同。但是,由於我的數據動態變化,所以我需要更新resourceURL參數值。但是,當我更新它比只有部分數據將發送到我的serveResource( - , - )方法 – 2015-03-19 08:18:25

+0

而我用resourceURL標識的另一個問題是具有一定長度限制的URL。所以當數據很龐大時會造成問題。 – 2015-03-19 08:22:08

回答

2

你可以寫出如下POI HSSFWorkbook的內容,以一個ByteArrayOutputStream,然後使用Liferay的PortletResponseUtil SENDFILE(流的toByteArray()方法)方法resourceResponse。

但是,可能出於安全原因(Javascript不能直接將文件寫入客戶端),您無法通過Ajax執行此操作。

您也可以將您在JS代碼中計算的原始數據保存到隱藏的輸入中,並通過常規表單提交將其傳遞給服務器。

+0

嗨Tryfon,謝謝你的回覆..我會嘗試它,讓你知道狀態 – 2015-03-20 04:34:12

+0

我試過下面(但它並沒有解決我的問題問題): ByteArrayOutputStream byteArrOStream = new ByteArrayOutputStream(); objHSSFWorkbook.write(byteArrOStream); PortletResponseUtil.sendFile(resourceRequest,resourceResponse,excelSheetName +「_ Template.xls」,byteArrOStream.toByteArray(),「application/vnd.ms-excel」); 你可以把更多的燈光放在我接下來要做的事情上嗎? – 2015-03-20 07:57:25

2

只是將請求作爲GET返回文件的字節流作爲響應並相應地設置標題(取決於您的文件格式爲excel/pdf),然後在客戶端打開新標籤中的響應,瀏覽器會開始文件下載。

+0

我嘗試過沒有辦法,你能提供一個樣本參考它 – 2015-04-23 12:23:48

2

我認爲這只是你的ajax命令,它不符合要求。 請參閱jquery ajax文檔。

這似乎ajax jquery抱怨xml數據下載,但它不是相應的Excel數據格式。

在ajax中將dataType設置爲「text」,並在將生成的文件發送給客戶端之前執行良好的MIME類型。使excel文件下載被瀏覽器解釋爲真正的excel文件。

7

可能有2個問題。要麼你根本不發送文件,要麼ajax沒有下載它。

從你的代碼中,我可以看到你在響應的輸出流中寫入文件,所以我懷疑該部分正在工作。如果它包含response body中的數據,也許你可以打開瀏覽器開發者工具來查看服務器的響應。

第二部分是複雜的,因爲從JS的性質(安全原因),你不能直接下載JS本身(下載不會自行啓動)。

您需要爲使用iframe和文件的URL追加到,並提交形式開始下載

$("body").append("<iframe src='" + data.message + "' style='display: none;' ></iframe>"); 

您可以使用新的HTML5 FileAPI在一個請求爲你做這個。只需指定blobresponseType: 'blob')類型的響應,從響應主體轉換URL,將其附加到新創建的錨點<a>的href屬性並單擊它。

查看this發佈瞭解更多詳情。

希望有所幫助。

+0

謝謝你的建議,我會盡力讓你知道 – 2015-04-23 13:45:30

+0

我們正在使用FileAPI,所以你可以下載文件在單個請求比較第一種方法,你需要將文件保存在某個地方,然後發送它的網址併發送另一個請求以便下載它。 – Mior 2015-04-23 14:42:50

1

只需調用帶參數如下功能:

網址 - 要請求的文件
數據 - 櫃面要 發送一些數據
的PageIndex - DIV ID其中u要追加的iframe 並且它將被刪除而沒有#。

this.ajaxDownload = function(url, data,pageId) { 
       pageId = '#' + pageId; 
       if ($(pageId + ' #download_iframe').length == 0) { 
        $("<iframe id='download_iframe' style='display: none' src='about:blank'></iframe>").appendTo(pageId); 
       } 

       var input = "<input type='hidden' name='requestJson' value='" + JSON.stringify(data) + "'>"; 

       var iframe_html = "<html>"+ 
        "<head>"+ 
        "</head>"+ 
        "<body>"+ 
        "<form id='downloadForm' method='POST' action='" + url +"'>" +input+ "</form>" + 
        "</body>"+ 
        "</html>"; 

       var ifrm = $(pageId + ' #download_iframe')[0].contentWindow.document; 
       ifrm.open(); 
       ifrm.write(iframe_html); 
       ifrm.close(); 

       $(pageId + ' #download_iframe').contents().find("#downloadForm").submit(); 
} 
+0

我收到異常像:contentWindow undefined,ifrm.open(); //無法打開 – 2015-04-24 15:28:13

+0

@ChandanPrakashSharma你不發送pageId正確嘗試發送div id到它。你可以通過調試代碼來確保你的頁面ID工作正常,如果我們檢查長度等於零的條件 – KlwntSingh 2015-04-25 06:53:32

相關問題