使用环境:springMVC、spring、mybatis、firefox22、ie9、MysqL 5、tomcat 6,操作系统:window7旗舰版
最近使用ajaxfileupload.js这个组件,在异步上传文件后遇到两个问题:
1、使用spring集成jackson插件,获取到的json格式的数据,ajaxfileupload会自动在前后加上<pre></pre>标记,导致json格式无法正确解析。
解决办法:
找到ajaxfileupload的源码,tyep=="json"的位置,修改如下:
if (type == "script") jQuery.globalEval(data); // Get the JavaScript object,if JSON is used. if (type == "json") { if (data.startsWith("<pre>") && data.endsWith("</pre>")) { data = data.substr(5,data.length - 11); data = jQuery.parseJSON(data); } else { eval("data = " + data); } }
即是去掉前后的标记,自己解析json数据。
2、需求:在获取到用户上传的excel文件,使用POI解析其中的内容,并写入内容的处理结果数据到excel,最后当数据解析完成后,将excel保存到服务器,并直接通知用户下载该文件(直接异步下载,弹出下载窗口)。
问题:在firefox下OK,在IE9下边,上传这一步,ie直接认为发送的是一个下载请求,直接弹出下载提示,下载的文件名为请求的action.do的名字。
问题分析:原来上传请求的action,发挥的是一个对象,通过jackson转换为json数据返回给前端,但ajaxfileupload无法识别这个数据,通过ie的断点调试,无法跟踪到发挥的数据到底是什么样的。而后台根本没有出现任何错误,前端也如此。后来,我将请求的action返回为一个string对象,严格按照json的格式拼装:
return "{\"success\" : \"" + true + "\"}";
这样问题解决……但是很遗憾任然没有找出问题所在……
@RequestMapping("import") @ResponseBody public String importWordsFromExcel(MultipartHttpServletRequest request,HttpSession session) { try { MultipartFile excel = request.getFile("excel"); LOG.debug("begin import words from excel file :" + excel.getOriginalFilename()); InputStream in = excel.getInputStream(); Workbook wb = null; try { // 2003 - 2007 wb = new HSSFWorkbook(in); LOG.debug("using excel 2003/2007"); } catch (OfficeXmlFileException e) { // 2007以后的版本 OPCPackage pkg = OPCPackage.open(in); wb = new XSSFWorkbook(pkg); LOG.debug("using excel 2010 or higher version."); } // 存放导入结果的列,无法实现 int resultColIndex = 7; CellStyle failStyle = wb.createCellStyle(); Font font = wb.createFont(); font.setBoldweight(Font.BOLDWEIGHT_BOLD); font.setColor(HSSFColor.RED.index); failStyle.setFont(font); CellStyle succStyle = wb.createCellStyle(); font = wb.createFont(); font.setBoldweight(Font.BOLDWEIGHT_BOLD); font.setColor(HSSFColor.GREEN.index); succStyle.setFont(font); Vocabulary v = null; Sheet sheet = wb.getSheetAt(0); int totalColNum = 0; if (sheet.getRow(0) != null) totalColNum = sheet.getRow(0).getLastCellNum() - sheet.getRow(0).getFirstCellNum(); String sheetName = sheet.getSheetName(); LOG.debug("current sheet name : " + sheetName); Cell cell = null; for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) { Row row = sheet.getRow(rowNum); if (rowNum == 0) { cell = row.createCell(resultColIndex); cell.setCellValue("完成状态"); cell.setCellStyle(failStyle); cell = row.createCell(resultColIndex + 1); cell.setCellValue("说明"); cell.setCellStyle(failStyle); continue; } v = new Vocabulary(); for (int colNum = 0; colNum <= totalColNum; colNum++) { cell = row.getCell(colNum,Row.CREATE_NULL_AS_BLANK); CellReference cellRef = new CellReference(rowNum,colNum); LOG.debug("cell reference : " + cellRef.formatAsString()); String content = ""; if (cell.getCellType() == Cell.CELL_TYPE_STRING) content = cell.getRichStringCellValue().getString().trim(); else if (cell.getCellType() == Cell.CELL_TYPE_BLANK) content = ""; else { continue; } switch (colNum) { case 1: // 单词 v.setWord(content); break; case 2: // 美式发音 v.setSoundmark(content); break; case 3: // 英式发音 v.setSoundmark2(content); break; case 4: // 释义 v.setMeaning(content); break; case 5: // 例句 v.setSentence(content); break; case 6: // 例句释义 v.setSentenceMean(content); break; default: break; } } try { Vocabulary tmpV = service.getByWord(v.getWord()); if (tmpV == null) { // 保存到数据库 service.add(v); cell = row.createCell(resultColIndex); cell.setCellValue("成功"); cell.setCellStyle(succStyle); cell = row.createCell(resultColIndex + 1); cell.setCellValue("导入成功."); // v.setStatus(Vocabulary.IMPORT_SUCCESS); // v.setResult("导入成功."); } else { cell = row.createCell(resultColIndex); cell.setCellValue("失败"); cell.setCellStyle(failStyle); cell = row.createCell(resultColIndex + 1); cell.setCellValue("单词已经存在."); // v.setStatus(Vocabulary.IMPORT_FAIL); // v.setResult("单词已存在."); } } catch (Exception e) { LOG.error("save words error : ",e); cell = row.createCell(resultColIndex); cell.setCellValue("失败"); cell.setCellStyle(failStyle); cell = row.createCell(resultColIndex + 1); cell.setCellValue("未知异常."); // v.setStatus(Vocabulary.IMPORT_FAIL); // v.setResult("未知异常."); } } String originalFilename = excel.getOriginalFilename(); User user = SystemUtil.getLoginUser(session); resultFilePath = request.getSession().getServletContext().getRealPath("/") + "/resource/tmp/" + FilenameUtils.getBaseName(originalFilename) + "_导入结果_" + user.getName() + "." + FilenameUtils.getExtension(originalFilename); FileOutputStream out = new FileOutputStream(resultFilePath); wb.write(out); out.close(); // GeneralMessage msg = new GeneralMessage(); // msg.setCode(GeneralMessage.SUCCESS); // msg.setMsg("导入完成."); // return msg; return "{\"success\" : \"" + true + "\"}"; } catch (Exception e) { LOG.error("import words error : ",e); } return null; }
下载结果文件的action方法:
@RequestMapping("downloadResultFile") @ResponseBody public ResponseEntity<byte[]> downloadUploadResult(HttpServletRequest request,HttpServletResponse response) { try { if (!StringUtils.hasLength(resultFilePath)) return null; String fileName = FilenameUtils.getName(resultFilePath); // // HttpHeaders headers = new HttpHeaders(); // headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); // headers.setContentDispositionFormData("attachment",new String(f.getBytes("UTF-8"),// "ISO-8859-1")); // return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(new // File(fileAbsolutePath)),headers,HttpStatus.CREATED); File file = new File(resultFilePath); // 根据文件路径获得File文件 // 设置文件类型(这样设置就不止是下Excel文件了,一举多得) response.setContentType("application/msexcel;charset=GBK"); // 文件名 response.setHeader("Content-Disposition","attachment;filename=\"" + new String(fileName.getBytes("GBK"),"ISO-8859-1") + "\""); response.setContentLength((int) file.length()); byte[] buffer = new byte[4096];// 缓冲区 BufferedOutputStream output = null; BufferedInputStream input = null; try { output = new BufferedOutputStream(response.getOutputStream()); input = new BufferedInputStream(new FileInputStream(file)); int n = -1; while ((n = input.read(buffer,4096)) > -1) { output.write(buffer,n); } output.flush(); // 不可少 response.flushBuffer();// 不可少 } catch (Exception e) { LOG.error("download upload words result file error : ",e); } finally { if (input != null) input.close(); if (output != null) output.close(); } } catch (Exception e) { LOG.error("download upload words result file error : ",e); } return null; }
前端javascript中的处理:
function importFromExcel() { var excel = $("#excelFile").val(); if (!excel || excel == "" || !(excel.endsWith("xls") || excel.endsWith("xlsx"))) { Error("未选择excel文件,请选择excel格式的文件后在进行导入操作."); return false; } $.ajaxFileUpload({ url : Util.getContentPath() + '/word/import.do',secureuri : false,fileElementId : "excelFile",dataType : 'json',success : function(data,status) { var msg = data; if (msg && msg.success == "true") { var callback = function() { window.location.href = Util.getContentPath() + "/word/downloadResultFile.do"; }; Alert("导入完成,可能有部分单词为成功导入!您需要下载<b>导入结果文件</b>来查看详细信息,点击确定后开始下载.",callback); } else { Error("批量导入出错."); } },error : function(data,status,e) { Error("批量导入出错."); } }); return false; }