zoukankan      html  css  js  c++  java
  • java后端导出excel

    最近工作中需要导出excel。这次机智一点做个笔记,顺便写了一个比较通用的工具类。自然目前不能生成java实体类属性嵌套多次的这种没办法导出了,后续有需要的时候我再改改。

    首先,java后端导出excel需要的HSSFWorkbook或者XSSFWorkbook,实际上他们并没有什么区别,只是导出的格式不同而已(在我看来)。前者导出.xls格式,后者导出.xlsx格式的。不过新版的好像就没有这个区别了吧,因为我也是使用HSSFWorkbook,但是同样也能导出.xlsx格式的文件呦。

    HSSFWorkbook(XSSFWorkbook)他们都是Apache的产品,你可以按照需求随意切换!他们没有实质上的太多的差别,听别人说他们还有一个差别就是HSSFWorkbook只能导出65535条数据,再大的话就会报错,而XSSFWorkbook可以导出数据量是非常大的(在下并没有测试,感兴趣的兄弟可以试一下),实际上一般我们也用不了导出超过65535条数据吧。

    先看一下api吧!http://poi.apache.org/apidocs/dev/org/apache/poi/hssf/usermodel/HSSFWorkbook.html

    接下来我就直接粘代码了

    package com.ml.code.one.until;
    
    import org.apache.poi.hssf.usermodel.*;
    import org.apache.poi.ss.usermodel.HorizontalAlignment;
    import org.apache.poi.ss.usermodel.VerticalAlignment;
    import org.apache.poi.ss.util.CellRangeAddress;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.*;
    import java.util.regex.Pattern;
    import java.util.stream.Collectors;
    
    /**
     * @author lhf
     * @param <T>
     * @since 1.0
     * <p>
     *     导出excel工具类,比较通用的呦
     * </p>
     */
    public class ExcelUtil<T> {
    
    
        /**
         * 导出excel
         * @param datas  要导出的数据
         * @param excelName excel名字
         * @param sheetHead 表头 key对应java中的属性名,每个key前边    
         * 加01-99,为了排序。value对应表头的中文名
         * @param path 路径
         * @param entity 分装属性名(如果有连表查询的话)
         * @return -1其他异常   1导出成功     2目标文件被占用(文件已存在但是被其他应用占用)   0 导出失败(io)
         * @throws IllegalAccessException
         * @throws InvocationTargetException
         */
        public  int outExcel(Collection<T>datas, String excelName,
                                      Map<String, String> sheetHead,String path,String... entity) throws IllegalAccessException, InvocationTargetException {
            HSSFWorkbook workbook = new HSSFWorkbook(); //excel对象
            HSSFSheet sheet = workbook.createSheet(excelName);
            sheet.autoSizeColumn(1,true);
    
            //第一行表名
            HSSFRow row = sheet.createRow(0);
            HSSFCell cell = row.createCell(0);
            cell.setCellValue(excelName);
    
    
            //获取表头集合中所有的key(那么顺序可能会乱)
            Set<String> sheetKeySet = sheetHead.keySet();
            //转换为list集合,并排序
            List<String> sheetKey = sheetKeySet.stream().sorted().collect(Collectors.toList());//将set集合进行排序并转换成List集合
            //合并单元格
            sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, sheetKey.size() - 1));
    
            //设置单元格文字垂直居中,水平居中
            HSSFCellStyle cellStyle = workbook.createCellStyle();
            cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
            cellStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION);
            cell.setCellStyle(cellStyle);
    
            //日期格式
            HSSFCellStyle style = workbook.createCellStyle();
    //        HSSFDataFormat dataFormat = workbook.getCreationHelper().createDataFormat();
            HSSFDataFormat dataFormat = workbook.createDataFormat();
            style.setDataFormat(dataFormat.getFormat("yyyy/m/d"));
    
            //表头
            HSSFRow row1 = sheet.createRow(1);
            for (int i = 0; i < sheetKey.size(); i++) {
                HSSFCell cell1 = row1.createCell(i);
                cell1.setCellValue(sheetHead.get(sheetKey.get(i)));
                cell1.setCellStyle(cellStyle);
            }
    
            List<T> data = datas.stream().collect(Collectors.toList()); //将Collection转为List集合
            T t=null; //获取到的泛型
            //开始向excel表中添加信息
            for (int i = 0; i < data.size(); i++) {//生成行
                HSSFRow row2 = sheet.createRow(i + 2);
                t=data.get(i);
                Method[] declaredMethods = t.getClass().getDeclaredMethods();
                for (int m = 0; m < sheetKey.size(); m++) {//拿到key值  key的数量代表列的数量
                    String key = sheetKey.get(m).substring(2);
                    String newKey = "get" + key.substring(0, 1).toUpperCase() + key.substring(1);//key首字母大写
    
                        for (int k = 0; k < declaredMethods.length; k++) {//遍历字段进行比较并添加信息//添加列信息
                            String methodName = declaredMethods[k].getName();//方法名
                            Object invoke1=null;
                            if (methodName.equals(newKey)) {//执行方法获取属性值
                                 invoke1= declaredMethods[k].invoke(t);
                            }else if (entity.length>0){//如果有分装属性 A类中封装了B类 一下代码块就是执行B类中get方法
                                for (int j=0;j<entity.length;j++){
                                    String s = "get"+entity[j].substring(0,1).toUpperCase()+entity[j].substring(1);
                                    if (s.equals(methodName)){
                                        Object oo = declaredMethods[k].invoke(t);
                                        Method[] mes = oo.getClass().getDeclaredMethods();
                                        for (int p=0;p<mes.length;p++){
                                            if (mes[p].getName().equals(newKey)){
                                                 invoke1 = mes[p].invoke(oo);
                                            }
                                        }
    
                                    }
                                }
                            }
    
                            if (invoke1 instanceof String){
                                boolean matches = Pattern.matches("[0-9]*", invoke1.toString());
                                if (matches){
                                    Double invoke = (Double)invoke1;
                                    row2.createCell(m).setCellValue(invoke);
                                }else {
                                    String invoke= (String) invoke1;
                                    row2.createCell(m).setCellValue(invoke);
                                }
                            } else if (invoke1 instanceof Integer){
                                Integer invoke = (Integer) invoke1;
                                row2.createCell(m).setCellValue(invoke);
                            } else if (invoke1 instanceof Short){
                                Short invoke = (Short) invoke1;
                                row2.createCell(m).setCellValue(invoke);
                            } else if (invoke1 instanceof Long){
                                Long invoke = (Long)invoke1;
                                row2.createCell(m).setCellValue(invoke);
                            } else if (invoke1 instanceof Boolean){
                                Boolean invoke = (Boolean)invoke1;
                                row2.createCell(m).setCellValue(invoke);
                            } else if (invoke1 instanceof Double){
                                Double invoke = (Double)invoke1;
                                row2.createCell(m).setCellValue(invoke);
                            } else if (invoke1 instanceof Float){
                                Float invoke = (Float)invoke1;
                                row2.createCell(m).setCellValue(invoke);
                            } else if (invoke1 instanceof Byte){
                                Byte invoke = (Byte)invoke1;
                                row2.createCell(m).setCellValue(invoke);
                            } else if (invoke1 instanceof Character){
                                Character invoke = (Character)invoke1;
                                row2.createCell(m).setCellValue(invoke);
                            } else if (invoke1 instanceof Date){
                                Date invoke = (Date)invoke1;
                                HSSFCell cell1 = row2.createCell(m);
                                cell1.setCellStyle(style);
                                cell1.setCellValue(invoke);
                            } else if (invoke1 instanceof java.sql.Date){
                                java.sql.Date invoke = (java.sql.Date)invoke1;
                                HSSFCell cell1 = row2.createCell(m);
                                cell1.setCellStyle(style);
                                cell1.setCellValue(invoke);
                            } //if  类型转换
                        }//for k
                }//for m
            }//for  i
    
            //写入到文件
            try {
                File file = new File(path + excelName + ".xlsx");
                if (!file.exists()) {
                    file.createNewFile();
                }
                workbook.write(file);
                return 1;//导出成功
            } catch (FileNotFoundException e){
                e.printStackTrace();
                return 2;//目标文件被占用
            } catch (IOException e) {
                e.printStackTrace();
                return 0;//导出失败
            } catch (Exception e){
                e.printStackTrace();
                return -1;//其他异常
            }finally {
                try {
                    if (workbook!=null)
                    workbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
        

    代码很简单,相信大家看的懂。有什么不明白的加我qq1490030544。

    以下的伪代码是表名什么情况下不能用该类:

    以上这种情况通过A类导出Excel时可以拿到B类的id,但是拿不到C类的id(虽然可以拿到C类的对象),这个后续可能我会改造一下,看时间安排吧

  • 相关阅读:
    win10 L2TP拨号
    Esxi直通板载Sata
    Esxi 增加网卡驱动 生成ISO
    IPMITOOL THRESHOLD 修改
    Reverse Engineering Supermicro IPMI
    Esxi通过RDM直通硬盘
    Centos 安装后优化
    Centos 6安装apache 2.4
    Try Catch Finally 中Finally的代码在什么时候不被执行
    用CutePDF AND GhostScript 生成PDF的处理流
  • 原文地址:https://www.cnblogs.com/Tiandaochouqin1/p/11087908.html
Copyright © 2011-2022 走看看