springboot实现简单的excel导入

前文其实已经实现了较为复杂的excel导入了,这篇博客就给大家介绍简单的excel表格导入方法

以下是我的excel表格:

以下是我的实体类:

java 复制代码
package com.datapojo.bean;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

import java.io.Serializable;
import java.util.Date;

/**
 * <p>
 * 
 * </p>
 *
 * @author yinan
 * @since 2024-03-08
 */
@Getter
@Setter
@Builder
@TableName("data_standard_manage")
@ApiModel(value = "DataStandardManage对象", description = "")
public class DataStandardManage implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty("数据库标准id")
    @TableId(value = "data_id", type = IdType.AUTO)
    private Integer dataId;

    @ApiModelProperty("数据标准编号")
    @TableField("data_standard_code")
    private String dataStandardCode;

    @ApiModelProperty("中文名")
    @TableField("cn_name")
    private String cnName;

    @ApiModelProperty("英文名")
    @TableField("en_name")
    private String enName;

    @ApiModelProperty("数据标准说明")
    @TableField("data_standard_explain")
    private String dataStandardExplain;

    @ApiModelProperty("来源机构")
    @TableField("source_orgnization")
    private String sourceOrgnization;

    @ApiModelProperty("数据类型")
    @TableField("data_standard_type")
    private String dataStandardType;

    @ApiModelProperty("数据长度")
    @TableField("data_standard_length")
    private Double dataStandardLength;

    @ApiModelProperty("数据精度")
    @TableField("data_standard_accuracy")
    private Double dataStandardAccuracy;

    @ApiModelProperty("默认值")
    @TableField("data_standard_default")
    private String dataStandardDefault;

    @ApiModelProperty("取值范围的最大值")
    @TableField("data_standard_value_max")
    private String dataStandardValueMax;

    @ApiModelProperty("取值范围的最小值")
    @TableField("data_standard_value_min")
    private String dataStandardValueMin;

    @ApiModelProperty("枚举范围:字典组编码")
    @TableField("data_standard_enumeration_range")
    private String dataStandardEnumerationRange;

    @ApiModelProperty("标准状态(0:未发布  1:已发布 2:已停用)")
    @TableField("data_standard_status")
    private Integer dataStandardStatus;

    @ApiModelProperty("是否为空(0:可为空 1:不为空)")
    @TableField("data_standard_is_blank")
    private Integer dataStandardIsBlank;

    @ApiModelProperty("创建时间")
    @TableField("create_time")
    @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss", timezone = "GMT+8")
    private Date createTime;

    @ApiModelProperty("修改数据")
    @TableField("update_time")
    @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss", timezone = "GMT+8")
    private Date updateTime;


}
复制代码
FileUploadConfig工具类:
java 复制代码
public String objectNameFromUploadPath(String filepath) {
        // 假设filepath是一个完整的URL形式
        // 首先判断是否为空或者不是一个合法的HTTP/HTTPS URL
        if (filepath == null || !(filepath.startsWith("http://") || filepath.startsWith("https://"))) {
            throw new IllegalArgumentException("Invalid file path: " + filepath);
        }

        try {
            // 将文件路径转换成URL对象
            URL url = new URL(filepath);
            // 获取URL的路径部分
            String path = url.getPath();

            // 我们需要去掉路径前的"/",因为OSS object name是不带前导"/"的
            if (path.startsWith("/")) {
                path = path.substring(1);
            }

            // 返回"files/"之后的部分作为object name
            int filesIndex = path.indexOf("files/");
            if (filesIndex != -1) {
                // 返回 "files/" 后面的部分
                return path.substring(filesIndex);
            } else {
                // 如果路径中不含 "files/",直接使用路径作为object name,根据具体情况调整
                return path;
            }
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException("Malformed file path URL: " + filepath, e);
        }
    }

这里的filepath路径我是将前端传给我的文件先上传到oss上面然后获取的链接,你也可以上传到自己本地然后获取文件,或者后台私信我给你具体的上传oss的代码。

接下来是具体的service里面的实现方法:

java 复制代码
  public R addDataStandardsByExcel(MultipartFile file) throws IOException {
//        String filepath = fileUploadConfig.upload(file);
        String filepath = "https://yinan-bucket.oss-cn-beijing.aliyuncs.com/files/33ae3fdb-7b9d-46f4-8227-62c0189c08d6.xlsx";
        String filename = fileUploadConfig.objectNameFromUploadPath(filepath);
        System.out.println("filepath:" + filepath + "  filename:" + filename);
        String fileName = file.getOriginalFilename();
//        if (Objects.equals(filepath, "文件上传失败")) {
//            return R.Failed("文件上传失败,无法进行数据导入");
//        }
//        初始化变量
        boolean notNull = false;
        List<DataStandardManage> dsmList = new ArrayList<>();
//        InputStream is = fileUploadConfig.download(filename);
        InputStream is = file.getInputStream();
//        检查文件格式是否正确
        if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
//            自定义异常处理
            throw new FileNotStandardException(MessageConstant.File_NOT_STANDARD);
        }
        Workbook workbook = null;
        try {
            // 判断文件是2003格式的Excel还是2007格式的Excel
            boolean isExcel2003 = true;
            if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
                isExcel2003 = false;
            }
//        创建workbook对象
            workbook = null;
            if (isExcel2003) {
                workbook = new HSSFWorkbook(is);
            } else {
                workbook = new XSSFWorkbook(is);
            }
//        获取第一个工作表
            Sheet sheet = workbook.getSheetAt(0);
//        判断是否为空
            if (sheet != null) {
                notNull = false;
            } else {
                throw new FileIsEmptyException(MessageConstant.FILE_IS_EMPTY);
            }
//        遍历工作表的每一行
            for (int i = 1; i <= Objects.requireNonNull(sheet).getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                // 检查行是否为空
                if (row == null) {
                    continue; // 如果为空,跳过该行
                }
                DataStandardManage dsm = null;
                String dsmCnName = row.getCell(0).getStringCellValue();
                String dsmEnName = row.getCell(1).getStringCellValue();
                String dsmExplain = row.getCell(2) == null ? null : row.getCell(2).getStringCellValue();
                Integer dsmIsBlank = Objects.equals(row.getCell(3).getStringCellValue(), "可为空") ? 0 : 1;
                String dsmSourceOrg = row.getCell(4).getStringCellValue();
                String dsmDefault = row.getCell(5) == null ? null : row.getCell(5).getStringCellValue();
                String dsmDataType = row.getCell(6).getStringCellValue();
                Double dsmLength = row.getCell(7) == null ? null : row.getCell(7).getNumericCellValue();

                // 格式化科学计数法,取一位整数,如取小数,值如0.0,取小数点后几位就写几个0
                DecimalFormat df = new DecimalFormat("0");

                Double dsmAccuracy = ObjectUtils.isEmpty(row.getCell(8).getNumericCellValue()) ? null : row.getCell(7).getNumericCellValue();
//                Integer dsmAccuracy = dsmAccuracyTemp == null ? null : Integer.parseInt(df.format(dsmAccuracyTemp));

                Double dsmMinTemp = ObjectUtils.isEmpty(row.getCell(9).getNumericCellValue()) ? null : row.getCell(8).getNumericCellValue();
                String dsmMin = dsmMinTemp == null ? null : df.format(dsmMinTemp);

//                String dsmMin=ObjectUtils.isEmpty(row.getCell(9))?null:String.valueOf(row.getCell(9).getNumericCellValue());//使用此方法也可以,但是转换后格式有点不对
                Double dsmMaxTemp = ObjectUtils.isEmpty(row.getCell(10).getNumericCellValue()) ? null : row.getCell(10).getNumericCellValue();
                String dsmMax = dsmMaxTemp == null ? null : df.format(dsmMaxTemp);
//                String dsmMax=ObjectUtils.isEmpty(row.getCell(10))?null:String.valueOf(row.getCell(10).getNumericCellValue());
                String dsmMaBiao = row.getCell(11) == null ? null : row.getCell(11).getStringCellValue();
                dsm = DataStandardManage.builder()
                        .dataStandardCode(RandomUtil.generateRandomNumber("BZ",2))
                        .cnName(dsmCnName)
                        .enName(dsmEnName)
                        .dataStandardExplain(dsmExplain)
                        .sourceOrgnization(dsmSourceOrg)
                        .dataStandardType(dsmDataType)
                        .dataStandardIsBlank(dsmIsBlank)
                        .dataStandardDefault(dsmDefault)
                        .dataStandardLength(dsmLength)
                        .dataStandardAccuracy(dsmAccuracy)
                        .dataStandardValueMin(dsmMin)
                        .dataStandardValueMax(dsmMax)
                        .dataStandardEnumerationRange(dsmMaBiao)
                        .createTime(dateConfig.getDate())
                        .updateTime(dateConfig.getDate())
                        .dataStandardStatus(0)
                        .build();
                dsmList.add(dsm);
            }
            for (DataStandardManage dsm : dsmList) {
                dataStandardManageDao.insert(dsm);
                System.out.println("插入:" + dsm);
            }
            is.close();
            return R.Success("导入成功");
        } catch (Exception e) {
            // 处理文件读取异常
            e.printStackTrace(); // 这里可以记录日志或者返回相应错误信息
            return R.Failed("文件读取异常,无法进行数据导入");
        } finally {
            // 确保关闭流
            if (workbook != null) {
                workbook.close();
            }
            is.close();
        }
    }

代码中均做有注释,不懂得可以在评论区进行留言~

相关推荐
小信啊啊9 小时前
Go语言切片slice
开发语言·后端·golang
全靠bug跑9 小时前
Spring Cloud OpenFeign 实战三部曲:快速集成 · 连接池优化 · 客户端抽取
java·spring boot·openfeign
北城以北888810 小时前
Spring定时任务与Spring MVC拦截器
spring boot·spring·mvc
Victor35610 小时前
Netty(20)如何实现基于Netty的WebSocket服务器?
后端
缘不易10 小时前
Springboot 整合JustAuth实现gitee授权登录
spring boot·后端·gitee
Kiri霧10 小时前
Range循环和切片
前端·后端·学习·golang
WizLC11 小时前
【Java】各种IO流知识详解
java·开发语言·后端·spring·intellij idea
Mr.朱鹏11 小时前
SQL深度分页问题案例实战
java·数据库·spring boot·sql·spring·spring cloud·kafka
星星不打輰11 小时前
SSM项目--SweetHouse 甜蜜蛋糕屋
java·spring·mybatis·ssm·springmvc
Victor35611 小时前
Netty(19)Netty的性能优化手段有哪些?
后端