Java实现对象列表导出为excel表格的实用工具类

 更新时间:2023年12月29日 08:19:28   作者:funfan0517  
这篇文章主要为大家详细介绍了Java如何实现对象列表导出为excel表格的实用工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

传入一个任意实体集合(List),通过反射获取实体类的属性名和属性值。在写入文件时,第一行为属性名,从第二行开始为属性值。

1.POI工具介绍

Excel的文件的组织形式,一个Excel文件对应于一个workbook(HSSFWorkbook),一个workbook可以有多个sheet(HSSFSheet)组成,一个sheet是由多个row(HSSFRow)组成,一个row是由多个cell(HSSFCell)组成。

基本操作步骤:

1、用HSSFWorkbook打开或者创建“Excel文件对象”

2、用HSSFWorkbook对象返回或者创建Sheet对象

3、用Sheet对象返回行对象,用行对象得到Cell对象

4、对Cell对象读写。

以上只能导入xls的文件不能导入xlsx的。导入xlsx需要用XSSFWorkFont,基本上都一样。

2.添加maven依赖

<!--Apache POI提供API给Java程式对Microsoft Office(Excel、WORD、PowerPoint、Visio等)格式档案读和写的功能-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>
<!--导出excel文件-->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</dependency>

3.Excel操作工具类

import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hpsf.DocumentSummaryInformation;
import org.apache.poi.hpsf.SummaryInformation;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @Author: funfan0517
 * @CreateTime: 2022-11-07  14:36
 * @Description: Excel操作工具类
 */
@Slf4j
public class PoiUtils {

    /**
     * 将对象集合导出到excel
     * @param list
     * @param <T>
     * @return
     */
    public static <T> ResponseEntity<byte[]> exportToExcel(List<T> list,String excelName) {
        if(list.isEmpty()) return null;//列表为空直接返回null
        // 1、创建一个excel文档
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 2、创建文档摘要
        workbook.createInformationProperties();
        // 3、获取并配置文档摘要信息
        DocumentSummaryInformation docInfo = workbook.getDocumentSummaryInformation();
        // 文档类别
        docInfo.setCategory("导出文档");
        // 文档管理员
        docInfo.setManager("UT");
        // 设置公司信息
        docInfo.setCompany("www.ut.com.cn");
        // 4、获取文档摘要信息
        SummaryInformation summaryInformation = workbook.getSummaryInformation();
        // 文档标题
        summaryInformation.setTitle("导出文档");
        // 文档作者
        summaryInformation.setAuthor("UT");
        // 备注信息
        summaryInformation.setComments("本文档由 优特科技 提供");
        // 5、创建样式
        // 创建标题行的样式
        HSSFCellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); // 背景颜色
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式
        HSSFSheet sheet = workbook.createSheet();// 不传name 默认为sheet1
        // 6、创建标题行 第一行数据
        // 只循环一次目的是将对象名写入到excel标题上
        for (T t : list) {
            HSSFRow row = sheet.createRow(0);
            String[] fieldNames = getFiledNames(t);
            for (int i = 0; i < fieldNames.length; i++) {
                HSSFCell cell = row.createCell(i);
                cell.setCellValue(fieldNames[i]);
                cell.setCellStyle(headerStyle);
            }
            break;
        }
        // 7、创建后面行
        for (int j = 0; j < list.size(); j++) {
            T t = list.get(j);
            String[] fieldValues = getFieldValues(t);
            // 由于第一行已经写入了标题,所以这里从第二行开始写
            HSSFRow rows = sheet.createRow(j + 1);
            for (int i = 0; i < fieldValues.length; i++) {
                rows.createCell(i).setCellValue(fieldValues[i]);
            }
        }
        HttpHeaders headers = new HttpHeaders();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//        FileOutputStream baos = null;
        try {
//            baos = new FileOutputStream("D:\\data\\test.xls");
            // 防止乱码
            headers.setContentDispositionFormData("attachment", new String(excelName.getBytes(StandardCharsets.UTF_8), "ISO-8859-1"));//ISO-8859-1

            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            workbook.write(baos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ResponseEntity<>(baos.toByteArray(), headers, HttpStatus.CREATED);//null;//
    }

    /**
     * 获取所有对象属性名称
     * @param o
     * @return
     */
    public static String[] getFiledNames(Object o) {
        Field[] fields=o.getClass().getDeclaredFields();
        String[] fieldNames=new String[fields.length];
        for(int i=0;i<fields.length;i++){
            fieldNames[i]=fields[i].getName();
        }
        return fieldNames;
    }

    /**
     * 获取对象属性值
     * @param o
     * @return
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private static String[] getFieldValues(Object o) {
        Field[] fields=o.getClass().getDeclaredFields();
        String[] fieldNames=new String[fields.length];
        String[] fieldValues = new String[fieldNames.length];
        for(int i=0;i<fields.length;i++){
            fieldNames[i]=fields[i].getName();
        }
        try {
            for (int i=0; i<fieldNames.length; i++) {
                String fieldName = fieldNames[i];
                Object invoke = o.getClass().getMethod("get" + returnFirstCapital(fieldName)).invoke(o);
                String field = invoke == null? null:invoke.toString();//数据为null时做特殊处理
                if(invoke instanceof Date) {
                    field = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(invoke);
                }
                fieldValues[i] = field;
            }
        } catch(Exception e) {
            log.error("获取实体类对象属性异常:", e);
        }
        return fieldValues;
    }

    /**
     * 判断字符串首字母是否为大写,如果不是转化为大写
     * @param str
     * @return
     */
    public static String returnFirstCapital(String str) {
        if (str.charAt(0) >= 'A' && str.charAt(0) <= 'Z') {
            return str;
        }
        char[] ch = str.toCharArray();
        ch[0] -= 32;
        return String.valueOf(ch);
    }



    /**
     * 将对象集合导出到excel
     */
    public static <T> String exportToExcelFile(List<T> list, String excelName) {
        if(list.isEmpty()) return null;//列表为空直接返回null
        // 1、创建一个excel文档
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 2、创建文档摘要
        workbook.createInformationProperties();
        // 3、获取并配置文档摘要信息
        DocumentSummaryInformation docInfo = workbook.getDocumentSummaryInformation();
        // 文档类别
        docInfo.setCategory("导出文档");
        // 文档管理员
        docInfo.setManager("UT");
        // 设置公司信息
        docInfo.setCompany("www.ut.com.cn");
        // 4、获取文档摘要信息
        SummaryInformation summaryInformation = workbook.getSummaryInformation();
        // 文档标题
        summaryInformation.setTitle("导出文档");
        // 文档作者
        summaryInformation.setAuthor("UT");
        // 备注信息
        summaryInformation.setComments("本文档由 优特科技 提供");
        // 5、创建样式
        // 创建标题行的样式
        HSSFCellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); // 背景颜色
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式
        HSSFSheet sheet = workbook.createSheet();// 不传name 默认为sheet1
        // 6、创建标题行 第一行数据
        // 只循环一次目的是将对象名写入到excel标题上
        for (T t : list) {
            HSSFRow row = sheet.createRow(0);
            String[] fieldNames = getFiledNames(t);
            for (int i = 0; i < fieldNames.length; i++) {
                HSSFCell cell = row.createCell(i);
                cell.setCellValue(fieldNames[i]);
                cell.setCellStyle(headerStyle);
            }
            break;
        }
        // 7、创建后面行
        for (int j = 0; j < list.size(); j++) {
            T t = list.get(j);
            String[] fieldValues = getFieldValues(t);
            // 由于第一行已经写入了标题,所以这里从第二行开始写
            HSSFRow rows = sheet.createRow(j + 1);
            for (int i = 0; i < fieldValues.length; i++) {
                rows.createCell(i).setCellValue(fieldValues[i]);
            }
        }
        File file=new File("D:\\"+excelName+".xls");
        FileOutputStream baos = null;
        try {
            baos = new FileOutputStream(file);
            workbook.write(baos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String absolutePath = file.getAbsolutePath();
        return "导出文件存放路径为:"+absolutePath;
    }

    /**
     * 将对象集合导出到excel
     * SXSSFWorkbook对于大型excel的创建且不会内存溢出的,就只有SXSSFWorkbook了。它的原理很简单,用硬盘空间换内存(就像hash map用空间换时间一样)
     * @param list
     * @param <T>
     * @reurn
     */
    public static <T> void exportExcel(HttpServletRequest request, HttpServletResponse response, List<T> list, String sheetName) {
        // 1、创建一个excel文档
        SXSSFWorkbook workbook = new SXSSFWorkbook();

        // 5、创建样式
        // 创建标题行的样式
        CellStyle headerStyle = workbook.createCellStyle();
        headerStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex()); // 背景颜色
        headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充模式
        Sheet sheet = workbook.createSheet();// 不传name 默认为sheet1
        // 6、创建标题行 第一行数据
        // 只循环一次目的是将对象名写入到excel标题上
        for (T t : list) {
            Row row = sheet.createRow(0);
            String[] fieldNames = getFiledNames(t);
            for (int i = 0; i < fieldNames.length; i++) {
                Cell  cell = row.createCell(i);
                cell.setCellValue(fieldNames[i]);
                cell.setCellStyle(headerStyle);
            }
            break;
        }
        // 7、创建后面行
        for (int j = 0; j < list.size(); j++) {
            T t = list.get(j);
            String[] fieldValues = getFieldValues(t);
            // 由于第一行已经写入了标题,所以这里从第二行开始写
            Row rows = sheet.createRow(j + 1);
            for (int i = 0; i < fieldValues.length; i++) {
                rows.createCell(i).setCellValue(fieldValues[i]);
            }
        }
        //声明输出流
        OutputStream outputStream = null;
        //响应到客户端
        try {
            //表格文件名称
            String codedFileName = java.net.URLEncoder.encode(sheetName, "UTF-8");
            //设置响应头
            response.setContentType("application/vnd.ms-excel");
            String agent = request.getHeader("USER-AGENT").toLowerCase();
            if (agent.contains("firefox")) {
                response.setCharacterEncoding("utf-8");
                response.setHeader("content-disposition", "attachment;filename=" + new String(sheetName.getBytes(), "ISO8859-1") + ".xlsx");
            } else {
                response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xlsx");
            }
            //获取输出流
            outputStream = response.getOutputStream();

            //用文档写输出流
            workbook.write(outputStream);

            //刷新输出流
            outputStream.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭输出流
            if (outputStream != null) {
                try {
                    outputStream.close();
                    workbook.dispose();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

参考文章:java使用POI实现excel文件的导入和导出(通用方法)

到此这篇关于Java实现对象列表导出为excel表格的实用工具类的文章就介绍到这了,更多相关Java列表导出为excel内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java FTPClient连接池的实现

    Java FTPClient连接池的实现

    这篇文章主要介绍了Java FTPClient连接池的实现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • Java基础学习之标签

    Java基础学习之标签

    在Java中,标签必须在循环之前使用, 一个循环之中嵌套另一个循环的开关,从多重嵌套中continue或break,该文详细介绍了标签的相关知识,对正在学习java基础的小伙伴们还很有帮助,需要的朋友可以参考下
    2021-05-05
  • java正则表达式用法大全(深度好文)

    java正则表达式用法大全(深度好文)

    这篇文章主要给大家介绍了关于java正则表达式用法大全的相关资料,正则表达式在处理字符串时非常有用,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-10-10
  • 如何用SpringBoot 进行测试

    如何用SpringBoot 进行测试

    这篇文章主要介绍了如何用SpringBoot 进行测试,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下
    2020-11-11
  • Springboot使用kafka的两种方式

    Springboot使用kafka的两种方式

    在公司用kafka比较多,今天整理下Springboot使用kafka的两种方式,Kafka作为一个消息发布订阅系统,就包括消息生成者和消息消费者,文中通过代码示例介绍的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2023-11-11
  • java 获取mac地址的两种方法(推荐)

    java 获取mac地址的两种方法(推荐)

    下面小编就为大家带来一篇java 获取mac地址的两种方法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • JAVA中的日期时间类用法总结

    JAVA中的日期时间类用法总结

    这篇文章主要给大家介绍了关于JAVA中日期时间类用法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 详解Spring Data JPA系列之投影(Projection)的用法

    详解Spring Data JPA系列之投影(Projection)的用法

    本篇文章主要介绍了详解Spring Data JPA系列之投影(Projection)的用法,具有一定的参考价值,有兴趣的可以了解一下
    2017-07-07
  • 详解Spring mvc DispatchServlet 实现机制

    详解Spring mvc DispatchServlet 实现机制

    本篇文章主要介绍了详解Spring mvc DispatchServlet 实现机制,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • 深入理解SpringMVC的参数绑定与数据响应机制

    深入理解SpringMVC的参数绑定与数据响应机制

    本文将深入探讨SpringMVC的参数绑定方式,包括基本类型、对象、集合等类型的绑定方式,以及如何处理参数校验和异常。同时,本文还将介绍SpringMVC的数据响应机制,包括如何返回JSON、XML等格式的数据,以及如何处理文件上传和下载。
    2023-06-06

最新评论