一、需要读取的Excel表格格式相对完整工整,且只需要写入一张表中

    在读取Excel表格的需求中,有像下图的这么一种表格,它的格式工整,且表格中的列名和数据库表中的列名一一对应,如下图:

Excel表:

数据库表:

    此时就需要用到下面的方法。

1、引入依赖

org.apache.poi

poi

RELEASE

org.apache.poi

poi-ooxml

RELEASE

commons-io

commons-io

2.13.0

2、创建实体类

@Data

@TableName("test")

public class TestDto {

@ExcelImport("id")

private String id;

@ExcelImport("username")

private String username;

@ExcelImport("password")

private String password;

}

3、导入Excel相关的工具类

      创建exceIUtil包,并导入ExcelClassField、ExcelExport、ExcelImport和ExcelUtils工具类。

4、创建Mapper接口

public interface TestMapper extends BaseMapper {

}

5、创建Service接口及它的实现类

public interface TestService extends IService {

void add(TestDto testDto);

}

public class TestServiceImpl extends ServiceImpl implements TestService {

public void add(TestDto testDto) {

super.save(testDto);//加入数据库中

}

}

6、编写Controller类

@PostMapping("/GetExcel")

public Result GetExcel(@RequestParam("file") MultipartFile file) throws Exception {

List testDtos = ExcelUtils.readMultipartFile(file, TestDto.class);

for (TestDto testDto : testDtos) {

testService.add(testDto);

}

return Result.success(testDtos, "导入成功");

}

7、具体实现

二、需要读取的Excel表格格式固定有规律,且需要写入多张表中

    在读取Excel表格的需求中,有一种表格它的格式固定且有规律,一张表格中有写入多张数据库表格的需求,如下图:

    在上图的表格中,我们需要在数据库中写入站点配置、车道配置、枪机配置等三张表的数据,且车道配置、枪机配置表的行数随着站点配置中的车道数量的变化而变化,此时就需要用到下面的方法。

1、引入依赖

    详见第一种方法。

2、创建实体类

    因为需要写入多张表中,所以需要创建多个实体类。且这些属于重复性操作,所以以下我就以写入两张表作为示例。

实体类1:

@Data

@TableName("tri_zd_stationinfo")

public class stationinfo {

@ExcelImport("站点id")

private Integer id;

@ExcelImport("站点名称")

private String station_name;

@ExcelImport("业务类型")

private String business_type;

@ExcelImport("站点位置")

private String station_position;

@ExcelImport("安装日期")

private Date install_date;

@ExcelImport("摄像枪品牌类型")

private Integer capture_brand;

@ExcelImport("车道数量")

private Integer lane_count;

}

实体类2:

@Data

@TableName("tri_zd_laneinfo")

public class laneinfo {

private Integer station_id;

@ExcelImport("车道号")

private Integer laneid;

@ExcelImport("仪表ip")

private String ip;

}

3、导入Excel相关的工具类

    详见第一种方法。

4、创建Mapper接口

Mapper接口1:

public interface ExcelStationMapper extends BaseMapper {

}

Mapper接口2:

public interface ExcelLaneMapper extends BaseMapper {

//根据你的业务需求写代码,这里有删除旧数据/重复数据的需求

@Delete("delete from tri_zd_laneinfo where station_id = #{station_id};")

int delByStation_id (int station_id);

}

5、创建Service接口及它的实现类

Service接口及其实现类1:

public interface ExcelStationService extends IService {

void delByStation_id(stationinfo stationinfo);

void add(stationinfo stationinfo);

}

@Service

public class ExcelStationImpl extends ServiceImpl implements ExcelStationService {

@Autowired

ExcelStationMapper excelStationMapper;

public void delByStation_id(stationinfo stationinfo){

excelStationMapper.deleteById(stationinfo.getId());

}

@Override

public void add(stationinfo stationinfo) {

super.save(stationinfo);

}

}

Service接口及其实现类2:

public interface ExcelLaneService extends IService {

void delByStation_id(stationinfo stationinfo);

void add (laneinfo laneinfo);

}

@Service

public class ExcelLaneImpl extends ServiceImpl implements ExcelLaneService {

@Autowired

ExcelLaneMapper excelLaneMapper;

public void delByStation_id(stationinfo stationinfo){

excelLaneMapper.delByStation_id(stationinfo.getId());

}

@Override

public void add(laneinfo laneinfo) {

super.save(laneinfo);

}

}

6、编写Controller类

//读取excel表格内容

@Autowired

private ExcelStationService excelStationService;

@Autowired

private ExcelLaneService excelLaneService;

@PostMapping("/GetExcel")

public Result GetExcel(@RequestParam("file") MultipartFile file) throws Exception{

List stationinfos = new ArrayList<>();

List laneinfos = new ArrayList<>();

try {

InputStream inputStream = file.getInputStream();

Workbook workbook = new HSSFWorkbook(inputStream);

// 假设 Excel 表格的第一个工作表是要读取的工作表

Sheet sheet = workbook.getSheetAt(0);

stationinfo stationinfo = new stationinfo();

for (int i = 2; i<3;i++){

Row row = sheet.getRow(i);

String cellValue = row.getCell(1).toString(); // 获取单元格的字符串值

int intValue;

try {

// 尝试将字符串转换为整数

intValue = (int) Double.parseDouble(cellValue);

} catch (NumberFormatException e) {

// 转换失败时的处理,赋予默认值

intValue = 0; // 默认值为0

}

stationinfo.setId(intValue);

stationinfo.setStation_name(row.getCell(2).toString());

stationinfo.setBusiness_type(row.getCell(3).toString());

stationinfo.setStation_position(row.getCell(4).toString());

stationinfo.setInstall_date(row.getCell(5).getDateCellValue());

String cellValue2 = row.getCell(6).toString(); // 获取单元格的字符串值

int intValue2;

try {

// 尝试将字符串转换为整数

intValue2 = (int) Double.parseDouble(cellValue2);

} catch (NumberFormatException e) {

// 转换失败时的处理,赋予默认值

intValue2 = 0; // 默认值为0

}

stationinfo.setCapture_brand(intValue2);

String cellValue3 = row.getCell(7).toString(); // 获取单元格的字符串值

int intValue3;

try {

// 尝试将字符串转换为整数

intValue3 = (int) Double.parseDouble(cellValue3);

} catch (NumberFormatException e) {

// 转换失败时的处理,赋予默认值

intValue3 = 0; // 默认值为0

}

stationinfo.setLane_count(intValue3);

stationinfos.add(stationinfo);

}

int y = stationinfo.getLane_count();

for (int i = 5; i < y + 5; i++){

Row row = sheet.getRow(i);

laneinfo laneinfo = new laneinfo();

laneinfo.setStation_id(stationinfo.getId());

String cellValue = row.getCell(1).toString(); // 获取单元格的字符串值

int intValue;

try {

// 尝试将字符串转换为整数

intValue = (int) Double.parseDouble(cellValue);

} catch (NumberFormatException e) {

// 转换失败时的处理,赋予默认值

intValue = 0; // 默认值为0

}

laneinfo.setLaneid(intValue);

laneinfo.setIp(row.getCell(2).toString());

laneinfos.add(laneinfo);

}

//删除旧数据/重复数据

excelStationService.delByStation_id(stationinfo);

System.out.println(stationinfos);

for (stationinfo stationinfo1 : stationinfos){

excelStationService.add(stationinfo1);

}

//删除旧数据/重复数据

excelLaneService.delByStation_id(stationinfo);

System.out.println(laneinfos);

for (laneinfo laneinfo : laneinfos){

excelLaneService.add(laneinfo);

}

}catch (IOException e) {

e.printStackTrace();

}

return Result.success("导入成功","导入成功");

}

7、具体实现

三、常见错误

1、"MultipartFile resource [file] cannot be resolved to URL"错误

    这个错误貌似很多人也遇到过,是SpringBoot中关于打印MultipartFile类型参数的log问题,而且大家也都没有具体的问题原因和解决方案,大多数人都是把有关的日志注解给注释掉来解决问题,虽然这种方法不能从根本上解决问题,但胜在方便,所以我也修改了项目中用AOP(面向切面编程)实现的日志处理切面的代码。

/**

* 定义切面

*/

@Pointcut("execution(public * com.hs.server.controller..*.*(..)) " +

"&& !execution(public * com.hs.server.controller.WebApiController.DownloadLocal(..))" +

"&& !execution(public * com.hs.server.controller.TriStationController.GetExcel(..))")

//GetExcel接口不能应用这个切面,不然会有"MultipartFile resource [file] cannot be resolved to URL"错误

2、"org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile cannot be cast to com.hs.server.common.ReqParams"错误

    因为我的项目中有使用 Spring AOP 来实现在指定的 Controller 方法执行前和执行后进行处理的切面,且GetExcel接口不能应用这个切面,所以要添加不应用切面的接口。

/**

* 定义切面

*/

@Pointcut("execution(public * com.hs.server.controller..*.*(..))" +

" && !execution(public * com.hs.server.controller.LoginController.postAccessToken(..))" +

" && !execution(public * com.hs.server.controller.ValidateCodeController.createCode(..))" +

/*" && !execution(public * com.hs.server.controller.VehicleDriverMedicalController.*(com.hs.server.dto.paramsDto.UploadFileDto))" +

" && !execution(public * com.hs.server.controller.VehicleDriverMedicalController.aliPayCallback(..))" +*/

" && !execution(public * com.hs.server.controller.WebApiController.download(..))" +

" && !execution(public * com.hs.server.controller.WebApiController.DownloadLocal(..))" +

" && !execution(public * com.hs.server.controller.WebApiController.AddVehThjl(..))" +

" && !execution(public * com.hs.server.controller.TriStationController.Upload(..))" +

" && !execution(public * com.hs.server.controller.TriStationController.GetExcel(..))")

//GetExcel接口不能应用这个切面,不然会有"org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile cannot be cast to com.hs.server.common.ReqParams"错误

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: