关于Java导出Excel,使用POI的入门案例

本文分享了使用Java POI库批量导出Excel表格的实战经验,详细介绍了从需求背景、材料准备到实现代码的全过程。通过反射机制填充表格数据,实现了灵活的数据映射。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

①需求背景:企业实际项目中,一般都会少不了数据导出Excel表!今天亲自尝试了一下,记录如下。

②材料准备:

《1》POI的jar包(我是在maven项目中直接导入的POI3.7版本,小伙伴们可以自己搜一下导入,一大把,这里就不贴了)

    <dependencies>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.7</version>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>servlet</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>

《2》建了一个pojo实体类

package pojo;

public class Information {
    private String name;
    private Integer age;
    private Integer score;

    public Information() {
    }

    public Information(String name, Integer age, Integer score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }
}

③实现代码如下

熟悉Excel的都知道大致结构,我先理一下思路:

<1>先有工作簿(WorkBook)--->再有工作表(Sheet)--->再有行(Row)--->再有单元格(Cell)

<2>Cell单元格格式主要分字体格式(Font)和单元格格式(CellStyle),其中CellStyle包含Font

<3>一般会设置两套单元格格式,一套为首行使用(一般是列字段信息,为了突出表格包含内容重点什么的,也为了区分和表中数据的不同,因为测试嘛,我这里就没有写了),一套为表格中数据使用

package basetest.projecttest.poitest;

import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import pojo.Information;

import java.io.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class POITest {

    public static void main(String[] args) throws FileNotFoundException {
        //准备单元格数据
        List<Information> data = new ArrayList<Information>();
        data.add(new Information("zhangsan",22,99));
        data.add(new Information("lisi",25,100));
        data.add(new Information("wangwu",20,89));
        data.add(new Information("xialijun",24,90));
        //准备表头字段
        String names[] = {"姓名", "年龄", "分数"};
        //创建工作簿
        Workbook wk = new HSSFWorkbook();
        Sheet sheet = wk.createSheet("2019年度成绩报告");
        sheet.setDefaultColumnWidth(10);
        //创建行
        Row row = sheet.createRow(0);
        for (int i = 0; i < 3; i++) {
            //创建单元格
            Cell cell = row.createCell(i);
            //设置单元格内容
            HSSFRichTextString text = new HSSFRichTextString(names[i]);
            cell.setCellValue(text);
            //设置单元格样式(基于工作簿)
            CellStyle cs = wk.createCellStyle();
                //设置单元格字体
                Font font = wk.createFont();
                font.setBoldweight((short)15);
                font.setFontHeight((short)14);
            cs.setBorderBottom((short) 1);
            cs.setBorderLeft((short) 1);
            cs.setBorderRight((short) 1);
            cs.setFont(font);
        }
        //填写sheet数据(使用reflect方式)
        for (int i = 0; i < data.size(); i++) {
            Row row1 = sheet.createRow(i + 1);
            //获取每一个对象
            Information info1 = data.get(i);
            //根据实例对象拿到字节码文件对象
            Class<? extends Information> infoClass = info1.getClass();
            //真实中需要传入封装导出类文件的字段组成的String[]
            String[] filedNames = {"name", "age", "score"};
            //遍历属性填充数据
            for (int i1 = 0; i1 < filedNames.length; i1++) {
                String filedName = filedNames[i1].substring(0, 1).toUpperCase() + filedNames[i1].substring(1);
                try {
                    Method method = infoClass.getMethod("get" + filedName);
                    Object o = method.invoke(info1);
                    if (o != null) {
                        row1.createCell(i1).setCellValue(o.toString());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            /*for (int i1 = 0; i1 < names.length; i1++) {
                Cell cell = row1.createCell(0);
                cell.setCellValue(data.get(i).getName());
                Cell cell1 = row1.createCell(1);
                cell1.setCellValue(data.get(i).getAge());
                Cell cell2 = row1.createCell(2);
                cell2.setCellValue(data.get(i).getScore());
            }*/

        }
        //流形式写出excel
        FileOutputStream fos=new FileOutputStream(new File("d:\\a.xls"));
        try {
            wk.write(fos);
            fos.flush();
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

 

重点:表中数据基本根据Javabean来对应映射,所以我这里填充表中数据(上面代码标红地方)的是使用反射机制来写的,思路是这样:

先遍历整体数据组成的List集合(代码中的List<Information> data)--->获取一个个Information,拿到字节码文件对象--->Information类中的成员变量名称组成字符串数组(String[ ] fileNames)--->处理每一个元素,然后得到相应的方法对象(Method method)--->反射调用(method.invoke(Object obj))得到具体值填充进Excel中去。最后用输出流写出

④结果检验

⑤本来想自己封装一下

String[] filedNames = {"name", "age", "score"};
这句代码提高可用性,但是看了反射底层代码,不是很明白,还是后面再想想吧!

欢迎小伙伴交流讨论(夏李逸笙:XLYS_000@126.com)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值