0.背景

一个简单的上传并解析excel文件的方法,在windows上正常导入并解析,但是放到linux中上传excel就报错”No such file or directory”。一开始以为是linux服务器权限的问题,但是把所有的权限都改成777后发现还是报错,于是开始找代码的错并修改成功。这篇文章简单记录了改错的过程。

1.windows下的代码
    @RequestMapping(value = "/batchImport ", method = RequestMethod.POST)
    @ResponseBody
    public InvokeResult batchImport(HttpServletResponse response,
                                    @RequestParam("file") MultipartFile file) throws IOException {
        try {
            if (file == null) {
                return InvokeResult.failure("文件内容错误");
            }
            int n;
           File f = new File(file.getOriginalFilename());
           try (InputStream in = file.getInputStream();
                OutputStream os = new FileOutputStream(f)) {
               // 得到文件流。以文件流的方式输出到新文件
               // 可以使用byte[] ss = multipartFile.getBytes();代替while
               byte[] buffer = new byte[4096];
               while ((n = in.read(buffer, 0, 4096)) != -1) {
                  os.write(buffer, 0, n);
               }
               // 读取文件第一行
               BufferedReader bufferedReader = new BufferedReader(new FileReader(f));
               // 输出路径
               bufferedReader.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
           InputStream is = new FileInputStream(f);
           Workbook xssfWorkbook = new HSSFWorkbook(is);
           Sheet xssfSheet = xssfWorkbook.getSheetAt(0);
            if (xssfSheet.getLastRowNum() < 1) {
                return InvokeResult.failure("EXCEL文件中没有数据!");
            }
          //从第4行开始输入
            int sum=0;
            for (int rowNum = 3; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
                try{
                        Row xssfRow = xssfSheet.getRow(rowNum);
                        EnergySavingReview energySavingReview =new EnergySavingReview();
                        String id = UUID.randomUUID().toString();
                        energySavingReview.setId(id);

                        // 每一行构建一个新对象
                        Student stu = new Student();

                        if (xssfRow != null) {
                            //第一列数据
                            Cell c1 = xssfRow.getCell(0);
                            try{
                                if(c1!=null){
                                    stu.id(getCellValueStr(c1));
                                }
                            }catch (Exception e){
                                return InvokeResult.failure("第" + (rowNum + 1) + "行数据,id解析失败!");
                            }
                            //继续构造其他行数据
                            
                         
                }
                catch (Exception e) {
                    return InvokeResult.failure("导入失败,请检查第" + (rowNum + 1) + "行数据");
                }
            }

            //这里使用insert往数据库里插入数据
            
            
            String result="成功导入"+sum+"条数据.";
            return InvokeResult.success(result);

        }catch (Exception ex) {
            return InvokeResult.failure("批量导入数据源出现错误:" + ex.toString());
        }
    }

    //获取Excel单元格的字符串值
    public static String getCellValueStr(Cell cell) {
        cell.setCellType(CellType.STRING);
        return cell.getStringCellValue();
    }
    //获取Excel单元格的NUMERIC值
    public static double getCellValueDouble(Cell cell) {
        cell.setCellType(CellType.NUMERIC);
        return cell.getNumericCellValue();
    }

上面这段代码在windows上正常上传并解析excel入库,但是到了linux上就开始报错。查了很多百度,有的说是路径问题,有的说是格式问题,但是最后都没有解决掉。最终在不断的尝试下,终于找到问题所在,在于文件流那一部分。

2. linux 下的代码
    @RequestMapping(value = "/batchImport ", method = RequestMethod.POST)
    @ResponseBody
    public InvokeResult batchImport(HttpServletResponse response,
                                    @RequestParam("file") MultipartFile file) throws IOException {
        try {
            if (file == null) {
                return InvokeResult.failure("文件内容错误");
            }
            try {
            if (file == null) {
                return InvokeResult.failure("文件内容错误");
            }
            Workbook workbook = null;
            InputStream inputStream = file.getInputStream();
            workbook = new HSSFWorkbook(inputStream);
            Sheet xssfSheet = workbook.getSheetAt(0);  //读取第一个sheet页
            if (xssfSheet.getLastRowNum() < 1) {
                return InvokeResult.failure("EXCEL文件中没有数据!");
            }
          //从第4行开始输入
            int sum=0;
            for (int rowNum = 3; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
                try{
                        Row xssfRow = xssfSheet.getRow(rowNum);
                        EnergySavingReview energySavingReview =new EnergySavingReview();
                        String id = UUID.randomUUID().toString();
                        energySavingReview.setId(id);

                        // 每一行构建一个新对象
                        Student stu = new Student();

                        if (xssfRow != null) {
                            //第一列数据
                            Cell c1 = xssfRow.getCell(0);
                            try{
                                if(c1!=null){
                                    stu.id(getCellValueStr(c1));
                                }
                            }catch (Exception e){
                                return InvokeResult.failure("第" + (rowNum + 1) + "行数据,id解析失败!");
                            }
                            //继续构造其他行数据
                            
                         
                }
                catch (Exception e) {
                    return InvokeResult.failure("导入失败,请检查第" + (rowNum + 1) + "行数据");
                }
            }

            //这里使用insert往数据库里插入数据
            
            
            String result="成功导入"+sum+"条数据.";
            return InvokeResult.success(result);

        }catch (Exception ex) {
            return InvokeResult.failure("批量导入数据源出现错误:" + ex.toString());
        }
    }

把原来那一部分try…catch 去掉后,改成下面这样

            Workbook workbook = null;
            InputStream inputStream = file.getInputStream();
            workbook = new HSSFWorkbook(inputStream);
            Sheet xssfSheet = workbook.getSheetAt(0);  //读取第一个sheet页
            if (xssfSheet.getLastRowNum() < 1) {
                return InvokeResult.failure("EXCEL文件中没有数据!");
            }

然后重新打包上传到linux上,就上传解析excel正常了。