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();
        }
    }

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

相关推荐
兩尛1 小时前
数据统计–Excel报表(day12)2
excel
秋野酱5 小时前
如何在 Spring Boot 中实现自定义属性
java·数据库·spring boot
安的列斯凯奇6 小时前
SpringBoot篇 单元测试 理论篇
spring boot·后端·单元测试
架构文摘JGWZ6 小时前
FastJson很快,有什么用?
后端·学习
BinaryBardC6 小时前
Swift语言的网络编程
开发语言·后端·golang
邓熙榆6 小时前
Haskell语言的正则表达式
开发语言·后端·golang
多则惑少则明8 小时前
SSM开发(一)JAVA,javaEE,spring,springmvc,springboot,SSM,SSH等几个概念区别
spring boot·spring·ssh
Swift社区8 小时前
【分布式日志篇】从工具选型到实战部署:全面解析日志采集与管理路径
人工智能·spring boot·分布式
专职9 小时前
spring boot中实现手动分页
java·spring boot·后端
Ciderw9 小时前
Go中的三种锁
开发语言·c++·后端·golang·互斥锁·