前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >POI解析Excel文件并利用SpringMVC上传下载

POI解析Excel文件并利用SpringMVC上传下载

原创
作者头像
小明爱吃火锅
发布2024-05-02 21:40:11
2110
发布2024-05-02 21:40:11
举报
文章被收录于专栏:小明说Java

前言​

本文主要介绍的是利用POI技术解析Excel文件,包括将Excel文件封装成一个实体对象List和将实体对象List转换文Excel文件 ,本人也是多次会用了POI技术和SpringMVC上传下载技术,下面是详细介绍。

案例实操

1、POI解析Excel文件并文件上传

前端jsp页面通过表单编写,代码如下:

代码语言:javascript
复制
<form class="form-horizontal" action="${App_Path }/busStationController/importBetch"
						method="post"
						enctype="multipart/form-data" id="formobj">
				<div class="form-group">
							<label class="col-sm-2 control-label">选择文件</label>
							<div class="col-sm-8">
								<input type="file" name="file" class="layui-input">
							</div>
						</div>
					
					
				
</form>

后台在控制层通过SpringMVC的MultipartFile 进行获取。主要的思路:

1.获取前端表单上传的文件,获取文件名getOriginalFilename(),判断是否是Excel文件 2.1不是Excel文件,直接返回提示信息 2.2是Excel文件,由于浏览器不能显示文件的绝对路径,所以将文件上传保存在本地的另一个位置 3.创建上传目录 realpath="D:/uploadExcel"(如果目录不存在)

4.将上传文件保存在上传目录中new File(realpath,fileName)

5.执行上传操作file.transferTo(targetFile); 6.完毕,上传文件被统一放在上传目录中

为什需要要先执行文件上传呢?

由于浏览器不能显示文件的绝对路径,所以将文件上传保存在本地的另一个位置,而导入系统需要全路径才能获取得到该文件。

代码语言:javascript
复制
/**
	 * 执行批量操作实际上是上传操作,批量保存
	 * @param file
	 * @param request
	 * @return
	 */
	@RequestMapping("/importBetch")
	@ResponseBody
	public void ExcelInport(@RequestParam("file") MultipartFile file,HttpServletRequest request) {
		// 1.获取前端表单上传的文件,获取文件名getOriginalFilename(),判断是否是Excel文件
		String fileName = file.getOriginalFilename();
		System.out.println(fileName);
		// * 2.1不是Excel文件,直接返回提示信息
		if (!(fileName.contains("xls") || fileName.contains("xlsx"))) {
			// 格式错误
			//return "error";
		}

		// * 2.2是Excel文件,由于浏览器不能显示文件的绝对路径,所以将文件上传保存在本地的另一个位置
		// * 3.创建上传目录 realpath="D:/uploadExcel"(如果目录不存在)
		String realpath = request.getSession().getServletContext().getRealPath("/");
		System.out.println(realpath);
		// * 2.2是Excel文件,由于浏览器不能显示文件的绝对路径,所以将文件上传保存在本地的另一个位置
		// * 3.创建上传目录 realpath="D:/uploadExcel"(如果目录不存在)
		//String realpath = "D:/uploadExcel";
		File targetDir = new File(realpath+"/uploadExcel");
		if (!targetDir.exists()) {
			targetDir.mkdirs();
			System.out.println("不存在目录");
		}
		// * 4.将上传文件保存在上传目录中new File(realpath,fileName)
		File targetFile = new File(realpath+"/uploadExcel", fileName);
		// * 5.执行上传操作file.transferTo(targetFile);
		// 上传操作
		try {
			file.transferTo(targetFile);
		} catch (Exception e) {
			// TODO: handle exception
			// 导入错误
			//return "error";
		}
		// * 6.完毕,上传文件被统一放在上传目录中
		// * 执行导入系统操作
		// * 1.在上传目录中根据fileName,拼装成绝对路径
		String inportpath = realpath+"/uploadExcel" + "/" + fileName;
		System.out.println(inportpath);
		// * 2.调用InportExcelTool的loadScoreInfo方法执行导入数据库
		int xlBusStationLen=XlBusStationService.selectAll().size();
		InportExcelTool inportExcelTool = new InportExcelTool();
		List<XlBusStation> xlBusStations;
		try {
			// 导入站点信息Excel表
			xlBusStations = inportExcelTool.loadBusSationInfo(inportpath,xlBusStationLen);
		
			// 2.0将站点信息插入数据库,批量插入数据
			long a=System.currentTimeMillis();
					
			for (XlBusStation xlBusStation : xlBusStations) {
				System.out.println(xlBusStation.getId());
			}
			XlBusStationService.insertBacth(xlBusStations);
		
			long b=System.currentTimeMillis();
			System.out.println("批量");
			System.out.println(b-a);
			
		/*	效率很慢 可以说是批量插入的70倍
		 * long c=System.currentTimeMillis();
			for (XlBusStation xlBusStation : xlBusStations) {
				XlBusStationService.insert(xlBusStation);
			}
			long d=System.currentTimeMillis();
			System.out.println("单条");
			System.out.println(c-d);*/
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			//return "error";
			// 插入失败
		}

		//return "redirect:superervorPage";
	}

文件上传完毕之后,执行导入系统操作

1.在项目上传目录中根据fileName,拼装成绝对路径 2.利用POI技术将文件解析,即loadBusSationInfo(inportpath,xlBusStationLen)函数,并且封装成list,执行批量导入操作,本次是使用mybatis的foreach操作。

代码语言:javascript
复制
/**
	 * 加载Excel表中的数据,封装成一个List
	 * @param xlsPath 需要导入的Excel文件
	 * @return
	 * @throws IOException
	 */
	public List<XlBusStation> loadBusSationInfo(String xlsPath,int xlBusStationLen) throws IOException {
		List<XlBusStation> xlBusStations = new ArrayList<XlBusStation>();
		FileInputStream fileIn = new FileInputStream(xlsPath);
		// 根据指定的文件输入流导入Excel从而产生Workbook对象
		Workbook wb0 = new HSSFWorkbook(fileIn);
		// 获取Excel文档中的第一个表单
		Sheet sht0 = wb0.getSheetAt(0);
		// 对Sheet中的每一行进行迭代
		for (Row r : sht0) {
			// 如果当前行的行号(从0开始)未达到2(第三行)则从新循环
			if (r.getRowNum() < 1) {
				continue;
			}
			// 创建实体类,即每一行就是一行Student对象
			XlBusStation xlBusStation = new XlBusStation();
			// 将单元赋值给对象属性,避免报错,将Excel单元格都先转换成String,即setCellType(Cell.CELL_TYPE_STRING);
		//	System.out.println(r.getRowNum());

			//保存站点固定基本信息
			//设置id
			xlBusStation.setId(BillCodeUtil.generateBillCode());
			xlBusStation.setStationCode(BillCodeUtil.generateBillCode_mark(xlBusStationLen++));
			//保存站点审核状态,默认为待审核1 审核通过2 审核不通过3
			xlBusStation.setStatus("1");
			//设置数据状态,0:未删除,1:表示删除
			xlBusStation.setDataStatus("0");
			xlBusStation.setComefrom("Excel");
			
			//从表格中读取单元格数据
			//只保存 站点名称		站点简称	上行GPS	下行GPS	途经路段	所在路段	备注	创建时间	更新时间	
			r.getCell(0).setCellType(Cell.CELL_TYPE_STRING);
			xlBusStation.setStationName(r.getCell(0).getStringCellValue());
			r.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
			xlBusStation.setSiteShort(r.getCell(1).getStringCellValue());
			r.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
			xlBusStation.setSiteLongItude(r.getCell(2).getStringCellValue());
			r.getCell(3).setCellType(Cell.CELL_TYPE_STRING);
			xlBusStation.setSiteLatItude(r.getCell(3).getStringCellValue());
			r.getCell(4).setCellType(Cell.CELL_TYPE_STRING);
			xlBusStation.setByWay(r.getCell(4).getStringCellValue());
			r.getCell(5).setCellType(Cell.CELL_TYPE_STRING);
			xlBusStation.setRoadSection(r.getCell(5).getStringCellValue());
		
			//加入到list中
			xlBusStations.add(xlBusStation);
		}
		fileIn.close();
		return xlBusStations;
	}

2、文件下载并POI封装Excel文件

利用SpringMVC的ResponseEntity的进行下载操作, 首先数据保存到本地web应用目录中即指定文件文件下,之后客户端直接下载,之后通过输入流,将该文件读入,并且激活下载器下载文件。

HttpHeaders headers = new HttpHeaders(); // 激活下载器Content-Disposition,filename为默认下载文件名 headers.add("Content-Disposition", "attachment;filename=exportfile.xls");

HttpStatus status = HttpStatus.OK;

ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(body, headers, status);

代码语言:javascript
复制
/**
	 * 直接点击按钮下载 利用ResponseEntity实现文件下载
	 * 1.先将站点信息保存到本地web应用目录中即/exportfiles/exportfile.xls文件下,之后客户端直接下载
	 * 
	 * @param session
	 * @return
	 * @throws IOException
	 */
	@RequestMapping("/exportBusStation")
	public ResponseEntity<byte[]> exportBusStation(HttpServletRequest request) throws IOException {

		// 1.获取缴费记录表,保存在web应用下载的files文件中
		List<XlBusStation> xlBusStations = XlBusStationService.selectBydataStatus("0");

		// 获取缴费记录表,记录表会保存在服务器中
		ExportExcelTool exportExcelTool = new ExportExcelTool();
		exportExcelTool.exportExcelBusStation(xlBusStations.size(), xlBusStations, request);

		byte[] body = null;
		// 获取web应用的根目录,获取可被下载的文件的路径
		String realPath = request.getSession().getServletContext().getRealPath("/");
		//获取服务器已经存在的文件(实际已经保存在web项目路径)
		File file = new File(realPath+"/exportfiles/exportfile.xls");
		
		// 文件以及缓存在/exportfiles/exportfile.xls,直接下载
		InputStream in =new FileInputStream(file);//读入文件
		//InputStream in = servletContext.getResourceAsStream("/exportfiles/exportfile.xls");
		body = new byte[in.available()];
		in.read(body);

		HttpHeaders headers = new HttpHeaders();
		// 激活下载器Content-Disposition,filename为默认下载文件名
		headers.add("Content-Disposition", "attachment;filename=exportfile.xls");

		HttpStatus status = HttpStatus.OK;

		ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(body, headers, status);
		return responseEntity;
		// return null;
	}

exportExcelBusStation(xlBusStations.size(), xlBusStations, request);方法实现,主要是将list封装成Excel文件格式。

代码语言:javascript
复制
public  void exportExcelBusStation(int rowAll,List<XlBusStation> xlBusStations,HttpServletRequest request) throws IOException{
			

			//获取项目全路径
			//path:G:\webCode\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\ApartProj1.0\files\change.xls
			String realPath = request.getSession().getServletContext().getRealPath("/");
			System.out.println(realPath);
			
			//保存在类路径下的files
			File file = new File(realPath+"/exportfiles/exportfile.xls");
		
			if(!file.getParentFile().exists()){
				file.getParentFile().mkdirs();
			}
		
			//如果文件不存在
			if(!file.exists()){
				
				file.createNewFile();
				System.out.println("创建了");
			}
			String path  = file.getPath();
				// 创建一个空Excel表
				HSSFWorkbook workbook = new HSSFWorkbook();
				
				// 创建一个sheet
				HSSFSheet sheet = workbook.createSheet("站点信息表");
				// 创建第一行
				HSSFRow row0 = sheet.createRow(0);
				
				// 创建表头
				//dorm_number  month       ele_qua  ele_charge  warter_qua  warter_charge  pay
				HSSFCell cell0=row0.createCell(0);
				cell0.setCellValue("站点名称");
				HSSFCell cell1=row0.createCell(1);
				cell1.setCellValue("审核状态");
				HSSFCell cell2=row0.createCell(2);
				cell2.setCellValue("站点编号");
				HSSFCell cell3=row0.createCell(3);
				cell3.setCellValue("站点简称");
				HSSFCell cell4=row0.createCell(4);
				cell4.setCellValue("上行GPS");
				HSSFCell cell5=row0.createCell(5);
				cell5.setCellValue("下行GPS");
				HSSFCell cell6=row0.createCell(6);
				cell6.setCellValue("途经路段");
				HSSFCell cell7=row0.createCell(7);
				cell7.setCellValue("所在路段");
				HSSFCell cell8=row0.createCell(8);
				cell8.setCellValue("备注");
				HSSFCell cell9=row0.createCell(9);
				cell9.setCellValue("创建时间");
			
				
				//逐条插入数据,students就相当一个文件,List中的每一个值就表示一行
				for (int i=0;i<xlBusStations.size();i++) {
					HSSFRow row = sheet.createRow(i+1);// 创建行数,从第二行开始
						// 插入数据
						HSSFCell cellBusStation0=row.createCell(0);
						cellBusStation0.setCellValue(xlBusStations.get(i).getStationName());
						HSSFCell cellBusStation1=row.createCell(1);
						cellBusStation1.setCellValue(xlBusStations.get(i).getStatus());
						HSSFCell cellBusStation2=row.createCell(2);
						cellBusStation2.setCellValue(xlBusStations.get(i).getStationCode());
						HSSFCell cellBusStation3=row.createCell(3);
						cellBusStation3.setCellValue(xlBusStations.get(i).getSiteShort());
						HSSFCell cellBusStation4=row.createCell(4);
						cellBusStation4.setCellValue(xlBusStations.get(i).getSiteLongItude());
						HSSFCell cellBusStation5=row.createCell(5);
						cellBusStation5.setCellValue(xlBusStations.get(i).getSiteLatItude());
						HSSFCell cellBusStation6=row.createCell(6);
						cellBusStation6.setCellValue(xlBusStations.get(i).getByWay());
						HSSFCell cellBusStation7=row.createCell(7);
						cellBusStation7.setCellValue(xlBusStations.get(i).getRoadSection());
						HSSFCell cellBusStation8=row.createCell(8);
						cellBusStation8.setCellValue(xlBusStations.get(i).getVnote());
						HSSFCell cellBusStation9=row.createCell(9);
						cellBusStation9.setCellValue(xlBusStations.get(i).getCreateDate());
				
				}
				System.out.println("path:"+path);
				FileOutputStream out=null;
				try{
					//创建输出流,
					out =new FileOutputStream(path);
					//写入workbook中
					workbook.write(out);
				}catch(Exception e){
					e.printStackTrace();
				}finally {
					try {
						out.close();
					} catch (Exception ex) {
						System.out.println(ex.toString());
					}
				}

		}

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言​
  • 案例实操
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档