前言
本文主要介绍的是利用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.pluginsorg.eclipse.wst.server.coretmp0wtpwebappsApartProj1.0fileschange.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腾讯技术创作特训营最新征文,快来和我瓜分大奖!