我有一个要求:我正在制作一个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");
}
}
任何人都可以帮助我吗?
答案 0 :(得分:7)
可能有2个问题。您根本不发送文件或ajax没有下载它。
从您的代码中我可以看到您在响应的输出流中编写文件,因此我怀疑该部分正在运行。也许您可以打开浏览器开发人员工具,查看来自服务器的响应(如果它包含response body中的数据。
第二部分很复杂,因为从JS的本质(安全原因)你不能直接在JS本身下载(下载不会自行启动)。
您需要使用iframe并附加文件网址并提交表单以开始下载
$("body").append("<iframe src='" + data.message + "' style='display: none;' ></iframe>");
或
您可以在一个请求中使用新的HTML5 FileAPI
为您执行此操作。只需为响应指定blob
(responseType: '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();
}