Springboot 导入导出Excel ,一对多关系,复合表格、合并单元格数据

简介: Springboot 导入导出Excel ,一对多关系,复合表格、合并单元格数据

前言



学习是自己的事。


但是跟着我学习,也未尝不可。


这种一对多的导出需求,好像确实也是比较常见的:


image.png


表面拒绝,反手上演一手实战示例。


内容:


① 一对多关系数据 (合并单元格)数据的 导出

②一对多关系数据 (合并单元格)数据的 导入

导入导出一块给整了,直接杀死比赛。


(看官们,收藏起来,以后备用。顺手给我点个赞。)


之前写过一篇极其简单的excel导入导出,是单个文件的:


Springboot 最简单的结合MYSQL数据实现EXCEL表格导出及数据导入_小目标青年的博客-CSDN博客


还写过一篇单个,多个 excel文件导出,转成ZIP包的:


SpringBoot 导出多个Excel文件,压缩成.zip格式下载_小目标青年的博客-CSDN博客


还有指定模板导出的:

Springboot 指定自定义模板导出Excel文件_小目标青年的博客-CSDN博客_自定义导出excel


正文



模拟一个这种数据的业务场景:


image.png


效果,数据导出:


image.png实战:


先看看工程目录结构:


image.png


pom.xml 引入核心依赖:


    <dependencies>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-spring-boot-starter</artifactId>
            <version>4.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>


这篇文章核心就是使用easypoi 的 注解

@Excel()

合并单元格、复合表格的关键注解

@ExcelCollection()

项目小组类

ProjectGroupExcelVO.java


import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelCollection;
import lombok.Data;
import java.util.List;
/**
 * @Author: JCccc
 * @Description:
 * @Date: 1/1/1 1:11
 */
@Data
public class ProjectGroupExcelVO {
    @Excel(name = "小组名称", needMerge = true, width = 20,height = 8)
    private String groupName;
    @Excel(name = "小组口号", needMerge = true, width = 20,height = 8)
    private String groupSlogan;
    @Excel(name = "小组类型", needMerge = true, width = 20,height = 8)
    private String groupType;
    @ExcelCollection(name = "组员信息")
    private List<GroupUserExcelVO> groupUsers;
}


简析:


image.png


组员的类


GroupUserExcelVO.java


import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
/**
 * @Author: JCccc
 * @Description:
 * @Date: 1/1/1 1:11
 */
@Data
public class GroupUserExcelVO {
    @Excel(name = "组员名字", width = 20,height = 8)
    private String name;
    @Excel(name = "组员电话", width = 20,height = 8)
    private String phone;
    @Excel(name = "年龄",  width = 20,height = 8)
    private Integer age;
}


导入导出工具类一个


MyExcelUtils.java


import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.NoSuchElementException;
/**
 * @Author: JCccc
 * @Description:
 * @Date: 1/1/1 1:11
 */
public class MyExcelUtils {
    /**
     * 功能描述:复杂导出Excel,包括文件名以及表名,不创建表头
     *
     * @param list 导出的实体类
     * @param title 表头名称
     * @param sheetName sheet表名
     * @param pojoClass 映射的实体类
     * @param fileName
     * @param response
     * @return
     */
    public static void exportExcel( List<?> list, String title, String sheetName, Class<?> pojoClass,
                                       String fileName, HttpServletResponse response) {
        defaultExport(list, pojoClass, fileName, response, new ExportParams(title, sheetName));
    }
    /**
     * 功能描述:默认导出方法
     *
     * @param list 导出的实体集合
     * @param fileName 导出的文件名
     * @param pojoClass pojo实体
     * @param exportParams ExportParams封装实体
     * @param response
     * @return
     */
    private static void defaultExport(  List<?> list, Class<?> pojoClass, String fileName,
                                          HttpServletResponse response, ExportParams exportParams) {
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, pojoClass, list);
        if (workbook != null) {
            downLoadExcel(fileName, response, workbook);
        }
    }
    /**
     * 功能描述:Excel导出
     *
     * @param fileName 文件名称
     * @param response
     * @param workbook Excel对象
     * @return
     */
    private static void downLoadExcel(  String fileName, HttpServletResponse response,
                                          Workbook workbook) {
        try {
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "multipart/form-data");
            response.setHeader("Content-Disposition",
                    "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 功能描述:根据接收的Excel文件来导入Excel,并封装成实体类
     *
     * @param file 上传的文件
     * @param titleRows 表标题的行数
     * @param headerRows 表头行数
     * @param pojoClass Excel实体类
     * @return
     */
    public static <T> List<T> importExcel(  MultipartFile file, Integer titleRows, Integer headerRows,
                                              Class<T> pojoClass) {
        if (file == null) {
            return null;
        }
        ImportParams params = new ImportParams();
        params.setTitleRows(titleRows);
        params.setHeadRows(headerRows);
        List<T> list = null;
        try {
            list = ExcelImportUtil.importExcel(file.getInputStream(), pojoClass, params);
        } catch (NoSuchElementException e) {
            throw new RuntimeException("excel文件不能为空");
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        return list;
    }
}


导出接口:


TestController.java


import com.jc.excel.excelVO.GroupUserExcelVO;
import com.jc.excel.excelVO.ProjectGroupExcelVO;
import com.jc.excel.util.MyExcelUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
/**
 * @Author: JCccc
 * @Description:
 * @Date: 1/1/1 1:11
 */
@RestController
public class TestController {
    /**
     * excel导出 
     *
     * @return
     */
    @GetMapping(value = "/exportTest")
    public void export(HttpServletResponse response) {
        List<ProjectGroupExcelVO> projectGroupList=new ArrayList<>();
        //小组A数据模拟
        ProjectGroupExcelVO groupA=new ProjectGroupExcelVO();
        groupA.setGroupName("小组A");
        groupA.setGroupSlogan("天天向上,爱学习!");
        groupA.setGroupType("奋斗类型");
        List<GroupUserExcelVO> groupUserAList=new ArrayList<>();
        GroupUserExcelVO groupUser1=new GroupUserExcelVO();
        groupUser1.setName("小收");
        groupUser1.setPhone("123456");
        groupUser1.setAge(18);
        GroupUserExcelVO groupUser2=new GroupUserExcelVO();
        groupUser2.setName("小藏");
        groupUser2.setPhone("654321");
        groupUser2.setAge(20);
        groupUserAList.add(groupUser1);
        groupUserAList.add(groupUser2);
        groupA.setGroupUsers(groupUserAList);
        //小组B数据模拟
        ProjectGroupExcelVO groupB=new ProjectGroupExcelVO();
        groupB.setGroupName("小组B");
        groupB.setGroupSlogan("跟着JC学java,稳!");
        groupB.setGroupType("努力类型");
        List<GroupUserExcelVO> groupBUserBList=new ArrayList<>();
        GroupUserExcelVO groupUserB1=new GroupUserExcelVO();
        groupUserB1.setName("小点");
        groupUserB1.setPhone("123456");
        groupUserB1.setAge(12);
        GroupUserExcelVO groupUserB2=new GroupUserExcelVO();
        groupUserB2.setName("小赞");
        groupUserB2.setPhone("654321");
        groupUserB2.setAge(15);
        GroupUserExcelVO groupUserB3=new GroupUserExcelVO();
        groupUserB3.setName("JCccc");
        groupUserB3.setPhone("136919xxxxx");
        groupUserB3.setAge(10000);
        groupBUserBList.add(groupUserB1);
        groupBUserBList.add(groupUserB2);
        groupBUserBList.add(groupUserB3);
        groupB.setGroupUsers(groupBUserBList);
        projectGroupList.add(groupA);
        projectGroupList.add(groupB);
        String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss"));
        MyExcelUtils.exportExcel(projectGroupList,
                "小组信息",
                "小组信息",
                ProjectGroupExcelVO.class,
                "小组信息文件"+time+".xls",response);
    }
}


调用一下看看导出的效果:


image.png


非常OK:


image.png


接下来是导入,写个简单接口玩一下:


数据:


image.png导入 接口代码:

    /**
     * excel导入
     *
     * @return
     */
    @PostMapping(value = "/importTest")
    public void importTest( @RequestParam("file") MultipartFile file) {
        List<ProjectGroupExcelVO> projectGroupExcelVOList = MyExcelUtils.importExcel(file, 1, 2, ProjectGroupExcelVO.class);
        System.out.println(projectGroupExcelVOList.toString());
        System.out.println("-----------------------------------");
        System.out.println("写入数据库");
    }


调用看看效果:


image.pngimage.png


导入成功,就是如此简单。

相关文章
|
7月前
|
Python
如何根据Excel某列数据为依据分成一个新的工作表
在处理Excel数据时,我们常需要根据列值将数据分到不同的工作表或文件中。本文通过Python和VBA两种方法实现该操作:使用Python的`pandas`库按年级拆分为多个文件,再通过VBA宏按班级生成新的工作表,帮助高效整理复杂数据。
|
7月前
|
数据采集 数据可视化 数据挖掘
用 Excel+Power Query 做电商数据分析:从 “每天加班整理数据” 到 “一键生成报表” 的配置教程
在电商运营中,数据是增长的关键驱动力。然而,传统的手工数据处理方式效率低下,耗费大量时间且易出错。本文介绍如何利用 Excel 中的 Power Query 工具,自动化完成电商数据的采集、清洗与分析,大幅提升数据处理效率。通过某美妆电商的实战案例,详细拆解从多平台数据整合到可视化报表生成的全流程,帮助电商从业者摆脱繁琐操作,聚焦业务增长,实现数据驱动的高效运营。
|
9月前
|
存储 安全 大数据
网安工程师必看!AiPy解决fscan扫描数据整理难题—多种信息快速分拣+Excel结构化存储方案
作为一名安全测试工程师,分析fscan扫描结果曾是繁琐的手动活:从海量日志中提取开放端口、漏洞信息和主机数据,耗时又易错。但现在,借助AiPy开发的GUI解析工具,只需喝杯奶茶的时间,即可将[PORT]、[SERVICE]、[VULN]、[HOST]等关键信息智能分类,并生成三份清晰的Excel报表。告别手动整理,大幅提升效率!在安全行业,工具党正碾压手动党。掌握AiPy,把时间留给真正的攻防实战!官网链接:https://www.aipyaipy.com,解锁更多用法!
|
7月前
|
JSON Java 数据格式
Spring Boot返回Json数据及数据封装
在Spring Boot中,接口间及前后端的数据传输通常使用JSON格式。通过@RestController注解,可轻松实现Controller返回JSON数据。该注解是Spring Boot新增的组合注解,结合了@Controller和@ResponseBody的功能,默认将返回值转换为JSON格式。Spring Boot底层默认采用Jackson作为JSON解析框架,并通过spring-boot-starter-json依赖集成了相关库,包括jackson-databind、jackson-datatype-jdk8等常用模块,简化了开发者对依赖的手动管理。
702 3
|
7月前
|
Python
将Excel特定某列数据删除
将Excel特定某列数据删除
|
数据采集 数据可视化 数据挖掘
利用Python自动化处理Excel数据:从基础到进阶####
本文旨在为读者提供一个全面的指南,通过Python编程语言实现Excel数据的自动化处理。无论你是初学者还是有经验的开发者,本文都将帮助你掌握Pandas和openpyxl这两个强大的库,从而提升数据处理的效率和准确性。我们将从环境设置开始,逐步深入到数据读取、清洗、分析和可视化等各个环节,最终实现一个实际的自动化项目案例。 ####
2304 10
|
数据采集 存储 JavaScript
自动化数据处理:使用Selenium与Excel打造的数据爬取管道
本文介绍了一种使用Selenium和Excel结合代理IP技术从WIPO品牌数据库(branddb.wipo.int)自动化爬取专利信息的方法。通过Selenium模拟用户操作,处理JavaScript动态加载页面,利用代理IP避免IP封禁,确保数据爬取稳定性和隐私性。爬取的数据将存储在Excel中,便于后续分析。此外,文章还详细介绍了Selenium的基本设置、代理IP配置及使用技巧,并探讨了未来可能采用的更多防反爬策略,以提升爬虫效率和稳定性。
799 4
|
关系型数据库 MySQL Shell
不通过navicat工具怎么把查询数据导出到excel表中
不通过navicat工具怎么把查询数据导出到excel表中
196 0
|
12月前
|
分布式计算 Hadoop 大数据
从Excel到Hadoop:数据规模的进化之路
从Excel到Hadoop:数据规模的进化之路
271 10
|
存储 Java easyexcel
招行面试:100万级别数据的Excel,如何秒级导入到数据库?
本文由40岁老架构师尼恩撰写,分享了应对招商银行Java后端面试绝命12题的经验。文章详细介绍了如何通过系统化准备,在面试中展示强大的技术实力。针对百万级数据的Excel导入难题,尼恩推荐使用阿里巴巴开源的EasyExcel框架,并结合高性能分片读取、Disruptor队列缓冲和高并发批量写入的架构方案,实现高效的数据处理。此外,文章还提供了完整的代码示例和配置说明,帮助读者快速掌握相关技能。建议读者参考《尼恩Java面试宝典PDF》进行系统化刷题,提升面试竞争力。关注公众号【技术自由圈】可获取更多技术资源和指导。

热门文章

最新文章