java POI读取excel,并导入数据库

该博客介绍了如何使用Apache POI库来读取Excel文件,并将其数据批量导入到对应的数据库表中。通过创建一个公共的ExcelReadUtil类,包含抽象方法用于对象封装和数据库插入,子类根据具体表结构实现这些方法,实现了不同Excel到不同数据库表的映射。在Controller层调用这些方法,完成文件上传并处理。
摘要由CSDN通过智能技术生成

功能实现:一个controller接口读取不同的excel,并导入到对应的数据库表中(一张excel表对应一张数据库表)。
方案:用POI工具,抽取导入公共类(ExcelReadUtil),不同的数据库导入,都继承这个公共类中的抽象类excelReadTemplate,实现抽象类中的packageObject(封装实体类)与insertObject(批量插入)方法。
具体实现

  1. jar包引入
<dependency>
	<groupId>org.apache.poi</groupId>
	<arrtifactId>poi</artifactId>
	<vesion>4.0.1</version>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>4.0.1</version>
</dependency>
  1. 编写公共类 ExcelReadUtil
public class ExcelReadUtil {
	public abstract static class ExcelReadTemplate{
		/**
		* 处理每一行数据,封装为实体类
		* beginCell:从当前行的第beginCell列开始读取
		* row:行对象
		**/
		protected abstract ResponseVo PackageObject(int beginCell,Row row);
		/**
		*将对象集合插入到数据库中
		**/
		protected abstract boolean insertObject(List list);
	}
		/**
		*beginRow:开始读取行数
		*beginCell:开始读取列数
		**/	
		public final ResponseVo execute(MultipartFile file,int beginRow,int beginCell){
			InputStream fileInputStream = null;
			try{
				fileInputStream = file.getInputStream();//文件流
				//这种方式2003/2007/2010版本都是可以处理的
				Workbook workbook = WorkbookFactory.create(fileInputStream);
				int sheetCount = worbook.getNumberOfSheets();//sheet页的数量
				for(int i = 0; i < sheetCount; i++){
					Bookean isShow = workbook.isSheetHidden(i);//判断当前页是否是隐藏页
					if(isShow){
						continue;
					}
					Sheet sheet = workbook.getSheetAt(i);
					// sheet.setForceFormlaRecalculation(true);
					int rowCount = sheet.getPhysicalNumberOfRows();//获取当前sheet页的总行数
					if(rowCount==0{
						continue;
					}
					//遍历每一行
					List list = new ArrayList();
					for(int j = beginRow; j < rowCount; j++){
						Row row = sheet.getRow(j); // 当前行对象
						if(isRowEmpty(row)){  //isRowEmpty()方法是判断当前行是否为空行
							continue;
						}
						//int cellCount = row.getPhysicalNumberOfCells();//获取当前行的总行数
						ResponseVo responseVo = pacekgetObject(beginCell, row);
						list.add(responseVo.getData());
					}
					insertObject(list);//批量插入
				}
			}catch(Exception e){
				return ResponseVo.error("插入数据库失败”);
			}finally{
				if(fileInputStream != null){
					try{
						fileInputStream .close();
					}catch(IOException e){
						e.printStackTrace();
					}
				}
			}
			return ResponseVo.success();
		}

		/**
		* excel 文件单元格格式转换
		 */
		public static String formatConversion(Cell cell){
			SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
			String cellValue = "";
			if(ObjectUtils.isEmpty(cell)){
				return null;
			}
			CellType celltype = cell.getCellTypeEnum();
			//把数据当成String来读,避免出现1读成1.0的情况
			if(cellType == Celltype.NUMERIC){
				cell.setCellType(CellType.STRING);
			}
			cellType = cell.getCellTypeEnum();
			//判断数据的类型
			switch (cellType){
				case NUMERIC : //数字/日期
					if(DateUtil.isCellDateFormatted(cell){
						cellValue = fmt.format(cell.getDateCellValue())
					}else{
						cellValue = String.valueOf(cell.getStringCellVuale());
						if(cellValue .contains("E")){//是否包含字符串E
							cellValue = String.valueOf(new Double(cell.getNumericCellvalue()).longValue());
						}
					}
					break;
				case STRING: //字符串
					cellValue = String.valueOf(cell.getStringCellValue());
					break;
				case BOOLEAN: //boolean
					cellValue = String.valueOf(cell.getBooleanCellValue());
					break;
				case FORMULA: //公式
					try{
						cellValue = cell.getNumericCellValue()+"";
					}catch(IllegalStateException e){
						cellValue = cell.getStringCellValue();
					}
					break;
				case BLANK: //空值
					cellValue = cell.getStringValue();
					break;
				case ERROR : //故障
					cellValue = "非法字符";
					break;
				default:
					cellValue = "未知类型";
					break;
			}
			return cellValue ;
		}
		
		/**
		*判断是否是空行
		*/
		public static boolean isRowEmpty(Row row){
			for(int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++){
				Cell cell = row.getCell(c);
				if(cell!=null && cell.getCellType()!=Cell.CELL_TYPE_BLANK){
					return false;
				}
			}
			return true;
		}
}
  1. 编写某一张表的导入
	public class TestClassExcelRead extends ExcelReadTemplate{
		@Autowired
		TestClassMapper testClassMapper;
		@Override
		protected ResponseVo packageObject(int beginCell, Row row){
			TestClass testClass = new TestClass();
			testClass .setName(formatConversion(row.getCell(beginCell)));
			testClass .setage(formatConversion(row.getCell(++beginCell)));//取下一个单元格的值;
			return RespinseVo.success(testClass);
 		}
		
		@Override
		protected boolean insertObject(List list){
			return testClassMapper.insertList(list);//批量插入数据库的方法没写,
		}
	}
  1. controller层
public class ExcleReadController{
	@Autowired
	TestClassExcelRead testClassExcelRead ;
	
	@PostMapping("/excleRead/v1")
	public ResponseVo fileUpload(@RequestParam MultipartFile file){
		ResponseVo responseVo =	testClassExcelRead.execute(file,3,1);//从第4行第2列开始读取
		return responseVo;
	}
}
  1. ResponseVo 类是统一的返回实体类
public class ResponseVo <T> implements Serializable{
	private String final long serialVersionUID = -5454646446459978;
	private Integer retCode = 200;
	private String retMsg = "成功";
	private T data;
	// get set 方法
	private ResponseVo {}
	private ResponseVo (Integer retCode,String retMsg){
		this.retCode = retCode;
		this.retMsg = retMsg;
	}
	private ResponseVo (Integer retCode,String retMsg,T data){
		this.retCode = retCode;
		this.retMsg = retMsg;
		this.data = data;
	}
	//失败
	private static<T> ResponseVo<T> error(T data){
		return ResponseVo<T>(500,"失败",data);
	}
	//成功
	private static<T> ResponseVo<T> success(){
		return ResponseVo<T>(200,"成功");
	}
	private static<T> ResponseVo<T> success(T data){
		return ResponseVo<T>(200,"成功",data);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值