最近做一个项目,遇到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;
}