• java Excel导出工具类


    Excel工具类

    一、开发原因

    最近工作的时候,正在写关于Excel导出功能,由于当前使用的工具类不太灵活和不易看懂,自己从头写又很浪费时间等原因,我决定自己写一款很简单的Excel导出的工具类,仅仅是出于学习的目的。

    二、工具类的使用

    基于HSSFWorkbook,介绍如下:
    首先需要一个Maven依赖:

            <dependency>
                <groupId>org.apache.poigroupId>
                <artifactId>poiartifactId>
                <version>5.0.0version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    工具类的名称是ExcelUtil,类中包含两个主要的方法可以来调用:

    在这里插入图片描述

    本方法有两个形参,分别是String fileName(文件名), List dataList(数据列表)

    具体使用方法如下:
    首先创建一个数据列表,一般都是从数据库获取,这里我手动创建一个:

    public static List<List<Object>> listData() {
    
            List<List<Object>> dataList = new ArrayList<>();  //所需要的数据列表的类型
            String[] thStrings = {"id", "名字", "性别", "年龄", "籍贯", "学历"};
            //表头数据
            ArrayList<Object> th = new ArrayList<>(Arrays.asList(thStrings));
            dataList.add(th);   // 将表头数据放入数据列表中
    
            //表格数据
            ArrayList<Object> data = new ArrayList<>();
            data.add("001");
            data.add("iKun");
            data.add("man");
            data.add(18);
            data.add("美国");
            data.add("rap博士");
    
            for (int i = 0; i < 200; i++) {
                dataList.add(data);  // 循环将200个iKun放入数据列表中
            }
    
            return dataList;
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在main中使用:

        public static void main(String[] args) {
            String title = "Excel";   // 文件名
            List<List<Object>> listData = listData(); // 数据列表
    
            ExcelUtil excelUtil = new ExcelUtil();
            Boolean result = excelUtil.exportExcelList(title, listData);
            System.out.println("result = " + result);
    
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    导出成功后会返回一个:
    在这里插入图片描述
    导出的文件如下:
    在这里插入图片描述

    第二个方法是基于类的的反射和注解,主要是导出对应的实体类对象列表数据
    在这里插入图片描述

    exportExcelClass形参是三个,分别是String fileName(导出Excel的文件名), Class
    aClass(导出对应实体类类的反射), List dataList(对象集合的数据列表)

    本方法是基于类的反射和注解实现的,首先在需要导出的实体类中的属性上方添加一注解,如下:
    在这里插入图片描述
    此注解有两个参数:value(表头)order(表格的列顺序,从小到大,从左向右排列,默认值为0)
    在这里插入图片描述

    将注解写在实体类的属性上以后,还是首先创建一个数据列表:

     private static List<Student> studentListData() {
            List<Student> studentList = new ArrayList<>();
            Student iKun = new Student(18, "KunKun", 2.5, new Date());
            for (int i = 0; i < 10; i++) {
                studentList.add(iKun);
            }
    
            return studentList;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在main中使用:

     public static void main(String[] args) {
            String title = "iKun花名册";   // 文件名
            List<Student> studentList = studentListData();  //数据列表
    
            ExcelUtil<Student> excelUtil = new ExcelUtil<>();
            Boolean aBoolean = excelUtil.exportExcelClass(title, Student.class, studentList);
            System.out.println("aBoolean = " + aBoolean);
    
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    最终导出的结果:

    在这里插入图片描述

    上述就是工具类的使用。

    三、工具类的介绍

    类有以下几个属性和方法:

    在这里插入图片描述

    其中 wb; getWb() getSheet() outputFile() 不必过于关注。

    主要是剩余方法:
    setCellStyle(设置单元格的样式)
    exportExcelClass(根据实体类导出数据)
    exportExcelList(根据list列表导出数据)
    其中exportExcelClass调用了exportExcelList,exportExcelList调用了setCellStyle

    1、表头样式
    在这里插入图片描述
    2、数据样式
    在这里插入图片描述
    数据分为文本数据和数字数据,可根据需要修改

    3、标题样式
    在这里插入图片描述

    四、源码

    注解接口类:

    import java.lang.annotation.*;
    
    @Documented
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD, ElementType.METHOD})
    public @interface ExportExcel {
        String value() default "";  //表头
    
        int order() default 0;  // 顺序
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    工具实现类:

    import org.apache.poi.hssf.usermodel.*;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.CellRangeAddress;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.*;
    
    
    /**
     * 一个Excel文件对应于一个workbook(HSSFWorkbook),
     * 一个workbook可以有多个sheet(HSSFSheet)组成,
     * 一个sheet是由多个row(HSSFRow)组成,
     * 一个row是由多个cell(HSSFCell)组成。
     */
    public class ExcelUtil<T> {
        private final HSSFWorkbook wb = new HSSFWorkbook();
    
    
        public HSSFWorkbook getWb() {
            return wb;
        }
    
        /**
         * 获取HSSFSheet,内部方法不必关注
         *
         * @param fileName 文件名
         * @param wb       HSSFWorkbook
         * @return HSSFSheet
         */
        private static HSSFSheet getSheet(String fileName, HSSFWorkbook wb) {
            return wb.createSheet(fileName);
        }
    
        /**
         * 通过类的反射导出 Excel
         *
         * @param fileName 文件名
         * @param aClass   类对象
         * @param dataList 数据列表
         * @return 是否成功
         */
        public Boolean exportExcelClass(String fileName, Class<?> aClass, List<T> dataList) {
    
            List<Object> thRow = new ArrayList<>();  //表头数据
            List<List<Object>> thOrderList = new ArrayList<>();       //存放数据和顺序
            for (Field declaredField : aClass.getDeclaredFields()) {  //循环遍历对象的属性列表
                if (declaredField.isAnnotationPresent(ExportExcel.class)) {  //找到被注解的属性
    
                    List<Object> orderValues = new ArrayList<>();
    
                    int order = declaredField.getAnnotation(ExportExcel.class).order();  //获取属性的order
                    String value = declaredField.getAnnotation(ExportExcel.class).value();//取出属性注解的value值
    
                    orderValues.add(order);
                    orderValues.add(value);
    
                    thOrderList.add(orderValues);
    
                }
    
                thOrderList.sort(Comparator.comparingInt(a -> (Integer) a.get(0)));  //排序
    
            }
            for (List<Object> objects : thOrderList) {
                thRow.add(objects.get(1));
            }
    
            List<List<Object>> lists = new ArrayList<>(); //表格数据
            lists.add(thRow);  //将表头数据加入
    
            for (T t : dataList) {  //循环遍历对象列表
                Field[] declaredFields = t.getClass().getDeclaredFields();  //反射得到对象的属性列表
                List<List<Object>> orderList = new ArrayList<>();       //存放数据和顺序
                for (Field declaredField : declaredFields) {    //循环遍历对象的属性
                    if (declaredField.isAnnotationPresent(ExportExcel.class)) {
                        int order = declaredField.getAnnotation(ExportExcel.class).order();  //获取属性的order
    
                        String name = declaredField.getName();  //获取属性的name
                        String getValueMethodName = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);  // 获取属性的get方法
                        Method method = null;
                        try {
                            method = t.getClass().getMethod(getValueMethodName);
                            Object invoke = method.invoke(t);
                            if (invoke == null) {
                                invoke = "";
                            }
    
                            List<Object> list = new ArrayList<>();
                            list.add(order);
                            list.add(invoke);
    
                            orderList.add(list);
    
                        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                            throw new RuntimeException(e);
                        }
    
                    }
    
                }
    
                orderList.sort(Comparator.comparingInt(a -> (Integer) a.get(0))); //排序
    
                ArrayList<Object> rowList = new ArrayList<>();
                for (List<Object> orderData : orderList) {
                    rowList.add(orderData.get(1));
                }
                lists.add(rowList);
    
            }
            return exportExcelList(fileName, lists);
        }
    
        /**
         * 通过list数据集合导出
         *
         * @param fileName 文件名
         * @param dataList 数据列表(list)
         * @return 导出是否成功
         */
        public Boolean exportExcelList(String fileName, List<List<Object>> dataList) {
            HSSFSheet sheet = getSheet(fileName, wb);
            int thSize = dataList.get(0).size() - 1; //表头数据列表长度
    
            //标题内容  col列 row行
            CellStyle titleStyle = setCellStyle("Arial", 16, true, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);//设置title单元格样式
            HSSFRow titleRow = sheet.createRow(0);
            HSSFCell titleCell = titleRow.createCell(0);
            titleCell.setCellValue(fileName);
            /*
              合并单元格
                 第一个参数:第一个单元格的行数(从0开始)
                 第二个参数:第二个单元格的行数(从0开始)
                 第三个参数:第一个单元格的列数(从0开始)
                 第四个参数:第二个单元格的列数(从0开始)
             */
            CellRangeAddress range = new CellRangeAddress(0, 0, 0, thSize);
            sheet.addMergedRegion(range);
            titleCell.setCellStyle(titleStyle);
    
            //设置列的宽度
            int size = dataList.get(0).size();
            int[] colSize = new int[size];
    
            for (List<Object> data : dataList) {
                for (int i = 0; i < data.size(); i++) {
                    int length = data.get(i).toString().length();
                    if (colSize[i] < length) {
                        colSize[i] = length;   //获取每一列中最长的数据
                    }
                }
            }
            for (int i = 0; i < colSize.length; i++) {
                sheet.setColumnWidth(i, 2000 + colSize[i] * 200);   ///设置列的宽度
            }
    
            //表头行数
            int rowId = 1;
    
            //数据
            CellStyle style = setCellStyle("Arial", 12, false, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
            CellStyle numStyle = setCellStyle("Arial", 12, false, HorizontalAlignment.LEFT, VerticalAlignment.CENTER);
            for (List<Object> strings : dataList) {
                HSSFRow row = sheet.createRow(rowId);
    
                for (int i = 0; i < strings.size(); i++) {
                    HSSFCell cell = row.createCell(i);
                    //表头的样式
                    if (rowId == 1) {
                        CellStyle thStyle = setCellStyle("Arial", 12, false, HorizontalAlignment.CENTER, VerticalAlignment.CENTER);
                        thStyle.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
                        thStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
                        cell.setCellStyle(thStyle);
                    }
                    //数据的样式
                    if (rowId != 1) {
                        if (strings.get(i) instanceof Double
                                || strings.get(i) instanceof Float
                                || strings.get(i) instanceof Long
                                || strings.get(i) instanceof Integer) {
                            cell.setCellStyle(numStyle);
                        } else {
                            cell.setCellStyle(style);
                        }
                    }
    
                    //数据类型处理
                    if (strings.get(i) instanceof Double) {
                        cell.setCellValue((double) strings.get(i));
                    } else if (strings.get(i) instanceof Float) {
                        cell.setCellValue((double) (Float) strings.get(i));
                    } else if (strings.get(i) instanceof Long) {
                        cell.setCellValue((double) (Long) strings.get(i));
                    } else if (strings.get(i) instanceof Integer) {
                        cell.setCellValue((double) (Integer) strings.get(i));
                    } else if (strings.get(i) instanceof Date) {
                        DataFormat format = wb.createDataFormat();
                        style.setDataFormat(format.getFormat("yyyy-MM-dd"));
                        cell.setCellValue((Date) strings.get(i));
                    } else if (strings.get(i) instanceof String) {
                        cell.setCellValue((String) strings.get(i));
                    } else {
                        try {
                            cell.setCellValue((String) Class.forName(this.getClass()
                                            .getName()
                                            .replaceAll(this.getClass()
                                                    .getSimpleName(), "fieldtype." + strings.get(i)
                                                    .getClass()
                                                    .getSimpleName() + "Type"))
                                    .getMethod("setValue", Object.class)
                                    .invoke((Object) null, strings.get(i)));
                        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException |
                                 ClassNotFoundException e) {
                            throw new RuntimeException(e);
                        }
                    }
    
                }
    
    
                rowId++;
            }
    
            //输出Excel
            return outputFile(fileName);
        }
    
        /**
         * 设置单元格字体样式
         *
         * @param fontType        字体类型
         * @param fontSize        字体大小
         * @param bold            字体是否加粗
         * @param textAlign_l_a_r 字体对齐方式(左右)
         * @param textAlign_t_a_b 字体对齐方式(上下)
         * @return CellStyle
         */
        public CellStyle setCellStyle(String fontType, int fontSize, boolean bold, HorizontalAlignment textAlign_l_a_r, VerticalAlignment textAlign_t_a_b) {
            HSSFCellStyle cellStyle = wb.createCellStyle();
            if (textAlign_l_a_r != null) {
                cellStyle.setAlignment(textAlign_l_a_r);//设置对齐方式
            }
            if (textAlign_t_a_b != null) {
                cellStyle.setVerticalAlignment(textAlign_t_a_b); //设置对齐方式
            }
    
            HSSFFont font = wb.createFont();
            font.setFontName(fontType);
            font.setFontHeightInPoints((short) fontSize);
            font.setBold(bold);
            cellStyle.setFont(font);// 设置字体
            return cellStyle;
        }
    
        /**
         * 文件输出流
         *
         * @param fileName 文件名
         * @return 返回是否成功
         */
        private Boolean outputFile(String fileName) {
            FileOutputStream output = null;
    
            try {
                output = new FileOutputStream("D://" + fileName + ".xls");
                wb.write(output);
    
                output.flush();
                output.close();
    
                return true;
    
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283

    后面还会对这个类进行持续的修改优化!!!!,希望可以给各位有一定的帮助!!欢迎讨论分享

  • 相关阅读:
    myeclipse怎么打开server窗口
    Android 12(S) 图像显示系统 - drm_hwcomposer 简析(上)
    ViTag :在线 WiFi 精细时间测量辅助多人环境中的视觉-运动身份关联
    linux多处理器并发访问共享资源---自旋锁
    算法竞赛进阶指南 捉迷藏
    常见的排序方法
    PyTorch搭建基于图神经网络(GCN)的天气推荐系统(附源码和数据集)
    ElasticSearch简介
    springboot(ssm 网上摄影工作室管理系统 Java(code&LW)
    MobileViT
  • 原文地址:https://blog.csdn.net/jiu_mu_mu/article/details/127784171