Java实现读取和生成Excel

基于Apache POI实现一个通用的Java工具类来读取和生成Excel文件,并将数据封装为Java对象,需要考虑.xls.xlsx两种格式。

步骤1: 添加依赖

添加Apache POI的依赖:

<!-- Apache POI for .xls and .xlsx files -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.2</version>
</dependency>

步骤2: 定义Java对象

定义一个Java对象,用于映射Excel中的数据:

@Data
public class Employee {
    private String name;   // 员工姓名
    private int age;       // 员工年龄
    private String department;  // 员工部门
}

步骤3: 创建通用的Excel工具类

创建一个工具类,实现读取和写入Excel的方法:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;

public class ExcelUtil {

    /**
     * 读取Excel文件并转换为Java对象列表。
     *
     * @param file          Excel文件。
     * @param clazz         要转换为的对象类型。
     * @param <T>           对象类型。
     * @return              对象列表。
     * @throws IOException  如果读取文件时发生I/O异常。
     */
    public static <T> List<T> readExcel(File file, Class<T> clazz) throws IOException {
        Workbook workbook = null;
        FileInputStream fis = new FileInputStream(file);
        try {
            if (file.getName().endsWith(".xls")) {
                workbook = new HSSFWorkbook(fis); // 用于旧版Excel文件(.xls)
            } else if (file.getName().endsWith(".xlsx")) {
                workbook = new XSSFWorkbook(fis); // 用于新版Excel文件(.xlsx)
            }
        } finally {
            fis.close();
        }

        List<T> resultList = new ArrayList<>();
        Sheet sheet = workbook.getSheetAt(0); // 只读取第一个工作表
        Iterator<Row> rowIterator = sheet.rowIterator();
        Map<Integer, Field> fieldsMap = getFieldsMap(clazz);

        Row firstRow = rowIterator.next(); // 跳过标题行
        while (rowIterator.hasNext()) {
            Row currentRow = rowIterator.next();
            T obj = clazz.newInstance(); // 创建对象实例
            for (Cell cell : currentRow) {
                Field field = fieldsMap.get(cell.getColumnIndex());
                if (field != null) {
                    Object value = getCellValue(cell, field.getType());
                    field.setAccessible(true);
                    field.set(obj, value);
                }
            }
            resultList.add(obj);
        }
        workbook.close();
        return resultList;
    }

    /**
     * 将Java对象列表写入Excel文件。
     *
     * @param list          对象列表。
     * @param file          要写入的Excel文件。
     * @param clazz         对象类型。
     * @param <T>           对象类型。
     * @throws IOException  如果写入文件时发生I/O异常。
     */
    public static <T> void writeExcel(List<T> list, File file, Class<T> clazz) throws IOException {
        Workbook workbook = new XSSFWorkbook(); // 创建工作簿
        Sheet sheet = workbook.createSheet("Sheet1"); // 创建工作表

        // 写入标题行
        Row titleRow = sheet.createRow(0);
        Map<Integer, Field> fieldsMap = getFieldsMap(clazz);
        for (int i = 0; i < fieldsMap.size(); i++) {
            Field field = fieldsMap.get(i);
            titleRow.createCell(i).setCellValue(field.getName());
        }

        int rowNum = 1; // 从第二行开始写入数据
        for (T obj : list) {
            Row row = sheet.createRow(rowNum++);
            for (int i = 0; i < fieldsMap.size(); i++) {
                Field field = fieldsMap.get(i);
                field.setAccessible(true);
                Object value = field.get(obj);
                Cell cell = row.createCell(i);
                setCellValue(cell, value);
            }
        }

        try (FileOutputStream fos = new FileOutputStream(file)) {
            workbook.write(fos); // 写入文件
        }
    }

    /**
     * 获取对象所有字段与其在Excel中列的映射关系。
     *
     * @param clazz 对象类型。
     * @return 字段与其列索引的映射。
     */
    private static <T> Map<Integer, Field> getFieldsMap(Class<T> clazz) {
        Map<Integer, Field> fieldsMap = new HashMap<>();
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            fieldsMap.put(i, fields[i]);
        }
        return fieldsMap;
    }

    /**
     * 根据字段类型获取单元格的值。
     *
     * @param cell 单元格。
     * @param type 字段类型。
     * @return 单元格的值。
     */
    private static Object getCellValue(Cell cell, Class<?> type) {
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                return cell.getNumericCellValue();
            case BOOLEAN:
                return cell.getBooleanCellValue();
            default:
                return null;
        }
    }

    /**
     * 将值设置到单元格中。
     *
     * @param cell 单元格。
     * @param value 值。
     */
    private static void setCellValue(Cell cell, Object value) {
        if (value instanceof String) {
            cell.setCellValue((String) value);
        } else if (value instanceof Integer) {
            cell.setCellValue((Integer) value);
        } else if (value instanceof Double) {
            cell.setCellValue((Double) value);
        } else if (value instanceof Boolean) {
            cell.setCellValue((Boolean) value);
        } else {
            cell.setCellValue(value.toString());
        }
    }
}
  • readExcel: 读取Excel文件并将每一行数据映射到指定的Java对象中,返回一个对象列表。
  • writeExcel: 接受一个对象列表和Excel文件路径,将对象列表写入到Excel文件中。
  • getFieldsMap: 获取类的所有字段及其在Excel中的列索引的映射关系,用于在读取和写入时定位字段。
  • getCellValue: 根据单元格的类型获取其值。
  • setCellValue: 将值设置到单元格中,根据值的类型选择合适的单元格类型。

步骤四:使用Excel工具类

使用ExcelUtil类来读取和写入Excel文件:

public class Application {
    public static void main(String[] args) {
        try {
            // 读取Excel文件,支持.xls和.xlsx格式
            List<Employee> employees = ExcelUtil.readExcel(new File("employees.xls"), Employee.class);
            for (Employee emp : employees) {
                System.out.println(emp);
            }

            // 创建要写入Excel的员工数据列表
            List<Employee> newEmployees = new ArrayList<>();
            

            // 写入Excel文件
            ExcelUtil.writeExcel(newEmployees, new File("output.xlsx"), Employee.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 24
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值