一个需求,用户点击下载按钮,将指定的excel的报表模板使用数据库数据渲染,然后下载到用户本地;
通常而言,对于一个文件的下载,可以有以下几种方式:
window.location.href=文件名称URL全路径;
window.open(文件名称URL全路径);
这种方式不友好的地方在于服务器的目录结构直接暴露出去,而且在IE下很有可能会报错权限问题等,甚至firefox中会触发那个年代久远而依然没有解决的bug。所以这里不推荐。
对于jxl生成excel文件,有两种方式,一种是生成文件保存到磁盘,另一种是直接保存到输出流中。
对于上述需求,如果生成的文件保存到磁盘,随着系统运行,磁盘会主键被占用,需要手动去删除。由于文件都较小,所以这里采用第二种方式,直接在内存中生成文件,然后提供给用户下载的时候response回去。
看一个例子:
用于响应下载请求的controller
- /**
- * 下载个人订单
- * @param request
- * @param response
- * @param modelMap
- */
- @RequestMapping(value="/download.do", method=RequestMethod.GET)
- public void processDownload(HttpServletRequest request,HttpServletResponse response
- , ModelMap modelMap) {
- long userId = getUserId(request);
- String ids = request.getParameter("ids");
- try {
- Long[] idarray = getIdsFromStringArray(ids.split(","));
- if (null == idarray || 0 == idarray.length) {
- return;
- }
- // 直接往response的输出流中写excel
- OutputStream outputStream = response.getOutputStream();
- // 获取文件名称
- String fileName = getUserFileName(userId);
- // 下载格式设置
- response.setContentType("APPLICATION/OCTET-STREAM");
- response.setHeader("Content-Disposition", "attachment; filename=/"" + fileName + "/"");
- // 读取数据渲染模板并写入outputstream中
- List<PhAdvertiseOrderDO> advertiseOrderList = phAdvertiseOrderService.getAdvertiseOrderByIds(idarray, userId);
- outputStream = excelFileService.generalExcelFileInOutputStream(outputStream, advertiseOrderList);
- outputStream.close();
- } catch (Exception e) {
- logger.error("下载报表发生异常!", e);
- }
- }
其中调用到的文件服务
其中的重点就在于
- /* (non-Javadoc)
- * @see com.netease.photography.service.ExcelFileService#generalExcelFileInOutputStream(java.lang.String, java.io.OutputStream, java.util.List)
- */
- public OutputStream generalExcelFileInOutputStream(OutputStream outputStream, List<PhAdvertiseOrderDO> advertiseOrderList) throws BiffException, IOException, WriteException {
- // 检查参数是否合法
- checkParam(tempalteFile,"no File",advertiseOrderList);
- // 获取模板
- Workbook templatebook = Workbook.getWorkbook(new File(tempalteFile));
- WritableWorkbook writeableWorkbook = Workbook.createWorkbook(outputStream, templatebook);
- // 读取数据写入模板
- readDataAndWriteTemplate(templatebook, writeableWorkbook, advertiseOrderList);
- return outputStream;
- }
- WritableWorkbook writeableWorkbook = Workbook.createWorkbook(outputStream, templatebook);
这句话指定了写入的数据到输出流中。
页面调用很简单
- function getOrderFileNoDirect() {
- var ids ="";
- for(var i=0;i<30;i++){
- if($("choose"+i) != null && $("choose"+i).checked == true) {
- ids += $("choose"+i).value;
- ids += ",";
- }
- }
- if(ids==""){
- alert('不能建立空报表!');
- return;
- }
- window.open("download.do?ids="+ids);
- }
来源: http://www.phpxs.com/code/1001462/