获取如图所示的Excel数据
1.设计思路
1.1. 得到每一个单元格的值
List rowArrayList = new ArrayList;
List<ArrayList> allArrayList = new ArrayList<ArrayList>;
遍历Excel表格的所有行,第0行用来判断一共有多少列。将所有行存放到allArrayList集合中。
遍历Excel表格除0行外的所有行,得到每行的每一个单元格。
得到的单元格可能是合并的单元格。若要得到合并单元格的值,首先得到所有合并的单元格进行遍历,判断此单元格是否在合并单元格,然后得到该合并单元格的数据。
依此类推,得到每一个单元格的数据。
每一行生成一个rowArrayList集合,所有行组成一个allArrayList集合。
1.2. 对allArrayList集合进行遍历存储
Map<String,String> mapExcel = new HashMap<String,String>;
对allArrayList集合进行遍历。
遍历每个rowArrayList的偶数元素得到指标编号。
将得到的指标编号到mapExcel集合中看看能不能找到对应的指标名称,若是找到对应的指标名称,说明在mapExcel中已经存在且已经存到数据库中了,就不进行存储了。若是找不到就是要存储的数据。存储到mapExcel集合以及数据库中。
存储的时候也是要分是否为第0列的数据,若是第0列,parentId为-1。若不是第0列,parentId为父节点主键Id。
2. 代码实现
2.1.将前端上传的Excel文件拷贝到服务器上
这是controller层,主要是将前端传来的文件复制到服务器上,并且将界面返回到Excel上传模板的模态框上。
2.1.1. 得到上传文件的文件名,后边拼接时间跟“.xlsx”;
String tempFileName = uploadExcel.getOriginalFilename()+DateBuilder.getTimeFormatToSecCompact()+".xlsx";
2.1.2. 得到上传文件的路径;
String realPath = req.getSession().getServletContext().getRealPath("/");
2.1.3. 编辑要存放到服务器上的Excel文件夹的路径;
2.1.3.1. 判断Excel文件夹是否存在,不存在就新建Excel文件夹;
String excelFolderPath = realPath + "/excelfolder"; // 存放Excel模板的文件夹
File excelFolder = new File(excelFolderPath);
// 判断excelFolder文件夹是否存在,如果不存在就新建文件
if(!excelFolder.exists()) {
excelFolder.mkdirs();
}
2.1.4. 得到服务器上文件的全路径+文件名;
String finalFullFileName = realPath + "/excelfolder/"+tempFileName;
2.1.5. 将文件复制到服务器的响应的文件夹下
File srcFile = new File(finalFullFileName);
is = uploadExcel.getInputStream();
FileCopyUtils.copy(FileCopyUtils.copyToByteArray(is), srcFile);
2.1.6. 整体代码如下:
/**
* excel模板上传解析
* @param uploadExcel 上传的Excel文件
* @param req
*/
@RequestMapping(value = "/uploadTemplate", method = RequestMethod.POST)
public ModelAndView uploadTemplate(@RequestParam("uploadExcel") MultipartFile uploadExcel,HttpServletRequest req) {
//首先进行文件拷贝
Map<String, Object> map = new HashMap<>();
InputStream is = null;
try {
//打开模板
//获取到模板的相对路径
String tempFileName = uploadExcel.getOriginalFilename()+DateBuilder.getTimeFormatToSecCompact()+".xlsx";
String realPath = req.getSession().getServletContext().getRealPath("/");
String excelFolderPath = realPath + "/excelfolder"; // 存放Excel模板的文件夹
String finalFullFileName = realPath + "/excelfolder/"+tempFileName;
File excelFolder = new File(excelFolderPath);
// 判断excelFolder文件夹是否存在,如果不存在就新建文件
if(!excelFolder.exists()) {
excelFolder.mkdirs();
}
File srcFile = new File(finalFullFileName);
is = uploadExcel.getInputStream();
FileCopyUtils.copy(FileCopyUtils.copyToByteArray(is), srcFile);
map = iotEvaluationIndicatorTemplateService.parseExcel(finalFullFileName,indicatorClassIdForExcel);
map.put("indicatorClassId",indicatorClassIdForExcel);
} catch (FileNotFoundException e) {
log.error("文件未找到!",e);
map.put("messageDicHerbal", "数据上传失败!文件未找到!"+e.getMessage());
} catch (IOException e) {
log.error("",e);
map.put("messageDicHerbal", "数据上传失败!IO读写错误!"+e.getMessage());
} catch (Exception e) {
log.error("",e);
map.put("messageDicHerbal", "数据上传失败!未知异常"+e.getMessage());
} finally{
try{
is.close();
}catch(IOException e){
}
}
return new ModelAndView(TO_EXCEL_MODEL_PAGE, map);
}
2.2. 对服务器上的文件进行遍历
主要是为了生成allArrayList<rowArrayList<String,String>>集合。
跳转到service层进行事务的处理,参数为服务器上文件的根路径。
2.2.1. 对合并单元格的值的处理的工具类
package com.common.tool.excel;
import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
//获得Excel单元格数据的工具类
public class PoiMergedCell {
/**
* 判断单元格是否为合并单元格,是的话则将单元格的值返回
* @param cell 需要判断的单元格
* @param sheet sheet 需要判断的工作表
* @return
*/
public String getCellValue(Cell cell,Sheet sheet)
throws Exception{
int firstC = 0;
int lastC = 0;
int firstR = 0;
int lastR = 0;
String cellValue = null;
List<CellRangeAddress> craList = sheet.getMergedRegions();
// 判断此单元格是否为合并单元格
if(isMergedRegion(sheet,cell)) {
// 如果是合并单元格,就将合并的单元格进行遍历,得到此单元格的值
for(CellRangeAddress ca:craList){
//获得合并单元格的起始行, 结束行, 起始列, 结束列
firstC = ca.getFirstColumn();
lastC = ca.getLastColumn();
firstR = ca.getFirstRow();
lastR = ca.getLastRow();
if(cell.getRowIndex() >= firstR && cell