Spring Boot+poi实现excel文件上传、下载

阅读: 评论:0

Spring Boot+poi实现excel文件上传、下载

Spring Boot+poi实现excel文件上传、下载

Spring Boot+poi实现excel文件上传、下载

最近为了实现excel文件上传与下载找了很多的代码,可总有一些写的不是很完整而且用的方法也特别多(感受到了代码的强大),所以我决定综合资料自己做出来后也保存一份下来(亲测有效?)

1.poi介绍

Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。

开始整合spring boot+poi

1.第一步还是照旧添加poi的依赖

<!-- 文件上传与下载 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>RELEASE</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>RELEASE</version></dependency>

2.编写实体类

ity;import batisplus.annotation.IdType;
import batisplus.annotation.TableId;
import lombok.Data;
perimental.Accessors;import java.util.Date;/*** <p>*/
@Data
@Accessors(chain = true)
public class User {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.AUTO)private Integer id;private String name;private Integer age;private Date date;private Boolean type;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Boolean getType() {return type;}public void setType(Boolean type) {pe = type;}public void setDate(Date date) {this.date = date;}public Date getDate() {return date;}
}

/**** 存储错误数据实体类*/
@Data
public class ErrorUserDto {/*** 参数错误信息*/private String message;/*** 参数所在表格行数*/private Integer lineId;
}

3. 编写上传需要用的工具类


st.demo.support;stant.ExcelUtilConstant;
slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.IOException;
import java.io.InputStream;
ParseException;
SimpleDateFormat;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;/*** @program:* @description: 将excel文件转为user对象* @create: 2019-02-26 10:44**/
@Slf4j
public class POISupport {private static String columns[] = { ExcelUtilConstant.DATA_NAME,ExcelUtilConstant.DATA_AGE,ExcelUtilConstant.DATA,ExcelUtilConstant.DATA_TYPE};public static List<Map<String, Object>> readExcel(InputStream inputStream) throws ParseException, IOException {Workbook wb = new XSSFWorkbook(inputStream);;Sheet sheet;//用来存放表中数据List<Map<String, Object>> list = new ArrayList<>();Object cellData;if (wb != null) {//获取第一个sheetsheet = wb.getSheetAt(0);//获取最大行数int rownum = PhysicalNumberOfRows();//获取第一行Row row;for (int i = 1; i < rownum; i++) {Map<String, Object> map = new LinkedHashMap<String, Object>();row = Row(i);if (row != null) {for (int j = 0; j < columns.length; j++) {//CellType() != CellType.BLANK 判断字段是否为空,根据需求而加if (Cell(j) != null && !Cell(j).equals("")) {cellData = formatValueType(columns[j], Cell(j));map.put(columns[j], cellData);}}if (!map.isEmpty()) {list.add(map);}} else {continue;}}}return list;}//转换单元格类型为java类型public static Object getCellFormatValue(Cell cell) {Object cellValue = null;if (cell != null || CellType() != CellType.BLANK) {//判断cell类型CellType() == CellType.NUMERIC){if (DateUtil.isCellDateFormatted(cell)) {//转换为日期格式YYYY-mm-ddSimpleDateFormat sdf = new SimpleDateFormat(ExcelUtilConstant.DATE_FORMAT);cellValue = sdf.DateCellValue());} else {//数字cellValue = (int) NumericCellValue();}} else CellType() ==  CellType.FORMULA ){//数字cellValue = String.NumericCellValue());} else CellType() == CellType.STRING){cellValue = RichStringCellValue().getString();}} else {cellValue = "";}return cellValue;}//根据业务对象属性类型转换单元格值数据类型public static Object formatValueType(String columnName, Cell cell) throws ParseException {Object cellData;cellData = getCellFormatValue(cell);return cellData;}
}
public class ExcelUtilConstant {private ExcelUtilConstant(){}/*** xls表格格式*/public static final  String EXCEL_FORMAT_XLS=".xls";/*** xlsx表格格式*/public static final String EXCEL_FORMAT_XLSX=".xlsx";public static final String DATE_FORMAT = "yyyy-MM-dd";public static final String DATE_HOUR_MINUTE_SECOND = "yyyy-MM-dd HH:mm:ss";/*** User对象字段名,用于获取表格数据*/public static  final String DATA_NAME ="name";public static  final String DATA_AGE ="age";public static  final String DATA = "date";public static  final String DATA_TYPE = "type";
}

4.之后就是使用工具类完成上传与下载

/**** 将上传的excel文件信息添加进数据库* @param file* @return*/@RequestMapping("/excel/upload")public StringBuffer fileUpload(@RequestParam("file") MultipartFile file){StringBuffer msg = new StringBuffer();List<ErrorUserDto> errorList = new ArrayList<>();if (!file.isEmpty()) {try {List<Map<String, Object>> list = InputStream());//解析数据并放回错误信息。再上传过程中有发现错误的数据将进行保存errorList = transferAndInsert(list);if (errorList.size() > 0) {//将保存的错误数据进行返回createExcel(errorList);msg.append("部分导入成功,失败数据已生成excel文件");} else {msg.append("全部导入成功");}} catch (ParseException e) {msg.append("excel转换异常");} catch (Exception e) {msg.append("文件传输异常");}} else {msg.append("传入文件为空");}return msg;}

在解析数据之后,可以根据自己的需求添加一些判断或者其他业务操作

/*** 将表格中的数据转换为vehicle并插入数据库** @param list* @return*/private List<ErrorUserDto> transferAndInsert(List<Map<String, Object>> list) throws ParseException {List<ErrorUserDto> errorList = new ArrayList<>();if (list.size() > 0) {List<User> userListMap = new ArrayList<>();for (Map<String, Object> map : list) {userListMap.add(JSON.JSONString(map), User.class));}User user;List<User> userList = new ArrayList<>();for (int i = 0; i < userListMap.size(); i++) {ErrorUserDto errorUserDto = new ErrorUserDto();user = (i);if (Age() == null) {pyProperties(user, errorUserDto);errorUserDto.setMessage("年龄不能为空");errorUserDto.setLineId(i + 2);errorList.add(errorUserDto);continue;}userList.add(user);}userService.saveBatch(userList);}return errorList;}

5.上传之后可能会产生一些错误的数据,比如字段为空之类的。可以把错误数据保存起来,再生成一个excel下载出来。

/**** 下载错误数据到本地* @param errorList*/public void createExcel(List<ErrorUserDto> errorList) {// 第一步,创建一个webbook,对应一个Excel文件HSSFWorkbook hssfWorkbook = new HSSFWorkbook();// 第二步,在webbook中添加一个sheet,对应Excel文件中的sheetHSSFSheet sheet = ateSheet("测试表");sheet.setDefaultColumnWidth(20);// 默认列宽// 第三步,在sheet中添加表头第0行HSSFRow hssfRow = ateRow(0);//创建表头String[] headers = {"错误行数", "错误描述"};HSSFCell cell = null;for (int i = 0; i < headers.length; i++) {cell = ateCell(i);cell.setCellValue(headers[i]);}// 第四步,写入实体数据 实际应用中这些数据从数据库得到,list中字符串的顺序必须和数组strArray中的顺序一致for (int i = 0; i < errorList.size(); i++) {ErrorUserDto errorUserDto = (i);if (errorUserDto == null) {continue;}HSSFRow row = ateRow(i + 1);ateCell(0).setCellValue("第" + LineId() + "行");ateCell(1).setCellValue("错误为:" + Message());}// 第五步,将文件存到指定位置try {//获取精确到毫秒的时间戳作为保存后的文件名String name = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());//下载指定位置,使用时间戳当作文件名String path = "D:/" + name + ".xls";File file = new File(path);FileOutputStream fout = new FileOutputStream(file);hssfWorkbook.write(fout);fout.close();} catch (Exception e) {e.printStackTrace();}}

6.再excel表里面输入以下数据,可以看到第二行的性别是空的(也就是错误的数据)

使用postman进行测试,然后输出结果并将错误数据重新生成excel表格:

然后我们查一下数据库跟下载的错误信息,成功加入两条,并生成错误信息的excel

错误信息excel表格

最后,可能我写的有些不清楚或者不完整的地方还请海涵。

本文发布于:2024-01-27 22:24:33,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063654722998.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:文件上传   Boot   Spring   excel   poi
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23