I have a requirement like: I am making an AJAX request to pass some data to server. In my server I am creating a file using that data.
"Now problem is the file is not getting downloaded to client-side".
(I am using Apache POI API to create excel file from the given data). Can any one will help me to do this ?
Here is my code:
(Code to make AJAX request)
<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 code serveResource(-,-) method
/*
* 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(-, -, -) method to create excel file /
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");
}
}
Can anyone help me ?
We cannot download the file through Ajax, must use XMLHttpRequest.
Downloading Excel File using AJAX in jQuery Inside the DownloadFile JavaScript function, the URL of the File is passed as parameter to the jQuery AJAX function. Inside the jQuery AJAX function, using the XmlHttpRequest (XHR) call, the PDF file is downloaded as Byte Array (Binary Data).
Here is a simple resource URL example that makes an AJAX request to portlet action class and gets a response in JSON form. Import the liferay-portlet tag library to view.jsp file as shown below. Add the following code to view.jsp file. Here we have an anchor tag that calls the javascript method on clicking the link.
The file will be downloaded as BLOB using jQuery AJAX and XmlHttpRequest (XHR) request and then the file will be downloaded using the Response inside the Success event handler of jQuery AJAX function. In this article I will explain with an example, how to download file in AJAX Response (Success) using jQuery.
How to implement Resource URL in a Liferay application. We can use the Liferay resource URL to retrieve images, XML, JSON, or any other type of resource. Resource URL invokes the serveResource () method of the portlet.
The file will be downloaded as BLOB using jQuery AJAX and XmlHttpRequest (XHR) request and then the file will be downloaded using the Response inside the Success event handler of jQuery AJAX function. The PDF file are stored in a folder named Files inside the project directory.
There could be 2 issues. Either you don't send file at all or ajax is not downloading it.
From your code I can see that you writing file in response's output stream so I suspect that part is working. Maybe you can open browser developer tool to see response from server if it contains data in response body.
Second part is complicated because from nature of JS (security reason) you cannot download directly in JS itself (download will not start itself).
You need to use either iframe and append file url into and submit form to start download
$("body").append("<iframe src='" + data.message + "' style='display: none;' ></iframe>");
or
you can use new HTML5 FileAPI
to do this for you in one request. Just specify blob
(responseType: 'blob'
) type for response, convert URL from response body, append it to href attribute of newly created anchor <a>
element and click on it.
See this post for more details.
Hope that helps.
You can write the contents of the POI HSSFWorkbook to a ByteArrayOutputStream and then use the toByteArray() method of the stream in Liferay's PortletResponseUtil sendFile() method as follows:
PortletResponseUtil.sendFile(resourceRequest, resourceResponse, "FILENAME", byteStream.toByteArray(), "CONTENT_TYPE");
instead of writing directly to the resourceResponse.
However, probably for security reasons, (Javascript can not directly write files to a client) you can not do this via Ajax.
You could alternatively save the raw data that you calculate in your JS code to a hidden input and pass that to the server via a regular form submit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With