如何在Liferay serveResource( - , - )方法中从AJAX请求下载文件

时间:2015-03-19 08:12:59

标签: java javascript jquery ajax liferay

我有一个要求:我正在制作一个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");
        }
    }

任何人都可以帮助我吗?

5 个答案:

答案 0 :(得分:7)

可能有2个问题。您根本不发送文件或ajax没有下载它。

从您的代码中我可以看到您在响应的输出流中编写文件,因此我怀疑该部分正在运行。也许您可以打开浏览器开发人员工具,查看来自服务器的响应(如果它包含response body中的数据。

第二部分很复杂,因为从JS的本质(安全原因)你不能直接在JS本身下载(下载不会自行启动)。

您需要使用iframe并附加文件网址并提交表单以开始下载

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

您可以在一个请求中使用新的HTML5 FileAPI为您执行此操作。只需为响应指定blobresponseType: 'blob')类型,从响应正文转换URL,将其附加到新创建的锚<a>元素的href属性,然后单击它。

有关详细信息,请参阅this帖子。

希望有所帮助。

答案 1 :(得分:2)

您可以将POI HSSFWorkbook的内容写入ByteArrayOutputStream,然后在Liferay的PortletResponseUtil sendFile()方法中使用流的toByteArray()方法,如下所示:

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

而不是直接写入resourceResponse。

但是,可能出于安全原因(Javascript无法直接将文件写入客户端),您无法通过Ajax执行此操作。

您也可以将在JS代码中计算的原始数据保存到隐藏的输入中,并通过常规表单提交将其传递给服务器。

答案 2 :(得分:2)

将请求作为GET,返回文件的字节流作为响应并相应地设置标题(取决于您的文件格式excel / pdf)然后在客户端只需在新标签中打开响应,浏览器将启动文件下载。

答案 3 :(得分:2)

我认为这只是你的ajax命令,他不遵守要求。 请参阅jquery ajax文档。

似乎ajax jquery抱怨xml数据下载,但它与excel数据格式无关。

将dataType设置为&#34; text&#34;在ajax中,在将生成的文件发送到客户端之前做了好的MIME类型。使得excel文件下载被浏览器解释为真正的excel文件。

答案 4 :(得分:1)

只需使用参数调用以下函数:

  

url - 您想要请求文件
数据的地方 - 您想要的   发送一些数据
pageIndex - 你想要追加iframe的div id   而且没有#将被删除。

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();
 }