栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot使用使用poi生成excel(使用反射获取数据pojo属性)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot使用使用poi生成excel(使用反射获取数据pojo属性)

springboot使用使用poi生成excel(使用反射获取数据pojo属性)
  • 业务场景
    • 依赖
    • Excel生成工具类
    • UUID生成工具类
    • service接口及实现类
    • controller
    • 使用postman进行调试

业务场景

系统导出数据较多,由前端查询后进行导出下载存在性能问题,故后端进行数据查询后生成excel,前端直接调用导出接口进行下载。考虑到通用性(不同业务场景下导出数据不同),使用反射获取传输数据的pojo属性,并匹配传入参数中需导出字段输出excel文件流。

依赖

            org.apache.poi
            poi
            3.17
        
        
            org.apache.poi
            poi-ooxml
            3.17
        
Excel生成工具类
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;


@Slf4j
public class ExcelDownloadUtil {
    
    public byte[] excelDownload(List list, List columns, List columnHeaders) throws Exception {
        // 初始化返回字节数组
        byte[] fileData = new byte[0];

        // 传入参数为空,直接返回空的流
        if (list == null || list.size() == 0) {
            log.info("传入数据列表为空");
            return fileData;
        }
        if (columns == null || columns.size() == 0) {
            log.info("传入展示字段列表为空");
            return fileData;
        }
        if (columnHeaders == null || columnHeaders.size() == 0) {
            log.info("传入表头列表为空");
            return fileData;
        }
        // 判断传入展示字段和传入表头列表长度是否相等
        if (columns.size() != columnHeaders.size()) {
            log.info("传入展示字段和传入表头列表长度不同");
            return fileData;
        }

        long startTime = System.currentTimeMillis();

        // 临时文件,保存导出excel
        File tempFile = File.createTempFile(UUIDGenerateUtils.generateWithoutLineUUID(), ".xlsx");
        FileOutputStream fileOutputStream = new FileOutputStream(tempFile);

        // 获取数据实体类属性
        Class cls = list.get(0).getClass();
        Field[] fields = cls.getDeclaredFields();

        // 判断excel展示字段是否在pojo中,取交集
        List fieldList = new ArrayList<>();
        // map excel展示字段,pojo数据类型
        List> excelColumns = new ArrayList<>();
        List excelColumnHeaders = new ArrayList<>();

        for (Field field : fields) {
            fieldList.add(field.getName());
        }

        for (int i = 0; i < columns.size(); i++) {
            if (fieldList.contains(columns.get(i))) {
                HashMap columnMap = new HashMap<>();
                columnMap.put(columns.get(i), fields[fieldList.indexOf(columns.get(i))].getGenericType().toString());
                excelColumns.add(columnMap);
                excelColumnHeaders.add(columnHeaders.get(i));
            }
        }

        // 获取SXSSFWorkbook实例
        SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook();
        Sheet sheet = sxssfWorkbook.createSheet();

        try {
            // header表头
            Row header = sheet.createRow(0);
            Cell firstCellHeader = header.createCell(0);
            firstCellHeader.setCellValue("序号");

            for (int cellNum = 1; cellNum < excelColumnHeaders.size() + 1; cellNum++) {
                Cell cell = header.createCell(cellNum);
                cell.setCellValue(excelColumnHeaders.get(cellNum - 1));
            }

            // 导出数据
            for (int rownum = 1; rownum <= list.size(); rownum++) {
                Row row = sheet.createRow(rownum);
                Object obj = list.get(rownum - 1);

                for (int i = 0; i < excelColumns.size() + 1; i++) {
                    Cell cell = row.createCell(i);

                    // 第一列插入序号,剩余列插入数据
                    if (i == 0) {
                        cell.setCellValue(rownum);
                    } else {
                        //获取属性
                        String name = excelColumns.get(i - 1).keySet().iterator().next().substring(0, 1).toUpperCase()
                                + excelColumns.get(i - 1).keySet().iterator().next().substring(1);
                        Method method = obj.getClass().getMethod("get" + name);
                        //获取属性值
                        Object value = method.invoke(obj);
                        String fieldType = excelColumns.get(i - 1).values().iterator().next();
                        // 判断数据类型
                        switch (fieldType) {
                            // 如果类型是String
                            case "class java.lang.String":
                                cell.setCellValue((String) value);
                                break;
                            // 如果类型是Integer
                            case "class java.lang.Integer":
                                cell.setCellValue((Integer) value);
                                break;
                            // 如果类型是Double
                            case "class java.lang.Double":
                                cell.setCellValue((Double) value);
                                break;
                            // 如果类型是Boolean
                            case "class java.lang.Boolean":
                                cell.setCellValue((Boolean) value);
                                break;
                            // 如果类型是LocalDateTime或其他
                            default:
                                cell.setCellValue(String.valueOf(value));
                                break;
                        }
                    }

                }
            }
            // 将数据写入临时文件
            sxssfWorkbook.write(fileOutputStream);
            // file转byte
            fileData = FileUtils.readFileToByteArray(tempFile);

            long endTime = System.currentTimeMillis();
            log.info("数据导出excel完成,耗时:{}秒", (endTime - startTime) / 1000);
        } catch (
                Exception e) {
            log.error("数据导出excel发生错误:{}", e.getMessage());
        } finally {
            // 清除临时文件
            if (!sxssfWorkbook.dispose()) {
                log.error("excel导出临时文件sxssfWorkbook删除失败");
            }
            if (!tempFile.delete()) {
                log.error("excel导出临时文件tempFile删除失败");
            }

        }
        return fileData;
    }
}

UUID生成工具类
import java.util.UUID;



public class UUIDGenerateUtils {

    private UUIDGenerateUtils() {
    }

    
    public static String generateNormalUUID() {
        return UUID.randomUUID().toString();
    }

    
    public static String generateWithoutLineUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }

}
service接口及实现类

service接口及实现类只是多了一步,使用mapper得到查询数据结果后,调用ExcelDownloadUtil,返回数据类型为byte[]

controller

需要在response中设置ContentType,使接口调用后的结果为excel文件

public Response downloadProjectMatterAreaOrgStatistics(@ApiParam(name = "param name", value = "对结果进行excel导出", type = "json")
                                                          @Valid @RequestBody ReqVO reqVO, BindingResult bindingResult, HttpServletResponse response) {
    log.info("excel导出接口开始:入参{}", ReqVO);
    if (bindingResult.hasErrors()) {
        return ValidUtil.validateParam(bindingResult);
    }

    try {
        byte[] fileStream;
        fileStream = iXXService.downloadXX(reqVO);

        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.getOutputStream().write(fileStream);
    } catch (IOException e) {
        log.error("excel导出失败");
        e.printStackTrace();
        return null;
    }

    log.info("excel导出接口结束");

    return null;
}
使用postman进行调试

使用send and download功能调试,可直接下载接口返回都excel文件

注意
如使用mybatis-plus分页功能,默认只支持每页导出500条数据,如需导出全部数据,参数"size": -1

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/351042.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号