当前位置:   article > 正文

Java、SpringBoot实现对Excel内容的读取并将Excel内容导入到数据库中(后端篇)_springboot 读取excel并写入数据库

springboot 读取excel并写入数据库

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

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

Excel表:

数据库表:

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

1、引入依赖

  1. <!--解析excel-->
  2. <dependency>
  3. <groupId>org.apache.poi</groupId>
  4. <artifactId>poi</artifactId>
  5. <version>RELEASE</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.apache.poi</groupId>
  9. <artifactId>poi-ooxml</artifactId>
  10. <version>RELEASE</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>commons-io</groupId>
  14. <artifactId>commons-io</artifactId>
  15. <version>2.13.0</version> <!-- 请根据你的需求使用合适的版本 -->
  16. </dependency>

2、创建实体类

  1. @Data
  2. @TableName("test")
  3. public class TestDto {
  4. @ExcelImport("id")
  5. private String id;
  6. @ExcelImport("username")
  7. private String username;
  8. @ExcelImport("password")
  9. private String password;
  10. }

3、导入Excel相关的工具类

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

4、创建Mapper接口

  1. public interface TestMapper extends BaseMapper<TestDto> {
  2. }

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

  1. public interface TestService extends IService<TestDto> {
  2. void add(TestDto testDto);
  3. }
  1. public class TestServiceImpl extends ServiceImpl<TestMapper, TestDto> implements TestService {
  2. public void add(TestDto testDto) {
  3. super.save(testDto);//加入数据库中
  4. }
  5. }

6、编写Controller类

  1. @PostMapping("/GetExcel")
  2. public Result GetExcel(@RequestParam("file") MultipartFile file) throws Exception {
  3. List<TestDto> testDtos = ExcelUtils.readMultipartFile(file, TestDto.class);
  4. for (TestDto testDto : testDtos) {
  5. testService.add(testDto);
  6. }
  7. return Result.success(testDtos, "导入成功");
  8. }

7、具体实现

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

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

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

1、引入依赖

    详见第一种方法。

2、创建实体类

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

实体类1:

  1. @Data
  2. @TableName("tri_zd_stationinfo")
  3. public class stationinfo {
  4. @ExcelImport("站点id")
  5. private Integer id;
  6. @ExcelImport("站点名称")
  7. private String station_name;
  8. @ExcelImport("业务类型")
  9. private String business_type;
  10. @ExcelImport("站点位置")
  11. private String station_position;
  12. @ExcelImport("安装日期")
  13. private Date install_date;
  14. @ExcelImport("摄像枪品牌类型")
  15. private Integer capture_brand;
  16. @ExcelImport("车道数量")
  17. private Integer lane_count;
  18. }

实体类2:

  1. @Data
  2. @TableName("tri_zd_laneinfo")
  3. public class laneinfo {
  4. private Integer station_id;
  5. @ExcelImport("车道号")
  6. private Integer laneid;
  7. @ExcelImport("仪表ip")
  8. private String ip;
  9. }

3、导入Excel相关的工具类

    详见第一种方法。

4、创建Mapper接口

Mapper接口1:

  1. public interface ExcelStationMapper extends BaseMapper<stationinfo> {
  2. }

Mapper接口2:

  1. public interface ExcelLaneMapper extends BaseMapper<laneinfo> {
  2. //根据你的业务需求写代码,这里有删除旧数据/重复数据的需求
  3. @Delete("delete from tri_zd_laneinfo where station_id = #{station_id};")
  4. int delByStation_id (int station_id);
  5. }

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

Service接口及其实现类1:

  1. public interface ExcelStationService extends IService<stationinfo> {
  2. void delByStation_id(stationinfo stationinfo);
  3. void add(stationinfo stationinfo);
  4. }
  1. @Service
  2. public class ExcelStationImpl extends ServiceImpl<ExcelStationMapper, stationinfo> implements ExcelStationService {
  3. @Autowired
  4. ExcelStationMapper excelStationMapper;
  5. public void delByStation_id(stationinfo stationinfo){
  6. excelStationMapper.deleteById(stationinfo.getId());
  7. }
  8. @Override
  9. public void add(stationinfo stationinfo) {
  10. super.save(stationinfo);
  11. }
  12. }

Service接口及其实现类2:

  1. public interface ExcelLaneService extends IService<laneinfo> {
  2. void delByStation_id(stationinfo stationinfo);
  3. void add (laneinfo laneinfo);
  4. }
  1. @Service
  2. public class ExcelLaneImpl extends ServiceImpl<ExcelLaneMapper, laneinfo> implements ExcelLaneService {
  3. @Autowired
  4. ExcelLaneMapper excelLaneMapper;
  5. public void delByStation_id(stationinfo stationinfo){
  6. excelLaneMapper.delByStation_id(stationinfo.getId());
  7. }
  8. @Override
  9. public void add(laneinfo laneinfo) {
  10. super.save(laneinfo);
  11. }
  12. }

6、编写Controller类

  1. //读取excel表格内容
  2. @Autowired
  3. private ExcelStationService excelStationService;
  4. @Autowired
  5. private ExcelLaneService excelLaneService;
  6. @PostMapping("/GetExcel")
  7. public Result GetExcel(@RequestParam("file") MultipartFile file) throws Exception{
  8. List<stationinfo> stationinfos = new ArrayList<>();
  9. List<laneinfo> laneinfos = new ArrayList<>();
  10. try {
  11. InputStream inputStream = file.getInputStream();
  12. Workbook workbook = new HSSFWorkbook(inputStream);
  13. // 假设 Excel 表格的第一个工作表是要读取的工作表
  14. Sheet sheet = workbook.getSheetAt(0);
  15. stationinfo stationinfo = new stationinfo();
  16. for (int i = 2; i<3;i++){
  17. Row row = sheet.getRow(i);
  18. String cellValue = row.getCell(1).toString(); // 获取单元格的字符串值
  19. int intValue;
  20. try {
  21. // 尝试将字符串转换为整数
  22. intValue = (int) Double.parseDouble(cellValue);
  23. } catch (NumberFormatException e) {
  24. // 转换失败时的处理,赋予默认值
  25. intValue = 0; // 默认值为0
  26. }
  27. stationinfo.setId(intValue);
  28. stationinfo.setStation_name(row.getCell(2).toString());
  29. stationinfo.setBusiness_type(row.getCell(3).toString());
  30. stationinfo.setStation_position(row.getCell(4).toString());
  31. stationinfo.setInstall_date(row.getCell(5).getDateCellValue());
  32. String cellValue2 = row.getCell(6).toString(); // 获取单元格的字符串值
  33. int intValue2;
  34. try {
  35. // 尝试将字符串转换为整数
  36. intValue2 = (int) Double.parseDouble(cellValue2);
  37. } catch (NumberFormatException e) {
  38. // 转换失败时的处理,赋予默认值
  39. intValue2 = 0; // 默认值为0
  40. }
  41. stationinfo.setCapture_brand(intValue2);
  42. String cellValue3 = row.getCell(7).toString(); // 获取单元格的字符串值
  43. int intValue3;
  44. try {
  45. // 尝试将字符串转换为整数
  46. intValue3 = (int) Double.parseDouble(cellValue3);
  47. } catch (NumberFormatException e) {
  48. // 转换失败时的处理,赋予默认值
  49. intValue3 = 0; // 默认值为0
  50. }
  51. stationinfo.setLane_count(intValue3);
  52. stationinfos.add(stationinfo);
  53. }
  54. int y = stationinfo.getLane_count();
  55. for (int i = 5; i < y + 5; i++){
  56. Row row = sheet.getRow(i);
  57. laneinfo laneinfo = new laneinfo();
  58. laneinfo.setStation_id(stationinfo.getId());
  59. String cellValue = row.getCell(1).toString(); // 获取单元格的字符串值
  60. int intValue;
  61. try {
  62. // 尝试将字符串转换为整数
  63. intValue = (int) Double.parseDouble(cellValue);
  64. } catch (NumberFormatException e) {
  65. // 转换失败时的处理,赋予默认值
  66. intValue = 0; // 默认值为0
  67. }
  68. laneinfo.setLaneid(intValue);
  69. laneinfo.setIp(row.getCell(2).toString());
  70. laneinfos.add(laneinfo);
  71. }
  72. //删除旧数据/重复数据
  73. excelStationService.delByStation_id(stationinfo);
  74. System.out.println(stationinfos);
  75. for (stationinfo stationinfo1 : stationinfos){
  76. excelStationService.add(stationinfo1);
  77. }
  78. //删除旧数据/重复数据
  79. excelLaneService.delByStation_id(stationinfo);
  80. System.out.println(laneinfos);
  81. for (laneinfo laneinfo : laneinfos){
  82. excelLaneService.add(laneinfo);
  83. }
  84. }catch (IOException e) {
  85. e.printStackTrace();
  86. }
  87. return Result.success("导入成功","导入成功");
  88. }

7、具体实现

三、常见错误

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

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

  1. /**
  2. * 定义切面
  3. */
  4. @Pointcut("execution(public * com.hs.server.controller..*.*(..)) " +
  5. "&& !execution(public * com.hs.server.controller.WebApiController.DownloadLocal(..))" +
  6. "&& !execution(public * com.hs.server.controller.TriStationController.GetExcel(..))")
  7. //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接口不能应用这个切面,所以要添加不应用切面的接口。

  1. /**
  2. * 定义切面
  3. */
  4. @Pointcut("execution(public * com.hs.server.controller..*.*(..))" +
  5. " && !execution(public * com.hs.server.controller.LoginController.postAccessToken(..))" +
  6. " && !execution(public * com.hs.server.controller.ValidateCodeController.createCode(..))" +
  7. /*" && !execution(public * com.hs.server.controller.VehicleDriverMedicalController.*(com.hs.server.dto.paramsDto.UploadFileDto))" +
  8. " && !execution(public * com.hs.server.controller.VehicleDriverMedicalController.aliPayCallback(..))" +*/
  9. " && !execution(public * com.hs.server.controller.WebApiController.download(..))" +
  10. " && !execution(public * com.hs.server.controller.WebApiController.DownloadLocal(..))" +
  11. " && !execution(public * com.hs.server.controller.WebApiController.AddVehThjl(..))" +
  12. " && !execution(public * com.hs.server.controller.TriStationController.Upload(..))" +
  13. " && !execution(public * com.hs.server.controller.TriStationController.GetExcel(..))")
  14. //GetExcel接口不能应用这个切面,不然会有"org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile cannot be cast to com.hs.server.common.ReqParams"错误

                
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/570397
推荐阅读
相关标签
  

闽ICP备14008679号