关于Excel文件上传到后端问题

时间:2024-03-01 07:41:13

最近做一个项目,遇到excel上传问题,在此记录下问题以及解决方案。由于开发全栈,前端后端都要写,前端使用vue+element.ui,没有使用官方推荐的那一套写法。而是用了最传统的方法,代码如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
由于接触vue不深,可能写的不太好。下面是后端代码,由于客户需求,excel有三种不同的格式,.xls、.xlsx、.cxv。在网上找了一些资料,使用poj解析.xls和.xlsx,都是这样写:

 Workbook book = null; 
        try { 
            book = new XSSFWorkbook(excelFile); 
        } catch (Exception ex) { 
            book = new HSSFWorkbook(new FileInputStream(excelFile)); 
        } 

但是我用的时候却发现问题,对于.xlsx格式文件解析成功,但是对.xls格式文件解析报错,然后我用book = new XSSFWorkbook(excelFile); 来解析.xls竟然成功了,然后仔细思考了一下,原来是因为测试的文件test.xls是由原先的test.xlsx直接改后缀得到的文件,俩个文件的内部格式其实都是.xlsx。
然后我删除文件,将源文件test.xlsx另存为test2.xls,再次解析就成功了,因为俩个文件格式一样。
代码如下:

// 导入excel数据到数据库  1,将excel数据存储到map
    public List<Map<String, String>> excelToList(String path, String fileType) {
        boolean flag = true;
        List<Map<String, String>> list = new ArrayList<>();
        if (fileType.equals("xls") || fileType.equals("xlsx")) {
            list = getListOfXlsx(path,fileType);
        } else if (fileType.equals("csv")) {
            list = getListOfCsv(path);
        }
        return list;
    }
     // 解析.xls和.xlsx格式的文件
    private List<Map<String, String>> getListOfXlsx(String path,String fileType) {
        Workbook wb = null;
        Sheet sheet = null;
        List<Map<String, String>> list = new ArrayList<>();
        Row row = null;
        InputStream is = null;
        String columns[] = {"cropname", "periodname", "climatename", "effect", "advise"};
        try {
            is = new FileInputStream(path);
            if (fileType.equals("xls")){
                wb = new HSSFWorkbook(is);
            }else{
                wb = new XSSFWorkbook(is);
            }


            sheet = wb.getSheetAt(0);
            // 获取最大行数
            int rownum = sheet.getPhysicalNumberOfRows();
            // 获取第一行
            row = sheet.getRow(0);
            // 获取最大列数
            int colnum = row.getPhysicalNumberOfCells();
            String cellData = null;
            for (int i = 1; i < rownum; i++) {
                Map<String, String> map = new LinkedHashMap<>();
                row = sheet.getRow(i);
                if (row != null) {
                    for (int j = 0; j < colnum; j++) {
                        if (row.getCell(j) != null && row.getCell(j).getStringCellValue() != null) {
                            cellData = row.getCell(j).getStringCellValue();
                            map.put(columns[j], cellData);
                        } else {
                            map.put(columns[j], "无");
                        }
                    }
                } else {
                    break;
                }
                list.add(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

然后解析.csv格式文件,网上有人说csv和xls可以同样方法解析,但是我试过了以后报错,于是查了一下资料,csv文件,全名 comma separated values,以逗号分隔文本内容,是纯文本文件。虽然用excel打开后格式排版了,但是那是excel对它进行了处理。用notepad打开能看到最原始的文本。
在这里插入图片描述
需要使用apache的opencsv解析,我使用的是opencsv-2.3版本的,
下载链接http://www.java2s.com/Code/Jar/o/Downloadopencsv23jar.htm
代码如下:

// 解析csv格式文件
private List<Map<String, String>> getListOfCsv(String path) {
        List<Map<String,String>> list = new ArrayList<>();
        InputStream is = null;
        InputStreamReader isr = null;
        CSVReader reader = null;
        try {
            is = new FileInputStream(path);
            isr = new InputStreamReader(is);
            reader = new CSVReader(isr);
            String[] str = null;
            reader.readNext();
            while ((str = reader.readNext()) != null){
                Map<String,String> map = new LinkedHashMap<>();
                map.put("", str[0]);
                map.put("", str[1]);
                map.put("", str[2]);
                map.put("", str[3]);
                map.put("", str[4]);
                list.add(map);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }