2015-03-19 73 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