美文网首页
SpringBoot 整合poi 将JavaBean对象导出ex

SpringBoot 整合poi 将JavaBean对象导出ex

作者: goujj_123 | 来源:发表于2018-09-18 22:46 被阅读0次

说明:本人第一篇文章,希望各位多指教批评,同时希望该文章能够给各位读者带来帮助

运行环境

SpringBoot + maven + jdk1.8

1、配置maven依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>

2、自定义注解用于自动标识需要导出的列

/**
 * @author goujj
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelResources {
    /**
     * 标题
     *
     * @return
     */
    String title();

    /**
     * 排序
     *
     * @return
     */
    int order();
}

3、poi 导出的格式xls、xlsx后缀,本文主要介绍使用HSSFWorkbook导出xls格式excel

import com.scty.pps.pps.aop.ExcelResources;
import com.scty.pps.pps.dto.ExportDataDTO;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static java.util.stream.Collectors.toList;
/**
 * @author goujj
 * 导出excel文件
 */
public class ExportExcelUtil {
    /**
     * 导出数据处理
     *
     * @param exportDataDTO
     * @param out
     */
    public static void exportDeal(ExportDataDTO exportDataDTO, OutputStream out, Class<?> cls) throws IOException {
        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
        try {
            if (exportDataDTO.getSheetName() == null) {
                exportDataDTO.setSheetName("sheet1");
            }
            HSSFSheet hssfSheet = hssfWorkbook.createSheet(exportDataDTO.getSheetName());
            writeWorkBook(hssfWorkbook, hssfSheet, exportDataDTO, cls);
            hssfWorkbook.write(out);
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            hssfWorkbook.close();
        }
    }

    /**
     * 数据写入到workbook
     */
    private static void writeWorkBook(HSSFWorkbook hssfWorkbook, HSSFSheet hssfSheet, ExportDataDTO exportDataDTO, Class<?> cls) {
        int rowIndex = 0;
        //------统计有多少列需要导出
        int count = 0;
        Field[] field = cls.getDeclaredFields();
        Map<Integer, Object[]> res = new ConcurrentHashMap<>();
        List<Map<Integer, Object[]>> collection = new ArrayList<>();
        for (Field fie : field) {
            if (fie.isAnnotationPresent(ExcelResources.class)) {
                ExcelResources resources = fie.getAnnotation(ExcelResources.class);
                if (!res.containsKey(resources.order())) {
                    res.put(resources.order(), new Object[]{resources, fie});
                    count++;
                }
            }
        }
        if (res.size() > 0) {
            //设置数据第一行标题并且居中
            createTitle(hssfWorkbook, hssfSheet, count, exportDataDTO);
            rowIndex++;
            //设置导出的每列标题
            collection.add(res);
            Map<Integer, Object[]> dealSort = new ConcurrentHashMap<>();
            //对res根据key的大小排序,dataList为Filed排序之后的结果
            res.entrySet().stream().sorted(Map.Entry.<Integer, Object[]>comparingByKey().reversed()).forEach(e -> dealSort.put(e.getKey(), e.getValue()));
            List<Object[]> dataList = dealSort.entrySet().stream().map(e -> e.getValue()).collect(toList());
            //导出属性列名对应的字段
            List<String> heads = new ArrayList<>();
            //------获取每列的列名
            HSSFRow row = hssfSheet.createRow(rowIndex);
            rowIndex++;
            int colIndex = 0;
            for (Object[] obj : dataList) {
                ExcelResources resources = (ExcelResources) obj[0];
                HSSFCell cell = row.createCell(colIndex);
                cell.setCellValue(resources.title());
                HSSFCellStyle hssfCellStyle = hssfWorkbook.createCellStyle();
                cell.setCellStyle(hssfCellStyle);
                Field file = (Field) obj[1];
                heads.add(file.getName());
                colIndex++;
            }
            //-----设置每行的值并根据注解排序
            Map<String, Map<Integer, String>> result = new ConcurrentHashMap<>(heads.size());
            orderBy(heads, exportDataDTO, result);
            for (int i = 0; i < exportDataDTO.getDataList().size(); i++) {
                int zdCell = 0;
                HSSFRow ro = hssfSheet.createRow(rowIndex);
                rowIndex++;
                for (String head : heads) {
                    //写进excel对象
                    ro.createCell((short) zdCell).setCellValue(result.get(head).get(i));
                    zdCell++;
                }
            }
        }
    }

    /**
     * 创建第一行数据标题
     *
     * @param hssfWorkbook
     * @param hssfSheet
     * @param mergeCount    统计合并列的结束位置
     * @param exportDataDTO 获取第一行数据的标题
     */
    public static void createTitle(HSSFWorkbook hssfWorkbook, HSSFSheet hssfSheet, int mergeCount, ExportDataDTO exportDataDTO) {
        Font font = hssfWorkbook.createFont();
        font.setFontName("Arial");
        font.setColor(IndexedColors.BLACK.index);
        font.setBold(true);
        HSSFCellStyle titleStyle = hssfWorkbook.createCellStyle();
        titleStyle.setAlignment(HorizontalAlignment.CENTER);
        setStyle(titleStyle, font);
        HSSFRow row = hssfSheet.createRow(0);
        HSSFCell cell = row.createCell(0);
        cell.setCellValue(exportDataDTO.getTitle());
        CellRangeAddress rangeAddress = new CellRangeAddress(0, 0, 0, mergeCount - 1);
        hssfSheet.addMergedRegion(rangeAddress);
        cell.setCellStyle(titleStyle);
        cell.setCellValue(exportDataDTO.getTitle());
    }


    /**
     * 排序
     *
     * @param
     * @param heads         列属性
     * @param exportDataDTO
     * @param result        排序结果
     */
    private static void orderBy(List<String> heads, ExportDataDTO exportDataDTO, Map<String, Map<Integer, String>> result) {
        for (String str : heads) {
            result.put(str, new HashMap<>());
        }
        Integer num = 0;
        for (Object t : exportDataDTO.getDataList()) {
            Field[] fields = t.getClass().getDeclaredFields();
            for (Field field : fields) {
                String propertyName = field.getName();
                if (heads.contains(propertyName)) {
                    //获取value值
                    String methodName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
                    Class cl = t.getClass();
                    try {
                        Method getMethod = cl.getMethod(methodName,
                                new Class[]{});
                        //操控该对象属性的get方法,从而拿到属性值
                        Object val = getMethod.invoke(t, new Object[]{});
                        if (val != null) {
                            //转化成String
                            result.get(propertyName).put(num, String.valueOf(val));
                        } else {
                            result.get(propertyName).put(num, null);
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
            num++;
        }
    }

    /**
     * 指定单元格的样式
     */
    private static void setStyle(HSSFCellStyle titleStyle, Font font) {
        titleStyle.setAlignment(HorizontalAlignment.CENTER);
        titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        titleStyle.setBorderLeft(BorderStyle.DOTTED);
        titleStyle.setBorderTop(BorderStyle.DOTTED);
        titleStyle.setBorderRight(BorderStyle.DOTTED);
        titleStyle.setBorderBottom(BorderStyle.DOTTED);
        titleStyle.setWrapText(true);
        titleStyle.setFont(font);
    }
}

4、测试方法

public static void main(String[] args) {
        try {
            ExportDataDTO exportDataDTO = new ExportDataDTO();
            exportDataDTO.setSheetName("测试1");
            exportDataDTO.setFileName("导出1");
            exportDataDTO.setTitle("测试");
            List<JiaofeiDTO> jiaofeiDTOS = new ArrayList<>();
            for (int i = 0; i < 100; i++) {
                JiaofeiDTO jiaofeiDTO = new JiaofeiDTO();
                jiaofeiDTO.setStudentId(i + 1L);
                jiaofeiDTO.setCostAll(i + 0.1);
                jiaofeiDTO.setCostType(0);
                jiaofeiDTOS.add(jiaofeiDTO);
            }
            exportDataDTO.setDataList(jiaofeiDTOS);
            FileOutputStream exportXls = new FileOutputStream(new StringBuffer("D://" + exportDataDTO.getFileName() + ".xls").toString());
            exportDeal(exportDataDTO, exportXls, JiaofeiDTO.class);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

poi 相关知识请参考官方文档

相关文章

网友评论

      本文标题:SpringBoot 整合poi 将JavaBean对象导出ex

      本文链接:https://www.haomeiwen.com/subject/mydmnftx.html