通过ajax调用servlet下载文件。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过ajax调用servlet下载文件。相关的知识,希望对你有一定的参考价值。
想在一个jsp页面中通过ajax调用一个servlet来下载文件。当文件不存在的时候通过前台的ajax提示:文件不存在。 我自己写了一个,但是通过ajax调用下载的servlet时总不弹出下载框,而通过<a herf="...servlet"> 就可以下载。但是想实现提示文件不存在的功能,希望能帮我解决下。给个例子参考下也行,369320293@qq.com 谢谢。
通过response的contentType做处理,JS收到进行区别、再提示追问啥意思呢,response.setContentType("application/zip"); 具体怎么弄呢?
参考技术A response.contentType设置成text/html 参考技术B 百度啊 !下载的代码一大堆通过发送ajax请求下载Excel文件
【中文标题】通过发送ajax请求下载Excel文件【英文标题】:Download Excel File by sending ajax request 【发布时间】:2011-10-16 07:32:48 【问题描述】:我使用 ajaxForm 发送我的初始请求。该方法被调用并设置了所有响应,但是当我尝试打开窗口时,它再次重新触发请求。所以请求被发送了两次。附上我的请求。
$('#reportForm').ajaxForm(
dataType :'json',
type :'POST',
url : 'report/initialRequest.html',
beforeSubmit :validateSearchField,
ifModified : true,
success :function(data, textStatus, jqXHR),
complete : function(jqXHR, textStatus)
window.location.href = "report/initialRequest.html" + "?" + $('#reportForm').formSerialize();
$.unblockUI();
return false;
);
有什么方法可以阻止发送第二个请求。这样做的全部目的是生成的报告太大了,因此当用户提交请求时,jasper 报告需要很长时间才能获取文件,因此用户不知道文件何时返回。所以我使用了一个阻止 UI 插件,当用户单击提交按钮时,页面被阻止,一旦文件返回,我就会取消阻止页面。
或者任何机构对如何实现这一点有更好的想法。
控制器代码
@RequestMapping("/report/initialRequest.html")
public @ResponseBody Map<String, Object> handleInitialRequest
(HttpSession session, HttpServletRequest request, HttpServletResponse response )
Collection<Results> results = getResults();
Map<String,Object> requestMap = new HashMap<String,Object>();
try
getReportDataAsExcel(session, request, response , results );
catch (JRException e)
e.printStackTrace();
requestMap.put("status", "SUCCESS");
return requestMap;
@SuppressWarnings("unchecked")
public void getReportDataAsExcel(HttpSession session,HttpServletRequest request, HttpServletResponse response, Collection results) throws JRException
JRDataSource reportSource = new JRBeanCollectionDataSource( results );
Map parameters = new HashMap();
JRAbstractLRUVirtualizer virtualizer = null;
// JRSwapFile swapFile = new JRSwapFile( getServletContext().getRealPath("/reports/"), 1024, 1024);
JRSwapFile swapFile = new JRSwapFile( getServletContext().getRealPath("/reports/operationalreports/"), 1024, 1024);
virtualizer = new JRSwapFileVirtualizer(2, swapFile, true);
parameters.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);
//logger.debug(reportUrl);
Resource mainReport = null;
JasperDesign design = null;
JasperReport compiledReport = null;
JasperPrint outputReport = null;
try
mainReport = getApplicationContext().getResource(reportUrl);
if (!mainReport.exists())
throw new JRRuntimeException("File .jrxml was not found. The file must exists before compiling.");
InputStream reportInputStream = mainReport.getInputStream();
design = JRXmlLoader.load(reportInputStream);
compiledReport = JasperCompileManager.compileReport(design);
long start = System.currentTimeMillis();
logger.debug("Starting Time : " + start);
outputReport = JasperFillManager.fillReport(compiledReport, parameters, reportSource);
logger.debug("Filling time : " + (System.currentTimeMillis() - start));
writeExcel( session, request, response,outputReport );
if (virtualizer != null)
virtualizer.cleanup();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
@SuppressWarnings("unchecked")
public void writeExcel(HttpSession session,HttpServletRequest request, HttpServletResponse response, JasperPrint jasperPrint)
ByteArrayOutputStream reportOutputStream = new ByteArrayOutputStream(OUTPUT_BYTE_ARRAY_INITIAL_SIZE);
JRExporter exporter = new JRXlsExporter();
// Excel specific parameters
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, reportOutputStream);
try
exporter.exportReport();
catch (JRException e1)
// TODO Auto-generated catch block
e1.printStackTrace();
ServletOutputStream outputStream = null;
InputStream is = null;
byte[] res = reportOutputStream.toByteArray();
try
response.setContentType(getResponseContentType());
setResponseHeader(response);
response.setContentLength(reportOutputStream.size());
outputStream = response.getOutputStream();
is = new ByteArrayInputStream(res);
int iSize = 0;
byte[] oBuff = new byte[OUTPUT_BYTE_ARRAY_INITIAL_SIZE];
while ((iSize = is.read(oBuff)) != -1)
outputStream.write(oBuff, 0, iSize);
catch ( Exception e)
e.printStackTrace();
finally
try
outputStream.flush();
outputStream.close();
response.flushBuffer();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
【问题讨论】:
【参考方案1】:您不需要 AJAX;只需使用document.location="yourpage.php"
。
yourpage.php
是您生成 Excel 文件的位置。
【讨论】:
【参考方案2】:我们有一个生成 Excel 文件的整页请求。请求完成后,显示屏将包含指向生成的 Excel 文件的链接。我将此过程更改为通过 Ajax 调用 Excel 生成页面,但是当该过程完成时,它会将生成的 Excel 文件的 URL 返回到请求页面。用户会得到一个带有链接的对话框,他们可以在不运行 Excel 生成请求两次的情况下获取文件。你能改变你的流程让它这样运行吗?
【讨论】:
您能否举例说明您是如何实现的? 他的意思是他生成了文件,用唯一的名称(或 ID)保存它,然后使用指向该文件的直接链接获取它。这可以在文件系统中完成,也可以使用 Web 应用程序中的下载脚本完成。以上是关于通过ajax调用servlet下载文件。的主要内容,如果未能解决你的问题,请参考以下文章
在不使用 Ajax 请求的情况下使用 ExtJS 4.1 将文件下载为 CSV 的替代方法?