java导出Excle表格

世间万物,始于心,终于行

想要了解本章内容,你得先了解自定义注解.
目录

java中元注解
背景
所用依赖
逻辑代码块
测试

java中元注解

java.lang.annotation 提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解):
@Documented – 注解是否将包含在JavaDoc中 @Retention – 什么时候使用该注解 @Target –
注解用于什么地方 @Inherited – 是否允许子类继承该注解

1.)@Retention – 定义该注解的生命周期 ● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override,
@SuppressWarnings都属于这类注解。 ● RetentionPolicy.CLASS :
在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式 ● RetentionPolicy.RUNTIME :
始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。

2.)Target – 表示该注解用于什么地方。默认值为任何元素,表示该注解用于什么地方。可用的ElementType 参数包括 ● ElementType.CONSTRUCTOR: 用于描述构造器 ● ElementType.FIELD:
成员变量、对象、属性(包括enum实例) ● ElementType.LOCAL_VARIABLE: 用于描述局部变量 ●
ElementType.METHOD: 用于描述方法 ● ElementType.PACKAGE: 用于描述包 ●
ElementType.PARAMETER: 用于描述参数 ● ElementType.TYPE: 用于描述类、接口(包括注解类型)
或enum声明

3.)@Documented – 一个简单的Annotations 标记注解,表示是否将注解信息添加在java 文档中。

4.)@Inherited – 定义该注释和子类的关系
@Inherited 元注解是一个标记注解,@Inherited 阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited 修饰的annotation
类型被用于一个class,则这个annotation 将被用于该class 的子类。

接下来就是自定义注解

package com.yuan.testExcel;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *  excel 表格 列名注解
 *
 * @author yuanzixiang
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelRow {

    /**
     *  Excel 对应列名
     * @return
     */
    String name();

    /**
     *  excel 列名备注
     * @return
     */
    String note() default "";
}

ExcelRow 该注解使用在属性上.

package com.yuan.testExcel;

import java.lang.annotation.ElementType; import
java.lang.annotation.Retention; import
java.lang.annotation.RetentionPolicy; import
java.lang.annotation.Target;

/** * excel 表格 列名注解 * * @author yuanzixiang */
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public
@interface ExcelRow {

/**
 *  Excel 对应列名
 * @return
 */
String name();

/**
 *  excel 列名备注
 * @return
 */
String note() default ""; }

背景
最近在面试的时候被问到有没有用过java操作Excel,直接就是当场尬住,所以这几天狠狠研究了一下这个东西。

所用依赖
如果版本有不同有冲突,请自行去maven仓库拉取

  <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>4.1.1</version>
  </dependency>

逻辑代码块

/**
     *  workbook
     * @param titleList
     * @return
     */
    public static HSSFWorkbook getWorkBook(List<String> titleList){
        //第一步,创建一个workbook,对应一个Excel文件
        HSSFWorkbook wb = new HSSFWorkbook();
        // 一个sheet
        HSSFSheet sheet = wb.createSheet("工作表名");

       // 第一行 标题
        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, IllegalAccessException, InvocationTargetException {
        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;
    }

测试
/**
* 测试Excel表格导出
* @param args
*/
public static void main(String[] args) throws IllegalAccessException, IntrospectionException, InvocationTargetException, IOException {

            List<String> titleList = new ArrayList<>();
            titleList.add("哈");
            titleList.add("哈哈");
            titleList.add("Date");

            List<ExcelEntity> userEntities = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                ExcelEntity excelEntity = new ExcelEntity();
                excelEntity.setUsername("username"+i);
                excelEntity.setPassword("password"+i);
                excelEntity.setCreateDate(new Date());
                userEntities.add(excelEntity);
            }

            HSSFWorkbook workBook = ExcelUtils.getWorkBook(titleList, userEntities);
            if (workBook != null) {
                File file = new File("D:\\1.xlsx");
                workBook.write(file);
            }
            System.out.println("导出成功");

        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值