POI获取树结构的Excel数据并存储到数据库中

该博客介绍了如何从Excel文件中读取数据并进行处理,特别是处理合并单元格的情况。首先,通过遍历Excel表格获取每个单元格的值,特别关注合并单元格的值。然后,将数据存储到一个二维ArrayList中,再遍历这个ArrayList,利用HashMap检查指标编号对应的指标名称,决定是否存储到数据库。最后,分析存储过程,更新或插入数据库记录,同时跟踪成功和失败的数量。
摘要由CSDN通过智能技术生成

获取如图所示的Excel数据

如图所示的Excel数据

1.设计思路

1.1. 得到每一个单元格的值

List rowArrayList = new ArrayList;
List<ArrayList> allArrayList = new ArrayList<ArrayList>;
遍历Excel表格的所有行,第0行用来判断一共有多少列。将所有行存放到allArrayList集合中。
遍历Excel表格除0行外的所有行,得到每行的每一个单元格。
得到的单元格可能是合并的单元格。若要得到合并单元格的值,首先得到所有合并的单元格进行遍历,判断此单元格是否在合并单元格,然后得到该合并单元格的数据。
依此类推,得到每一个单元格的数据。
每一行生成一个rowArrayList集合,所有行组成一个allArrayList集合。
Excel展开

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值