Java实现集合和Excel文件相互转换

news2024/11/25 22:31:48

目录

    • 一、集合转化为Excel文件
    • 二、Excel文件转化为集合

一、集合转化为Excel文件

效果如下,是将集合转化为Excel文件,Excel包含合并单元格。
在这里插入图片描述
实体类:

@Data
public class ClassGrade {
    /** 年级 */
    private String grade;
    /** 班主任 */
    private String leader;
    /** 学生列表 */
    private List<Student> students;

    @Data
    public static class Student {
        /** 姓名 */
        private String name;
        /** 年龄 */
        private Integer age;
        /** 性别 */
        private String sex;
        /** 成绩 */
        private Integer gradeResult;
    }
}

需求就是将ClassGrade的集合转化为Excel表格对外输出。没有针对当前类去逐个取值处理,用到了反射来处理,达到了简化代码通用的目的。这个只针对有一个合并单元格的情形,如果是合并单元格中包含合并单元格的话,还需要加代码去处理。
实现代码如下:
1.初始化表头类,参数为表头集合

    public static SXSSFWorkbook makeExcelHead(String[] titles) {
        SXSSFWorkbook workbook = new SXSSFWorkbook();
        CellStyle styleTitle = getTitleStyle(workbook, (short) 16);
        SXSSFSheet sheet = workbook.createSheet();
        SXSSFRow rowTitle = sheet.createRow(0);
        for (int i = 0; i < titles.length; i++) {
            sheet.setDefaultColumnWidth(25);
            SXSSFCell cellTitle = rowTitle.createCell(i);
            // 为标题设置背景颜色
            styleTitle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            styleTitle.setFillForegroundColor(HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex());
            cellTitle.setCellValue(titles[i]);
            cellTitle.setCellStyle(styleTitle);
        }
        return workbook;
    }

2.反射获取实体的值

    public static <T> Object getProperty(T t, String propertyName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, IndexOutOfBoundsException {
        Class<?> aClass = t.getClass();
        propertyName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        Method method = aClass.getMethod("get" + propertyName);
        Object invoke = method.invoke(t);
        return invoke;
    }

2.将集合转化为Excel

    @Test
    public void exportExcel() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        //初始化数据
        List<ClassGrade> fileList = new ArrayList<>();
        for (int m = 1; m <= 1; m++) {
            fileList.addAll(getGrades());
        }

        //表头名称
        String[] title = {"班主任", "学生姓名", "学生年龄", "学生性别", "学生成绩", "班级"};
        SXSSFWorkbook workbook = SXSSFWorkbookUtil.makeExcelHead(title);

        //每一列表头属性,如果子类里面的,则提取子类里面对应的属性名
        String[] properties = {"leader", "name", "age", "sex", "gradeResult", "grade"};

        //获取当前sheet
        SXSSFSheet sheet = workbook.getSheetAt(0);
        int initRowNum = 0;
        //遍历数据,需要根据业务逻辑去处理是否合并单元格
        for (int i = 0; i < fileList.size(); i++) {
            ClassGrade file = fileList.get(i);
            int size = file.getStudents().size();

			//创建行,以子类的集合数为准
            int startRowNum = initRowNum + 1;
            int lastRowNum = startRowNum + size - 1;
            SXSSFRow row = sheet.getRow(startRowNum);
            if (row == null) {
                row = sheet.createRow(startRowNum);
            }

            //班主任一列,处理合并单元格
            for (int m = 0; m < 1; m++) {
                if (lastRowNum - startRowNum > 0) {
                    sheet.addMergedRegion(new CellRangeAddress(startRowNum, lastRowNum, m, m));
                }
                createCell(row, m, SXSSFWorkbookUtil.getProperty(file, properties[m]));
            }

            //处理学生姓名~学生成绩四列,非合并单元格信息
            int xRowNum = startRowNum;
            List<ClassGrade.Student> receiptItems = file.getStudents();
            for (ClassGrade.Student student : receiptItems) {
                SXSSFRow row1 = sheet.getRow(xRowNum);
                if (row1 == null) {
                    row1 = sheet.createRow(xRowNum);
                }
                for (int q = 1; q <= 4; q++) {
                	//利用反射获取到值,并且设置到cell里面
                    createCell(row1, q, SXSSFWorkbookUtil.getProperty(student, properties[q]));
                }
                xRowNum++;
            }

            //处理班级信息合并单元格
            for (int n = 5; n <= 5; n++) {
                if (lastRowNum - startRowNum >= 1) {
                    sheet.addMergedRegion(new CellRangeAddress(startRowNum, lastRowNum, n, n));
                }
                createCell(row, n, SXSSFWorkbookUtil.getProperty(file, properties[n]));
            }
            initRowNum = lastRowNum;

        }

        //导出
        try (
                FileOutputStream excel = new FileOutputStream("excel.xls");
                BufferedOutputStream bos = new BufferedOutputStream(excel)) {
            workbook.write(bos);
            System.out.println("导出完成");
        } catch (
                IOException e) {
            System.out.println("导出失败:" + e.getMessage());
        }

    }

    private void createCell(SXSSFRow row, int column, Object value) {
        SXSSFCell cell = row.createCell(column);
        if (value != null) {
            cell.setCellValue(String.valueOf(value));
        }
    }

效果
在这里插入图片描述

二、Excel文件转化为集合

如题,将获取到的excel文件流转化为集合进行处理。挺简单的。思路就是将一个文件流转化为一个备用类,再将备用类转化为想要的集合。
excel:
在这里插入图片描述
备用类代码:

@Data
public class ClassGrade2 {
    /** 年级 */
    private String grade;
    /** 班主任 */
    private String leader;
    /** 姓名 */
    private String name;
    /** 年龄 */
    private Integer age;
    /** 性别 */
    private String sex;
    /** 成绩 */
    private Integer gradeResult;
}

转化代码:

    @Test
    public void test1() {
        ExcelReader reader = ExcelUtil.getReader("excelToList.xls");
        List<List<Object>> rows = reader.read();
        //根据excel的结构,需要准备一个备用类接收数据
        List<ClassGrade2> listBaks = new ArrayList<>();

        //初始化属性,属性是备用类的属性名
        String[] properties = {"leader", "name", "age", "sex", "gradeResult", "grade"};
        for (int j = 1; j < rows.size(); j++) {
            List<Object> cells = rows.get(j);
            try {
                //反射获取值,组装成备用类
                ClassGrade2 file = new ClassGrade2();
                Class<?> clz = file.getClass();
                Method[] methods = clz.getDeclaredMethods();
                for (int i = 0; i < cells.size(); i++) {
                    String propertyName = properties[i].substring(0, 1).toUpperCase() + properties[i].substring(1);
                    Method method = Arrays.stream(methods).filter(m -> Objects.equal(m.getName(), "set" + propertyName)).findFirst().orElse(null);
                    Object cell = cells.get(i);
                    if (cell == null) {
                        continue;
                    }
                    Field field = clz.getDeclaredField(properties[i]);
                    String fieldType = field.getType().getName();
                    if (fieldType.equals("java.lang.String")) {
                        method.invoke(file, String.valueOf(cell));
                    } else if (fieldType.equals("java.math.BigDecimal")) {
                        method.invoke(file, new BigDecimal(String.valueOf(cell)));
                    }
                }
                listBaks.add(file);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } finally {

            }
        }
        //备用类转化为想要的集合类
        int i = 0;
        List<ClassGrade> files = new ArrayList<>();
        for (int m = 0; m < listBaks.size(); m++) {
            ClassGrade2 fileBak = listBaks.get(m);
            if (Strings.isNotEmpty(fileBak.getGrade())) {
                ClassGrade file = BeanUtil.copyProperties(fileBak, ClassGrade.class);
                files.add(file);

                ClassGrade.Student item = BeanUtil.copyProperties(fileBak, ClassGrade.Student.class);
                List<ClassGrade.Student> items = new ArrayList<>();
                items.add(item);
                file.setStudents(items);
                i++;
            } else {
                ClassGrade.Student item = BeanUtil.copyProperties(fileBak, ClassGrade.Student.class);
                ClassGrade file = files.get(i - 1);
                List<ClassGrade.Student> items = CollectionUtils.isEmpty(file.getStudents()) ? new ArrayList<>() : file.getStudents();
                items.add(item);
                file.setStudents(items);
            }
        }
        log.info("{}", JSONArray.toJSONString(listBaks));
        log.info("{}", JSONArray.toJSONString(files));
    }

实现效果:

11:47:03.635 [main] INFO Excel3Test - [{"grade":"八年级1班","leader":"赵老师","name":"张三","sex":"女"},{"grade":"八年级1班","leader":"赵老师","name":"李四","sex":"女"},{"grade":"八年级1班","leader":"赵老师","name":"王五","sex":"女"}]
11:47:03.647 [main] INFO Excel3Test - [{"grade":"八年级1班","leader":"赵老师","students":[{"name":"张三","sex":"女"}]},{"grade":"八年级1班","leader":"赵老师","students":[{"name":"李四","sex":"女"}]},{"grade":"八年级1班","leader":"赵老师","students":[{"name":"王五","sex":"女"}]}]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1257827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

其利天下技术总监冯建武受邀出席“2023年电子工程师大会”并作主题演讲

2023年11月23日&#xff0c;由华秋电子发烧友主办的“2023年电子工程师大会暨第三届社区年度颁奖活动”在深圳新一代产业园成功举行。本次年度颁奖活动邀请了高校教授、企业高管、行业专家、资深电子工程师等共300多人出席。聚焦“电机驱动技术”、“开源硬件”、“OpenHarmony…

sCrypt 在英国伦敦 Exeter 大学讲学

6月5日&#xff0c;sCrypt CEO晓晖和他的两位同事在英国伦敦Exeter大学举行了一场精彩的讲座。刘晓晖向听众们详细介绍了sCrypt智能合约开平台&#xff0c;并演示了如何使用sCrypt来开发基于比特币的智能合约。他用生动形象的语言&#xff0c;深入浅出地解释了这个领域复杂而又…

三方支付接口成为了电商竞争力的新动力

在当前快速发展的互联网时代&#xff0c;随着电子商务行业的兴起&#xff0c;支付体验已经成为企业获取竞争优势的重要因素。一个快速、安全、便捷的支付环节不仅可以提升用户的体验&#xff0c;还能有效促进交易的完成。在众多支付解决方案中&#xff0c;三方支付接口因其独特…

家用净水器产业分析:预计2029年将达到293亿美元

近年来&#xff0c;政府陆续出台了一系列鼓励居民安装家用净水器的政策措施。这些政策不仅提高了消费者的购买积极性&#xff0c;还促进了相关企业的研发和生产。此外&#xff0c;各级媒体也对家用净水器的重要性进行广泛宣传&#xff0c;增加了公众的认知度和接受度。 随着科技…

动起来,数据不散漏:上海迅软DSE助您解锁员工外带电脑信息安全新境界!

笔记本电脑作为企业数据泄密主要的途径之一&#xff0c;当员工携带着存放企业重要技术资料的笔记本在外办公时&#xff0c;很容易由于频繁的流动性让数据面临着丢失、恶意泄密等巨大风险&#xff0c;对此企事业单位需要通过一定的管理手段加以安全防护管控。 迅软DSE解决方案 一…

2023年双十二超声波清洗机如何选?有哪些值得购买的超声波清洗机?

通过眼科医院对近视眼统计报告说明&#xff0c;截止2023年3月27日&#xff0c;全国近视眼人数为3亿人&#xff0c;其中青少年近视约为2亿人&#xff0c;现在大部分人都离不开眼镜&#xff0c;也有很多人忽视了清洗眼镜的重要性&#xff0c;眼镜长时间的不清洗的话会很容易导致脸…

基于acme免费申请泛域名证书

参考文档&#xff1a;https://github.com/acmesh-official/acme.sh 文章目录 step1: 获取阿里云的ak、skstep2: 安装acmestep3: 安装通配符证书step4: 查看证书step5: 证书的使用step6: 删除证书 step1: 获取阿里云的ak、sk export Ali_Key"LTAI5tG8888888CDoEjLzkE"…

Grabcut算法在图片分割中的应用

GrabCut算法原理 Grabcut是基于图割(graph cut)实现的图像分割算法&#xff0c;它需要用户输入一个bounding box作为分割目标位置&#xff0c;实现对目标与背景的分离/分割&#xff0c;与KMeans与MeanShift等图像分割方法不同。 Grabcut分割速度快&#xff0c;效果好&#xff0…

Redis入门保姆级教程

1. Redis入门 1.1 Redis简介 Redis是一个基于内存的key-value结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件。 官网:https://redis.io 中文网:https://www.redis.net.cn/ key-value结构存储&#xff1a; 主要特点&#xff1a; 基于内存存储&#xff0c;读写…

数据资产入表在即,企业要从数据治理入手

数据是驱动数字经济发展的核心生产要素&#xff0c;数据资产化是释放数据要素价值的重要方式。2024年1月1日&#xff0c;《企业数据资源相关会计处理暂行规定》将正式实施。企业数据资产入表已进入倒计时&#xff0c;企业作如何充分发挥海量规模数据和应用场景等优势&#xff0…

编程题 :简单的洗牌算法的实现

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 目录 &#x1f324;️简单的洗牌算法…

探索接口测试:SOAP、RestFul规则、JMeter及市面上的接口测试工具

引言 在当今软件开发领域&#xff0c;接口测试扮演着至关重要的角色。随着系统变得日益复杂和互联&#xff0c;对于内部和外部接口的测试变得愈发关键。接口测试不仅仅是验证接口的正确性&#xff0c;更是确保系统的稳定性、安全性和性能优越性的关键一环。 本篇博客将带您深入…

嘴尚绝卤味添加草本物质的奥秘,让你品尝健康美味

每当提起卤味&#xff0c;相信很多人的口水都会开始分泌。确实&#xff0c;卤味作为一种深受人们喜爱的美食&#xff0c;其独特的口感和味道总是能够满足人们的味蕾。而在众多卤味品牌中&#xff0c;嘴尚绝卤味因其添加了草本物质而备受关注。那么&#xff0c;嘴尚绝卤味为什么…

科研工具推荐之ReadPaper

科研工具推荐之ReadPaper 之前也用很多朋友在问英文文献如何阅读&#xff0c;一直推荐的是Adobe PDF有道翻译。 但是呢&#xff0c;最近了解到了另外一个神器 ReadPaper 自己稍微体验了一下 感觉非常nice&#xff0c;特此推荐给大家。 想体验的朋友可以通过下面的方式注册呢…

【发表案例】新增2区SCI/SSCI/EI,最快19天录用!国人友好!

综合类EI ☑️检索数据库&#xff1a;EI &Scopus &Google Scholar ☑️版面类别&#xff1a;正刊 ☑️数据库收录年份&#xff1a;2009年 ☑️国人占比&#xff1a;47%&#xff0c;对国人友好 ☑️年发文量&#xff1a;20篇左右 ☑️接收领域&#xff1a;生物&am…

智慧城市政务一网统管解决方案:PPT全文34页,附下载

关键词&#xff1a;智慧政务解决方案&#xff0c;智慧城市解决方案&#xff0c;智慧政务一网统管解决方案&#xff0c;一网统管治理理念&#xff0c;一网统管治理体系&#xff0c;一网统管治理手段&#xff0c;智慧政务综合服务平台建设 一、智慧城市政务一网统管建设背景 一…

Redis 命令处理过程

我们知道 Redis 是一个基于内存的高性能键值数据库, 它支持多种数据结构, 提供了丰富的命令, 可以用来实现缓存、消息队列、分布式锁等功能。 而在享受 Redis 带来的种种好处时, 是否曾好奇过 Redis 是如何处理我们发往它的命令的呢&#xff1f; 本文将以伪代码的形式简单分析…

Linux操作系统使用及C高级编程-D15D16内存管理和动态内存使用

内存分区 使用size查看内存使用 动态内存使用 不能返回局部变量的引用&#xff0c;局部变量存放在栈区&#xff0c;空间随着函数结束自动释放 动态申请内存 内存泄漏和内存溢出

【沐风老师】3DMAX快速地板屋顶墙面铺设插件使用方法详解

3DMAX快速地板屋顶墙面铺设插件使用教程 3DMAX快速地板屋顶墙面铺设插件&#xff0c;一键生成各种地板、墙面纹理模型&#xff0c;是一款非常实用的室内设计和建筑建模插件。 【适用版本】 3dMax7或更新版本 【安装方法】 该插件无需安装&#xff0c;直接在建模过程中使用&a…

互联网上门预约按摩软件新模式

随着移动互联网的发展&#xff0c;人们越来越注重生活质量。其中&#xff0c;按摩作为一种保健方式受到了广大消费者的青睐。为了满足用户的这一需求&#xff0c;我们计划开发一款按摩小程序软件&#xff0c;那么&#xff0c;这款软件需要具备哪些功能呢&#xff1f;本文将从用…