首页 > 编程语言 >Java 超详细实现导入导出 (包含时间转换问题和样式)

Java 超详细实现导入导出 (包含时间转换问题和样式)

时间:2024-06-22 23:58:33浏览次数:28  
标签:Java MM Excel 导出 createCell 导入 setCellValue data row

序言

工作中遇到了导入导出问题,并且出现了导入或导出Excel时间格式变为数字的问题。通过学习解决实现了这些功能,记录总结分享给大家。本文将详细介绍如何使用 Java 编程语言和 Apache POI 库来实现这些功能。我们将通过一个示例项目演示如何从数据库中读取数据并将其导出为 Excel 文件,然后再从 Excel 文件中读取数据并导入回数据库。 

问题

导入或导出 Excel 时,时间格式变为数字的问题通常是由于 Excel 在处理日期时间时的内部表示方式所致。Excel会将日期时间数据存储为一个数字,该数字代表自 1900 年 1 月 1 日以来的天数(对于日期部分)或天数加上小数表示的时间部分。因此,如果不正确处理这些日期时间数据,Excel 可能会显示为日期时间的数字格式,而不是人类可读的日期时间格式。 

例:这是数据库时间 

 

导入之后

 

准备工作

在开始之前,确保你已经准备好以下环境和工具:

  • Java 开发环境(JDK11)
  • Maven 项目管理工具 (3.6.1)
  • IDE(例如 IntelliJ IDEA 或 Eclipse)
  • Apache POI 库
  • Mybatis-Plus / Mybatis 

1. 创建 Maven 项目并导入依赖

首先,创建一个 Maven 项目并在 pom.xml 文件中添加 Apache POI 的依赖:

        <!-- Apache POI -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.2.3</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.2.3</version> <!-- 版本号根据实际情况调整 -->
        </dependency>

2.实体类和数据库如下

@Data
@TableName("excel")
public class DataEntity {
    private Long id;
    private String name;
    private int age;
    private String email;
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    @TableField(value = "birthday")
    private LocalDate birthday;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    @TableField(value = "currenttime")
    private LocalDateTime currentTime;
}

 3.yml配置连接数据库,用Mybatis-Plus / Mybatis 写Mapper,Service,Impl此处不再赘述

导出功能实现

1.编写导出功能的 Controller

创建一个 Spring MVC 的 Controller 类,实现数据导出到 Excel 的功能:

@RestController
@RequestMapping("/execl")
public class ExeclController {
    @Resource
    private DataService dataService;

    @GetMapping("/export")
    public ResponseEntity<byte[]> exportDataToExcel() throws IOException {

        //读取数据库全部数据
        List<DataEntity> dataList = dataService.list();

        // 创建一个工作簿
        Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Data");

        // 创建表头
        Row headerRow = sheet.createRow(0);
        headerRow.createCell(0).setCellValue("ID");
        headerRow.createCell(1).setCellValue("Name");
        headerRow.createCell(2).setCellValue("Age");
        headerRow.createCell(3).setCellValue("Email");
        headerRow.createCell(4).setCellValue("Birthday");
        headerRow.createCell(5).setCellValue("CurrentTime");

        // 日期和时间格式化器
        // 将 LocalDate 和 LocalDateTime 转换为字符串格式
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");


        // 创建日期单元格样式
        //CreationHelper 是 Apache POI 提供的一个帮助类,用于创建各种格式和样式。
        CreationHelper creationHelper = workbook.getCreationHelper();
        //CellStyle 是用于定义单元格样式的类。
        //workbook.createCellStyle() 方法用于创建一个新的单元格样式对象。
        //dateStyle.setDataFormat(...) 方法用于设置单元格的数据格式。
        //creationHelper.createDataFormat().getFormat("yyyy-MM-dd") 方法用于获取日期格式的代码,"yyyy-MM-dd" 是我们想要的日期格式。
        CellStyle dateStyle = workbook.createCellStyle();
        dateStyle.setDataFormat(creationHelper.createDataFormat().getFormat("yyyy-MM-dd"));
        CellStyle dateTimeStyle = workbook.createCellStyle();
        dateTimeStyle.setDataFormat(creationHelper.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));

        // 填充数据行
        int rowNum = 1;
        for (DataEntity data : dataList) {
            Row row = sheet.createRow(rowNum++);
            row.createCell(0).setCellValue(data.getId());
            row.createCell(1).setCellValue(data.getName());
            row.createCell(2).setCellValue(data.getAge());
            row.createCell(3).setCellValue(data.getEmail());
            // 格式化并设置日期,单元格样式
            Cell birthdayCell = row.createCell(4);
            birthdayCell.setCellValue(data.getBirthday().format(dateFormatter));
            birthdayCell.setCellStyle(dateStyle);

            // 格式化并设置日期,单元格样式
            Cell currentTimeCell = row.createCell(5);
            currentTimeCell.setCellValue(data.getCurrentTime().format(dateTimeFormatter));
            currentTimeCell.setCellStyle(dateTimeStyle);
        }

        // 调整列宽以适应内容
        for (int i = 0; i < 6; i++) {
            sheet.autoSizeColumn(i);
        }

        // 将工作簿写入字节数组输出流
        ByteArrayOutputStream
                outputStream = new ByteArrayOutputStream();
        //这个方法用于将工作簿(通常是Excel文件)的内容写入到一个OutputStream中
        workbook.write(outputStream);
        workbook.close();

        // 将字节数组输出流转换为字节数组
        byte[] bytes = outputStream.toByteArray();

        // 设置响应头
        //HttpHeaders 类:这个类是 Spring 提供的一个方便的 HTTP 头部管理工具类,可以用来设置各种 HTTP 头部字段。
        HttpHeaders headers = new HttpHeaders();
        //设置响应的内容类型(Content-Type)
        //application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 是 Excel 文件的 MIME 类型,表示返回的是一个 Excel 文件。
        //MediaType.parseMediaType 方法:这个方法用来解析 MIME 类型字符串并返回一个 MediaType 对象。
        headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
        //设置响应的内容处置方式(Content-Disposition),告诉浏览器如何处理响应的内容。
        //Content-Disposition 头部:这个头部字段有助于控制浏览器对于响应内容的处理方式。它常用于提示浏览器下载文件,而不是直接在浏览器中显示内容。
        //attachment:表示响应的内容是一个附件,应该提示用户下载
        //data.xlsx":表示下载文件的默认名称为 data.xlsx
        headers.setContentDispositionFormData("attachment", "data.xlsx");

        // 返回 Excel 文件作为 ResponseEntity
        return ResponseEntity.ok()
                .headers(headers)
                .body(bytes);
    }

2.浏览器测试,输入http://localhost:你的端口号/execl/export即可下载

 

 

导入功能实现

1. 实现数据导入的 Controller

创建另一个 Controller 类,实现从 Excel 文件导入数据并存入数据库的功能:

@PostMapping("/import")
    public ResponseEntity<String> importDataFromExcel(@RequestParam("file") MultipartFile file) throws IOException {
        // 检查文件是否为空
        if (file.isEmpty()) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("文件为空");
        }

        // 用于存储解析后的数据
        List<DataEntity> dataList = new ArrayList<>();

        // 使用try-with-resources自动关闭资源
        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = new XSSFWorkbook(inputStream)) {

            // 获取第一个工作表
            Sheet sheet = workbook.getSheetAt(0);
            int rowNum = 1; // 行号计数器
            for (Row row : sheet) {
                // 跳过表头行
                if (rowNum == 1) {
                    rowNum++;
                    continue;
                }

                // 创建并填充数据实体
                DataEntity data = new DataEntity();
                data.setId((long) row.getCell(0).getNumericCellValue());
                data.setName(row.getCell(1).getStringCellValue());
                data.setAge((int) row.getCell(2).getNumericCellValue());
                data.setEmail(row.getCell(3).getStringCellValue());

                //将字符串转换回 LocalDate 类型
                String birthdayString = row.getCell(4).getStringCellValue();
                LocalDate birthday = LocalDate.parse(birthdayString, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                data.setBirthday(birthday);

                //将字符串转换为 LocalDateTime 类型
                String currentTimeString = row.getCell(5).getStringCellValue();
                LocalDateTime currentTime = LocalDateTime.parse(currentTimeString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                data.setCurrentTime(currentTime);


                // 添加到数据列表
                dataList.add(data);
            }
        }

        // 将数据保存到数据库
        dataService.saveBatch(dataList);

        // 返回成功响应
        return ResponseEntity.ok("数据导入成功");
    }

2.Postman测试

Excel数据 

 

数据库导入成功

 

标签:Java,MM,Excel,导出,createCell,导入,setCellValue,data,row
From: https://blog.csdn.net/m0_59166601/article/details/139881686

相关文章

  • LangChain4j LangChain集成Java
    LangChain4j介绍github地址https://github.com/langchain4j快速开始引入依赖<dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai</artifactId><version>0.31.0</version></dependency&g......
  • Java解析微信获取手机号信息
    在微信中,用户手机号的获取通常是通过微信小程序的getPhoneNumber接口来实现的。这个接口允许用户在授权后,将加密的手机号数据传递给开发者。由于隐私保护,微信不会直接提供用户的明文手机号,而是提供一个加密的手机号字符串和相应的解密密钥。以下是一个基于Java的示例,展示了如何接......
  • Java高手的30k之路|面试宝典|精通JVM(二)
    JVM基本结构类加载子系统:负责将.class文件加载到内存中,并进行验证、准备、解析和初始化。运行时数据区:包括堆(Heap)、方法区(MethodArea)、Java栈(JavaStack)、本地方法栈(NativeMethodStack)和程序计数器(ProgramCounterRegister)。执行引擎:包括解释器(Interpreter)、即时编译器......
  • Java脚本实现在微信聊天框发消息
    最近,有读者问Java脚本如何实现在微信聊天框发消息。首先,需要明确一点:由于微信的安全限制和封闭性,直接使用Java(或任何其他外部编程语言)来控制在微信聊天框中发送消息是不可行的。微信没有提供公开的API来允许外部程序直接与其交互。但是,如果我们的目标是创建一个可以与微信集成的......
  • Java高手的30k之路|面试宝典|精通网络编程
    基础概念OSI和TCP/IP在高级Java开发面试中,关于OSI模型和TCP/IP模型的理解是非常重要的。以下是这两个网络模型及其各层功能的详细解释:OSI模型OSI(OpenSystemsInterconnection)模型是一个概念性框架,用于理解和设计网络通信的不同层次。它分为七层,每层都有特定的功能。......
  • Java脚本实现在微信聊天框发消息
    最近,有读者问Java脚本如何实现在微信聊天框发消息。首先,需要明确一点:由于微信的安全限制和封闭性,直接使用Java(或任何其他外部编程语言)来控制在微信聊天框中发送消息是不可行的。微信没有提供公开的API来允许外部程序直接与其交互。但是,如果我们的目标是创建一个可以与微信集成......
  • 一、若依--P2--P5【黑马程序员Java最新AI+若依框架项目开发新方案视频教程,基于RuoYi-V
    学习视频【黑马程序员Java最新AI+若依框架项目开发新方案视频教程,基于RuoYi-Vue3前后端分离版本,从前端到后端再到AI智能化应用全通关】https://www.bilibili.com/video/BV1pf421B71v/?p=6&share_source=copy_web&vd_source=3949d51b57b2891ea14d6e51c792bef6P2:前端框架搭......
  • java面试题--基础上
    一、说说&和&&的区别?作为运算符:&将二进制的每一位进行与运算作为逻辑运算符:两者都是与,&&如果左边为假则终止右边运算,即短路运算。&则需要把两边的比较执行完。二、int和Integer的区别int是Java的基本数据类型,而Integer是int的包装类int直接存储整数值,而Integer是一个对象,包含......
  • 2024年华为OD机试真题-生成哈夫曼树-(C++/Java/python)-OD统一考试(C卷D卷)
    题目描述给定长度为n的无序的数字数组,每个数字代表二叉树的叶子节点的权值,数字数组的值均大于等于1。请完成一个函数,根据输入的数字数组,生成哈夫曼树,并将哈夫曼树按照中序遍历输出。为了保证输出的二叉树中序遍历结果统一,增加以下限制:二叉树节点中,左节点权值小于右节点......
  • java环境配置
    原文:https://edu.csdn.net/skill/java/java-4ddfc05dbbe54300905f404c1ed1b4f9?category=462&typeId=19824前言为什么写这篇文章呢,因为我不想再去百度搜别人的文章了,所以自己写一篇以作记录。一、准备工作JDK8下载地址JDK11下载地址在这里插入图片描述下载好之后双击exe文......