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

目录

    • 一、集合转化为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.mfbz.cn/a/192428.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智汇方象惠管家:提升电商系统与广告推广的效率,实现无代码开发的连接

无代码开发的连接优势 在当今快速发展的电商领域&#xff0c;商家们急需一个既能优化电商系统又能提升客服体验的解决方案。智汇方象的惠管家&#xff0c;一个基于云计算的SAAS服务&#xff0c;就是为了满足这一需求而生。这款工具通过无代码开发的方式&#xff0c;使得连接和…

中国北斗:守护萨雷兹湖一方安澜

中国北斗&#xff1a;守护萨雷兹湖一方安澜 在第三届“一带一路”国际合作高峰论坛数字经济高级别论坛上&#xff0c;由中国经济信息社、国家发展改革委高技术司、国家数据局联合编制的《数字“慧”就发展之路》中英文图文集正式发布&#xff0c;展现了中国与共建“一带一路”国…

Codeforces Round 911 (Div. 2) --- D题题解

D. Small GCD Problem - D - Codeforces 题目大意&#xff1a; 给你一个数组&#xff0c;你可以在里面任选三个数ai aj ak&#xff0c;要求i j k 互不相同&#xff0c; 现定义一个函数f(a,b,c)gcd(a,b)&#xff0c;其中a 和 b为a&#xff0c;b&#xff0c;c中较小的两个。求f…

Callable、Future和FutrueTask详解

一、Callable介绍 1.1 Runnable介绍 Runnable是一个接口&#xff0c;里面声明了run方法。但是由于run方法返回值类型为void&#xff0c;所以在执行完成任务后&#xff0c;无法返回任何结果。 FunctionalInterface public interface Runnable {public abstract void run(); }…

SIFT尺度不变特征变换

SIFT(Scale-Invariant Feature Transform)是一种用于图像处理和计算机视觉中的特征提取和匹配的算法。它的主要优点是对图像的尺度、旋转和亮度变化具有较强的鲁棒性。 基本原理: Scale-space peak selection: Potential location for finding features.Keypoint Localizat…

Redis 命令处理过程

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

【活动回顾】ABeam 德硕| 艾宾信息技术开发(西安)西北高校行——与西北三所高校签订校企合作协议

前言 INTRODUCTION 10月下旬&#xff0c;ABeam旗下艾宾信息技术开发&#xff08;西安&#xff09;校招团队来到宁夏大学、青海大学、兰州大学这三所高校&#xff0c;就校企合作达成多项共识并举行了隆重的签约仪式。ABeam大中华区董事长兼总经理中野洋辅先生也特意留出时间莅临…

【活动回顾】sCrypt在2023伦敦区块链大会上的精彩表现

2023伦敦区块链大会&#xff0c;是本年度最盛大的比特币及区块链行业活动。大会于2023年5月31日至6月2日&#xff0c;在伦敦女王伊丽莎白二世中心举行&#xff0c;旨在展示BSV区块链的真正潜力。 sCrypt Inc 的创始人兼 CEO 刘晓晖&#xff0c; 作为演讲嘉宾出席了会议。他向大…

FreeImage 编译安装

FreeImage下载&#xff1a; The FreeImage Project 点击第6行&#xff1a; Download FreeImage 3.18.0 或&#xff1a; wget http://downloads.sourceforge.net/freeimage/FreeImage3170.zip #解压 unzip FreeImage3170.zip -d freeImage 编译FreeImage源代码可能需要遵循…

抓包工具安装

charles的安装 参考链接:[Python3网络爬虫开发实战] 1.7.1-Charles的安装 | 静觅 说明: 1.电脑端+手机端 都需要安装证书,安装证书是为了能抓取https协议的接口 2.手机端设置wifi的网络代理 + 电脑端设置代理端口,即可实现抓包。 特定流量抓包 HttpCanary(安装在手机里…

echarts散点图(象限图)设置不同的颜色

如图所示&#xff1a; <template><div ref"sdtcmijy" :style"{height:scrollerHeight}"></div> </template> <script> import {getXxt} from ./../requestAPI.jsexport default {data(){return {params:{},seriesData:[],…

Vue快速实践总结 · 上篇

文章目录 模板语法数据绑定事件处理计算属性监视属性&#xff08;监听器&#xff09;条件渲染列表渲染数据监视原理内置指令总结生命周期组件化编程组件使用步骤组件的嵌套this指向单文件组件ref、props 脚手架(Vue CLI)render函数 参考自己的Vue专栏以及Vue官方文档 模板语法 …

10 个例子带你学会 AI 编程(含提示词)

大家好&#xff0c;我是伍六七。 AI 编程是一个程序员群体普遍关注的领域&#xff0c;但是真的使用 AI 编程实现提效的还是少数。 有的人没有大模型资源&#xff0c;有的人不知道可以在哪些方面使用 AI 进行提效&#xff0c;还有的人不相信使用 AI 可以提效。 今天&#xff…

用java实现王者荣耀

第一步是创建项目 项目名自拟 第二部创建个包名 来规范class 然后是创建类 GameFrame 运行类 package com.sxt; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; impo…

【开源】基于Vue和SpringBoot的数字化社区网格管理系统

项目编号&#xff1a; S 042 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S042&#xff0c;文末获取源码。} 项目编号&#xff1a;S042&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、开发背景四、系统展示五、核心源码5…

数据结构—树

文章目录 9.树(1).树的基本概念#1.基本定义#2.树的广义表表示法#3.基本术语 (2).树的存储结构#1.标准形式(常用)#2.逆存储形式#3.孩子兄弟存储法 (3).并查集#1.我们到底想解决什么问题#2.并查集结点#2.Find(查)#3.Union(并)#4.例子 (4).树的遍历#1.前序遍历#2.后序遍历#3.遍历的…

PHPExcel 导出Excel报错:PHPExcel_IOFactory::load()

背景 近期在做 excel文件数据导出时&#xff0c;遇到如下报错&#xff1a; iconv(): Detected an illegal character in input string场景&#xff1a;计划任务后台&#xff0c;分步导出 大数据 excel文件发现在加载文件时&#xff0c;会有报错 报错信息 如下&#xff1a; {&q…

锂电池污水如何处理

锂电池是目前应用广泛的重要电池类型&#xff0c;然而其生产过程和废弃处理中产生的污水对环境造成了不可忽视的影响。本文将探讨锂电池污水的处理方法&#xff0c;以期为环境保护和可持续发展作出贡献。 首先&#xff0c;了解锂电池污水的组成是解决问题的关键。锂电池污水通…

物理层之奈氏准则和香农定理

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

DevEco Studio对同一套HarmonyOS代码进行多设备端预览

鸿蒙代码有一个很大的优势 不需要其他的语法 只需要一套HarmonyOS代码 就可以在 手机 平板 电脑上运行 我们可以在DevEco Studio预览器上 点击如下图指向位置 弹出的这个窗口中 我们将右上角的开关勾选上 这样 我们调试器向下滚动 就可以看到多端预览的一个效果了
最新文章