java 导出Excel表格通用方法

简介: java 导出Excel表格通用方法

目录

背景

最近项目需要导出数据到Excel 表格中,在包装好获取表格方法之后,剩下的就是往单元格中添加数据和添加标题。写了一两个地方之后发现设置数据这块东西基本都是类似的重复代码,无非就是设置的数据不一样而已,看到这样的代码就很烦,想把它们封装起来,首先想到的就是通过自定义注解的方式来实现。

POI版本

我用的是POI导出Excel,版本如下:

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
      <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi</artifactId>
          <version>4.1.1</version>
      </dependency>

自定义注解

首先就自定义了两个注解

1、EnableExcel

这个注解的作用是是否开启Excel表格的导出。

/**
 *  标记类是否开启Excel
 * @Author: Sunlong
 * @date: 2020/5/10 20:29
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableExcel {
}

2、ExcelRow

ExcelRow在属性上使用,对应着Excel中的列

/**
 *  excel 表格 列名注解
 *
 * @author sunlong
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelRow {
    /**
     *  Excel 对应列名
     * @return
     */
    String name();
    /**
     *  excel 列名备注
     * @return
     */
    String note() default "";
}

逻辑代码实现

1、通过反射获取自定义注解EnableExcel 判断是否开启Excel导出

2、通过反射获取自定义注解ExcelRow 获取列对应的属性

3、把属性对应的列下标取出来,属性名做为key,下标做为value放到map中

4、遍历要导出的数据集合,通过属性描述器PropertyDescriptor获取对应属性下标及属性值并设置到cell单元格中


代码如下:

public class ExcelUtils {
    /**
     *  workbook
     * @param titleList
     * @return
     */
    public static HSSFWorkbook getWorkBook(List<String> titleList){
        //第一步,创建一个workbook,对应一个Excel文件
        HSSFWorkbook wb = new HSSFWorkbook();
        // 一个sheet
        HSSFSheet sheet = wb.createSheet("sheet1");
        HSSFRow rowTitle = sheet.createRow(0); // 第一行 标题
        // 设置标题
        for (int i = 0; i < titleList.size(); i++) {
            HSSFCell cell = rowTitle.createCell(i);
            cell.setCellValue(titleList.get(i));
        }
        //合并单元格CellRangeAddress构造参数依次表示起始行,截至行,起始列, 截至列
        /*sheet.addMergedRegion(new CellRangeAddress(0,0,0,4));
        sheet.addMergedRegion(new CellRangeAddress(titleList.size()-1,titleList.size()-1,titleList.size()-1,titleList.size()+1));*/
        return wb;
    }
    public static <T> HSSFWorkbook getWorkBook(List<String> titleList , List<T> dataList) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
        if (CollectionUtils.isNotEmpty(dataList)) {
            T t1 = dataList.get(0);
            Class<?> t1Class = t1.getClass();
            EnableExcel enableExcel = t1Class.getAnnotation(EnableExcel.class);
            if (enableExcel == null) {
                throw new IllegalArgumentException("EnableExcel 注解没有在实体类启用");
            }
            Field[] fields = t1Class.getDeclaredFields();
            if (fields != null && fields.length > 0) {
                Map<String , Integer> titleMap = new HashMap<>(titleList.size()); // 存放属性名称对应的下标
                int fieldExcelSize = 0; // 类中ExcelRow 注解的数量
                for (Field field : fields) {
                    field.setAccessible(true);
                    String fieldName = field.getName();
                    ExcelRow excelRow = field.getAnnotation(ExcelRow.class);
                    if (excelRow != null) {
                        String name = excelRow.name();
                        if (StringUtils.isEmpty(name)) {
                            throw new IllegalArgumentException("ExcelRow 注解name属性不能为空");
                        }
                        int index = titleList.indexOf(name.trim());
                        if (index != -1) {
                            fieldExcelSize++;
                            titleMap.put(fieldName , index);
                        }
                    }
                }
                if (!(titleList.size() == fieldExcelSize)) {
                    throw new IllegalArgumentException("ExcelRow 注解name属性对应的列数不对");
                }
                HSSFWorkbook workBook = getWorkBook(titleList);
                HSSFSheet sheet = workBook.getSheetAt(0);
                for (T t : dataList) {
                    int lastRowNum = sheet.getLastRowNum();
                    HSSFRow row = sheet.createRow(lastRowNum + 1);
                    BeanInfo beanInfo = Introspector.getBeanInfo(t.getClass());
                    PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
                    for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                        String fieldName = propertyDescriptor.getName();
                        if (titleMap.containsKey(fieldName)) {
                            Method readMethod = propertyDescriptor.getReadMethod();
                            if (readMethod != null) {
                                Class<?> returnType = readMethod.getReturnType();
                                String simpleName = returnType.getSimpleName();
                                Object invoke = readMethod.invoke(t);
                                String value = "";
                                // 可以根据不同的类型返回不同的数据
                                if ("date".equalsIgnoreCase(simpleName)) {
                                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                                    if (invoke != null) {
                                        value = simpleDateFormat.format(invoke);
                                    }
                                }
                                if (invoke != null && "".equals(value)) {
                                    value = invoke.toString();
                                }
                                row.createCell(titleMap.get(fieldName)).setCellValue(value);
                            }
                        }
                    }
                }
                return workBook;
            }
        }
        return null;
    }
}

测试

@EnableExcel
@Data
public class UserEntity {
    @ExcelRow(name = "name")
    private String username;
    @ExcelRow(name = "pass")
    private String password;
    @ExcelRow(name = "date")
    private Date createDate;
}
public class Test {
    public static void main(String[] args) throws IllegalAccessException, IntrospectionException, InvocationTargetException, IOException {
        List<String> titleList = new ArrayList<>();
        titleList.add("name");
        titleList.add("pass");
        titleList.add("date");
        List<UserEntity> userEntities = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            UserEntity userEntity1 = new UserEntity();
            userEntity1.setUsername("username"+i);
            userEntity1.setPassword("password"+i);
            userEntity1.setCreateDate(new Date());
            userEntities.add(userEntity1);
        }
        HSSFWorkbook workBook = ExcelUtils.getWorkBook(titleList, userEntities);
        if (workBook != null) {
            File file = new File("D:\\1.xlsx");
            workBook.write(file);
        }
    }
}

结果:

image.png

能力一般,水平有限,如果错误请指出。

目录
相关文章
|
27天前
|
关系型数据库 MySQL Shell
不通过navicat工具怎么把查询数据导出到excel表中
不通过navicat工具怎么把查询数据导出到excel表中
27 0
|
7天前
|
Java Apache Maven
java读取doc里的表格
java读取doc里的表格
20 9
|
1天前
|
存储 Java
java的Excel导出,数组与业务字典匹配并去掉最后一个逗号
java的Excel导出,数组与业务字典匹配并去掉最后一个逗号
17 2
|
2天前
|
存储 数据挖掘 测试技术
Python接口自动化中操作Excel文件的技术方法
通过上述方法和库,Python接口自动化中的Excel操作变得既简单又高效,有助于提升自动化测试的整体质量和效率。
8 0
|
27天前
|
存储 Java Apache
|
1月前
|
SQL 分布式计算 DataWorks
DataWorks产品使用合集之如何直接导出excel文件
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
1月前
|
easyexcel Java 关系型数据库
阿里巴巴-EasyExcel 基于Java的简单、省内存的读写Excel
该文章主要介绍了在Java应用中如何使用EasyExcel技术完成对Excel文件的导入和导出操作,包括环境搭建、基本概念、快速入门、进阶操作和综合应用等内容,并提供了相关代码示例和注意事项。
 阿里巴巴-EasyExcel 基于Java的简单、省内存的读写Excel
|
21天前
|
人工智能 BI
用ChatGPT做excel表格真香!只需动嘴提要求和复制粘贴
用ChatGPT做excel表格真香!只需动嘴提要求和复制粘贴
|
1月前
|
数据管理 数据处理 数据库
分享一个导出数据到 Excel 的解决方案
分享一个导出数据到 Excel 的解决方案
|
4月前
|
前端开发 Java
基于Java爬取微博数据(二) 正文长文本+导出数据Excel
【5月更文挑战第12天】基于Java爬取微博数据,正文长文本+导出数据Excel