需求:将excel中的所有数据导入到PG数据库的对应数据表中,需要对数据进行校验等操作

maven依赖:

    <properties><hutool.version>5.5.1</hutool.version><poi.version>3.17</poi.version></properties><!-- excel工具 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>${poi.version}</version></dependency><!-- hutool相关依赖 --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>${hutool.version}</version></dependency>

PG数据表的设计:


CREATE TABLE "public"."shopping_detail" ("id" int8 NOT NULL,"order_id" varchar(50) COLLATE "pg_catalog"."default" NOT NULL,"good_name" varchar(50) COLLATE "pg_catalog"."default" NOT NULL,"address" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,"receiver" varchar(50) COLLATE "pg_catalog"."default","phone" varchar(30) COLLATE "pg_catalog"."default","num" varchar(10) COLLATE "pg_catalog"."default" NOT NULL,"create_by" varchar(30) COLLATE "pg_catalog"."default","create_time" timestamptz(6),"update_by" varchar(30) COLLATE "pg_catalog"."default","update_time" timestamptz(6),"remark" varchar(500) COLLATE "pg_catalog"."default",CONSTRAINT "cgm_drug_info_pkey" PRIMARY KEY ("id")
)
;ALTER TABLE "public"."shopping_detail"OWNER TO "postgres";COMMENT ON COLUMN "public"."shopping_detail"."id" IS '主键ID';COMMENT ON COLUMN "public"."shopping_detail"."order_id" IS '订单号';COMMENT ON COLUMN "public"."shopping_detail"."good_name" IS '商品名称';COMMENT ON COLUMN "public"."shopping_detail"."address" IS '收货地址';COMMENT ON COLUMN "public"."shopping_detail"."receiver" IS '收件人';COMMENT ON COLUMN "public"."shopping_detail"."phone" IS '手机号';COMMENT ON COLUMN "public"."shopping_detail"."num" IS '数量';COMMENT ON COLUMN "public"."shopping_detail"."create_by" IS '创建人(账号name)';COMMENT ON COLUMN "public"."shopping_detail"."create_time" IS '创建时间';COMMENT ON COLUMN "public"."shopping_detail"."update_by" IS '更新人(账号name)';COMMENT ON COLUMN "public"."shopping_detail"."update_time" IS '更新时间';COMMENT ON COLUMN "public"."shopping_detail"."remark" IS '备注';COMMENT ON TABLE "public"."shopping_detail" IS '购买商品详情表';

MyBatisPlus的实体类设计:

package com.opencv.domain.entity;import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;@ApiModel("购买商品详情表")
@TableName(value = "shopping_detail", autoResultMap = true)
public class ShoppingDetailEntity extends CgmBaseEntity {/*** 商品名称*/@ApiModelProperty(value = "商品名称")private String goodName;/*** 收货地址*/@ApiModelProperty(value = "收货地址")private String address;/*** 收件人*/@ApiModelProperty(value = "收件人")private String receiver;/*** 手机号*/@ApiModelProperty(value = "手机号")private String phone;/*** 订单号*/@ApiModelProperty(value = "订单号")private String orderId;/*** 数量*/@ApiModelProperty(value = "数量")private String num;public String getNum() {return num;}public void setNum(String num) {this.num = num;}public String getOrderId() {return orderId;}public void setOrderId(String orderId) {this.orderId = orderId;}public String getGoodName() {return goodName;}public void setGoodName(String goodName) {this.goodName = goodName;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public String getReceiver() {return receiver;}public void setReceiver(String receiver) {this.receiver = receiver;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}
}

Mapper设计:

package com.opencv.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.opencv.domain.entity.ShoppingDetailEntity;
import org.springframework.stereotype.Repository;@Repository
public interface ShoppingDetailMapper extends BaseMapper<ShoppingDetailEntity> {
}

订单Excel需要导入的数据如下所示:

反射需要用到的枚举类设计:

package com.opencv.enums;public enum ShoppingDetailEnum {GOOD_NAME("商品名称", "goodName"),ADDRESS("收货地址", "address"),RECEIVER("收件人", "receiver"),PHONE("手机号", "phone"),ORDER_ID("订单号", "orderId"),NUM("数量", "num"),;private String columnName;private String fieldName;ShoppingDetailEnum(String columnName, String fieldName) {this.columnName = columnName;this.fieldName = fieldName;}public static ShoppingDetailEnum get(String columnName) {ShoppingDetailEnum[] values = ShoppingDetailEnum.values();for (ShoppingDetailEnum shoppingDetailEnum : values) {if (shoppingDetailEnum.getColumnName().equals(columnName)) {return shoppingDetailEnum;}}return null;}public String getColumnName() {return columnName;}public String getFieldName() {return fieldName;}
}

导入的测试代码(可以改成Web接口的形式对外提供服务),暂时用的main函数的方式实现:

package com.opencv.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.opencv.domain.entity.ShoppingDetailEntity;
import com.opencv.enums.ShoppingDetailEnum;
import com.opencv.mapper.ShoppingDetailMapper;
import com.opencv.utils.ExcelUtil;
import com.opencv.utils.IdUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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 org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Rollback
public class ImportExcelDataTests {private static String EXCEL_PATH = "E:\\backUp\\订单数据.xlsx";private static Map<Integer, String> COLUMN_MAP = new HashMap<>();@Autowiredprivate ShoppingDetailMapper shoppingDetailMapper;@Testpublic void importExcelTest() throws Exception {File file = new File(EXCEL_PATH);Workbook workbook = null;try {workbook = new XSSFWorkbook(file);} catch (Exception ex) {workbook = new HSSFWorkbook(new FileInputStream(file));}int numberOfSheets = workbook.getNumberOfSheets();for (int i = 0; i < numberOfSheets; i++) {if (i > 0) {break;}Sheet sheet = workbook.getSheetAt(i);int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();for (int j = 0; j < physicalNumberOfRows; j++) {Row row = sheet.getRow(j);int physicalNumberOfCells = row.getPhysicalNumberOfCells();if (j == 0) {for (int k = 0; k < physicalNumberOfCells; k++) {String cellValue = (String) ExcelUtil.getCellValue(row, k);ShoppingDetailEnum shoppingDetailEnum = ShoppingDetailEnum.get(cellValue);COLUMN_MAP.put(k, shoppingDetailEnum.getFieldName());}continue;// 标题行}ShoppingDetailEntity shoppingDetailEntity = new ShoppingDetailEntity();Field declaredField = null;for (int k = 0; k < physicalNumberOfCells; k++) {String fieldName = COLUMN_MAP.get(k);try {declaredField = shoppingDetailEntity.getClass().getDeclaredField(fieldName);} catch (NoSuchFieldException ex) {// 子类不存在该变量则从父类获取变量declaredField = shoppingDetailEntity.getClass().getSuperclass().getDeclaredField(fieldName);}Object cellValue = ExcelUtil.getCellValue(row, k);declaredField.setAccessible(true);declaredField.set(shoppingDetailEntity, cellValue);}// 开始插入数据LambdaQueryWrapper<ShoppingDetailEntity> shoppingDetailWrapper = new QueryWrapper<ShoppingDetailEntity>().lambda();shoppingDetailWrapper.eq(ShoppingDetailEntity::getOrderId, shoppingDetailEntity.getOrderId());ShoppingDetailEntity searchShoppingDetail = shoppingDetailMapper.selectOne(shoppingDetailWrapper);if (Objects.isNull(searchShoppingDetail)) {ShoppingDetailEntity insertShoppingDetail = new ShoppingDetailEntity();// 这里可以使用beanUtils等工具类通过反射来复制属性值insertShoppingDetail.setId(IdUtils.nextSnowFlakeId());insertShoppingDetail.setAddress(shoppingDetailEntity.getAddress());insertShoppingDetail.setGoodName(shoppingDetailEntity.getGoodName());insertShoppingDetail.setOrderId(shoppingDetailEntity.getOrderId());insertShoppingDetail.setPhone(shoppingDetailEntity.getPhone());insertShoppingDetail.setReceiver(shoppingDetailEntity.getReceiver());insertShoppingDetail.setNum(shoppingDetailEntity.getNum());insertShoppingDetail.setCreateTime(new Date());insertShoppingDetail.setCreateBy("excel导入");shoppingDetailMapper.insert(insertShoppingDetail);} else {System.out.println("已存在记录:orderId:" + shoppingDetailEntity.getOrderId() + ", address:" + shoppingDetailEntity.getAddress() + ", goodName:" + shoppingDetailEntity.getGoodName());}}}}
}

实现导入Excel数据的代码设计方案:

1、选中sheet分页:workbook.getSheetAt(i);

2、遍历excel表格的所有行数据:for (int j = 0; j < physicalNumberOfRows; j++)

3、遍历选中行的所有列的数据:for (int k = 0; k < physicalNumberOfCells; k++)

4、通过枚举类获取excel表头对应的列属性名:ShoppingDetailEnum.get(cellValue)

5、通过反射将excel表格中的列的对应数据,设置都需要导入的对象的属性值中:

Object cellValue = ExcelUtil.getCellValue(row, k); declaredField.setAccessible(true); declaredField.set(shoppingDetailEntity, cellValue);

6、将数据对象保存到数据库中:

shoppingDetailMapper.insert(insertShoppingDetail);

PS:也可以做成批量导入,将excel中的数据全部组装完成后,添加到集合中,最后再进行批量插入

导入结果:

总结:

Excel的数据导入在实际应用场景中可能更复杂,因为在实际使用的系统可能是分布式环境,测试到不同服务间,同时导入的也可能不是一张表的数据,数据的校验规则也比较复杂,还有异常的机制设计,比如:导入重复的返回提示,数据是否需要继续插入,还是全部失败?跨服务调用的接口超时怎么设置,超时时间设置成多大可以符合实际应用场景?

需要考虑的东西太多了,就不一一赘述了,但是excel导入的核心已经全部体现在案例中了,其他的都属于实际应用中的扩展,可以根据实际业务来设计,当然实现方案还有别的方式,这里展开的就是当前的实现方式来叙述的。

JAVA实现Excel模板导入案例分析相关推荐

  1. Java下载excel模板

    接上篇 -- "下载功能"实现 Excel模板数据导入 参考 上一篇 : Java实现Excel模板导入 正文: 一.接口层: /*** 下载** @param res respo ...

  2. java 分析excel模板,java 根据excel模板导出excel

    java 根据excel模板导出excel 由于项目需求,最近做了一个需要根据查询接口导出excel表格数据的需求 pom依赖: org.apache.poi poi 3.16 org.apache. ...

  3. 【转帖】Java实现Excel批量导入数据

    这篇文章主要为大家详细介绍了Java实现Excel批量导入数据,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 Excel的批量导入是很常见的功能,这里采用Jxl实现,数 ...

  4. VUE+JAVA实现EXCEL模板下载

    一.项目场景: VUE+JAVA实现EXCEL模板下载 二.功能背景 本人作为一个开发小白,今天接到一个小需求系统需要导入数据,也就十几个字段,我和老板说了,让客户一个一个去输入吧!然后我就被经理叫去 ...

  5. java通过Excel 模板导出复杂统计类excel文档,在ruoyi前后端分离框架中的应用

    Hello, 大家好! 我是不作死就不会死,智商不在线,但颜值超有品的拆家队大队长 --咖啡汪 一只不是在戏精,就是在戏精路上的极品二哈 前几天刚做了java通过Excel 模板导出复杂统计类exce ...

  6. Java实现excel模板

    Java实现excel模板 Java代码 前端调用 Java代码 @ApiOperation("下载模板")@RequestMapping(value = "/model ...

  7. java 根据excel模板导出excel

    java 根据excel模板导出excel 由于项目需求,最近做了一个需要根据查询接口导出excel表格数据的需求 pom依赖: <dependency><groupId>or ...

  8. java excel 导入 关闭,excel关联别的表格数据库-java实现excel表导入,有的字段数据库中没有,需要关......

    excel中我想用另一张表的内容我数据库,当我在一个... 用VLOOKUP函数,=VLOOKUP(lookup_value,table_array,col_index_num,range_looku ...

  9. VUE+ElementUI生成Excel模板 导入数据生成表格(自适应)

    VUE+ElementUI生成Excel模板 导入数据生成表格(自适应) 最近项目需求,需要根据条件查询对应数据的参数(每条数据的参数名称和个数都不一样) ,生成Excel表格模板,再通过Excel模 ...

最新文章

  1. 什么是智能仓储?一文带你彻底搞懂!
  2. leetcode处女作
  3. WCF布署问题1 :HTTP 错误 404.17 - Not Found 请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理。...
  4. android界面基本属性
  5. JavaScript的函数
  6. c 语言贪心钓鱼思路,2020届九年级中考语文复习教案:第4讲现代文阅读之概括(27页)-原创力文档...
  7. Jvm原理剖析与调优之内存结构
  8. 自媒体发展陷入僵局,社群媒体将成出路?呵呵…
  9. 算法模型该如何解释?
  10. Nginx端口占用问题
  11. 搭建spring MVC项目
  12. Jenkins 与 Kubernetes 的 CI 与 CD Git + Maven + Docker+Kubectl
  13. 3==num VS num==3
  14. iPhone开发:类似iChat的聊天泡泡
  15. 如何用ftp上传到服务器视频文件,ftp如何将文件上传到服务器上
  16. 上电瞬间电容相当于短路
  17. 【Tensorflow】op的理解和自定义损失函数
  18. 用python画熊_Python数据可视化:Pandas库,只要一行代码就能实现
  19. java中.level_java中的Level level是什么意思呢
  20. 《Excel数据可视化:一样的数据不一样的图表》——3.5用图标集让你的数据大放异彩...

热门文章

  1. 关于DSP28335的CAN模块与上位机(PC)通信调试心得(1)
  2. 科林明伦杯哈理工第十届同步赛部分题解
  3. CAD转Excel,如何快速转换呢?
  4. Python——画一棵漂亮的樱花树(不同种樱花+玫瑰+圣诞树喔)
  5. RabbitMQ fanout广播消息使用匿名队列
  6. 12.Linux 网络配置
  7. Apache Sling App CMS <1.1.4 存在反射型XSS漏洞(CVE-2022-46769)
  8. 如何用数据库可视化工具:DataGrip导入数据
  9. 5G LAN — 技术实现原理
  10. mac下怎么将终端命令安装的软件加进系统环境变量中