如何在Liferay serveResource(-,-)方法中从AJAX请求下载文件
How to download a file from AJAX request in Liferay serveResource(-, -) method
我有一个要求,比如:我正在发出一个AJAX请求,将一些数据传递给服务器。在我的服务器中,我正在使用这些数据创建一个文件。
"现在的问题是文件没有下载到客户端"。
(我正在使用ApachePOI 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(-, -) 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");
}
}
有人能帮我吗
可能存在2个问题。要么根本不发送文件,要么ajax没有下载
从您的代码中,我可以看到您在响应的输出流中编写文件,所以我怀疑该部分正在工作。若响应主体中包含数据,也许您可以打开浏览器开发工具来查看服务器的响应。
第二部分很复杂,因为从JS的性质(安全原因)来看,您不能直接在JS中下载(下载不会自行启动)。
您需要使用iframe和附加文件url到并提交表单来开始下载
$("body").append("<iframe src='" + data.message + "' style='display: none;' ></iframe>");
或
您可以使用新的HTML5FileAPI
在一个请求中为您做到这一点。只需指定响应的blob
(responseType: 'blob'
)类型,从响应主体转换URL,将其附加到新创建的锚<a>
元素的href属性中,然后单击它。
有关更多详细信息,请参阅本文。
希望能有所帮助。
您可以将POI HSSFWorkbook的内容写入ByteArrayOutputStream,然后在Liferay的PortletResponseUtil sendFile()方法中使用流的toByteArray()方法,如下所示:
PortletResponseUtil.sendFile(resourceRequest, resourceResponse, "FILENAME", byteStream.toByteArray(), "CONTENT_TYPE");
而不是直接写入resourceResponse。
然而,可能是出于安全原因(Javascript不能直接向客户端写入文件),您不能通过Ajax实现这一点。
或者,您可以将JS代码中计算的原始数据保存到隐藏的输入中,并通过常规表单提交将其传递给服务器。
我认为这只是您的ajax命令不符合要求。请参阅jquery ajax文档。
ajax jquery似乎抱怨xml数据下载,但与excel数据格式不同。
在ajax中将dataType设置为"text",并在将生成的文件发送到客户端之前执行良好的MIME类型。。它使下载的excel文件被浏览器解释为一个真正的excel文件。
只需将请求作为GET,返回文件的字节流作为响应,并相应地设置标题(取决于文件excel/pdf的格式),然后在客户端只需在新选项卡中打开响应,浏览器就会启动文件下载。
只需使用参数调用以下函数:
url-您想要请求文件
数据的位置-如果您想要发送一些数据
pageIndex-div id到要附加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();
}
- ajax请求的顺序总是不同的
- 从ajax请求中获取javascript对象
- Ajax请求文档就绪会导致jquery加载缓慢
- MockJax没有在JavaScript应用程序中发送对我AJAX请求的响应
- 正在传递JSONP标头's数据参数到另一个文件中的AJAX请求
- JavaScript代码未正确检查ajax请求
- "日期“;AJAX请求返回的类型值未定义
- 在等待ajax请求时显示微调器并禁用页面
- 跨域ajax请求
- Ajax请求返回空的数据字符串,但首先得到了正确的数据
- Javascript-如何让脚本与Ajax请求的数据一起运行
- ajax请求成功,但可以'我看不到我的数据
- 如何将给定的curl命令复制为jquery ajax请求
- 为什么我能够从javascript控制台发送跨域ajax请求
- 一台特定计算机的Ajax请求数据未定义/失败
- 获取ajax请求的请求头
- 原型Ajax请求参数为嵌套json
- 可以't从AJAX请求中筛选数据
- jQuery Mobile Collapse上的AJAX请求
- 暂停函数执行流程,直到ajax请求完成