Java利用Apache POI实现Excel文件读写操作

 更新时间:2026年02月12日 09:05:03   作者:清山博客  
Apache POI是一个用于读写Microsoft Office文件格式的Java库,可以用来读取或写入Excel文件,下面小编就和大家详细讲讲Java借助Apache POI读写Excel的详细代码吧

Apache POI是一个用于读写Microsoft Office文件格式的Java库,可以用来读取或写入Excel文件。

使用步骤

1.导入坐标

<!--alibaba-fastjson-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.9.graal</version>
</dependency> 
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-compress -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.26.1</version>
</dependency>
<!-- Excel处理 -->
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>

2.封装类

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class ExcelHelper {

    //文件后缀
    private final static String XLSX = ".xlsx";
    private final static String XLS = ".xls";

    /**
     * json数据导出Excel
     *
     * @param json     json数据
     * @param filepath 文件路径
     * @return true 导出成功
     */
    public static boolean jsonToExcel(String json, String filepath) {
        try {
            JSONArray array = JSONArray.parseArray(json);
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("Sheet1");
            // 创建表头
            Row header = sheet.createRow(0);
            JSONObject title = array.getJSONObject(0);
            for (String s : title.keySet()) {
                Cell cell = header.createCell(header.getLastCellNum() < 0 ? 0 : header.getLastCellNum());
                cell.setCellValue(s);
            }
            // 填充数据
            for (int i = 0; i < array.size(); i++) {
                JSONObject object = array.getJSONObject(i);
                Row row = sheet.createRow(i + 1);
                int colNum = 0;
                for (String key : object.keySet()) {
                    Object value = object.get(key);
                    row.createCell(colNum).setCellValue(String.valueOf(value));
                    colNum++;
                }
            }
            // 导出到文件
            OutputStream outputStream = new FileOutputStream(filepath);
            workbook.write(outputStream);
            workbook.close();
            return true;
        } catch (IOException e) {
            System.out.println(e.getMessage());
            return false;
        }
    }


    /**
     * Excel数据读取成json
     *
     * @param filepath 文件路径
     * @return json数据
     */
    public static JSONArray excelToJsonArray(String filepath) throws IOException, InvalidFormatException {
        File file = new File(filepath);
        String flieName = file.getName();
        Workbook book = null;
        Sheet sheet = null;
        if (flieName.endsWith(XLSX)) {
            book = new XSSFWorkbook(file);
            sheet = book.getSheetAt(0);
        }
        if (flieName.endsWith(XLS)) {
            POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new FileInputStream(file));
            book = new HSSFWorkbook(poifsFileSystem);
            sheet = book.getSheetAt(0);
        }
        if (sheet != null) {
            return readSheet(sheet, book);
        }
        return new JSONArray();
    }

    /**
     * 读取Excel
     *
     * @param sheet 工作表
     * @param book  工作簿
     * @return json数据
     */
    public static JSONArray readSheet(Sheet sheet, Workbook book) throws IOException {
        int rowStart = sheet.getFirstRowNum(); // 首行下标
        int rowEnd = sheet.getLastRowNum();    // 尾行下标
        // 如果首行与尾行相同,表明只有一行,直接返回空数组
        if (rowStart == rowEnd) {
            book.close();
            return new JSONArray();
        }
        // 获取第一行JSON对象键
        Row firstRow = sheet.getRow(rowStart);
        int cellStart = firstRow.getFirstCellNum();
        int cellEnd = firstRow.getLastCellNum();
        Map<Integer, String> keyMap = new HashMap<Integer, String>();
        for (int j = cellStart; j < cellEnd; j++) {
            keyMap.put(j, getValue(firstRow.getCell(j), rowStart, j, book, true));
        }
        // 获取每行JSON对象的值
        JSONArray array = new JSONArray();
        for (int i = rowStart + 1; i <= rowEnd; i++) {
            Row eachRow = sheet.getRow(i);
            JSONObject obj = new JSONObject();
            StringBuffer sb = new StringBuffer();
            for (int k = cellStart; k < cellEnd; k++) {
                if (eachRow != null) {
                    String val = getValue(eachRow.getCell(k), i, k, book, false);
                    sb.append(val);        // 所有数据添加到里面,用于判断该行是否为空
                    obj.put(keyMap.get(k), val);
                }
            }
            if (!sb.toString().isEmpty()) {
                array.add(obj);
            }
        }
        book.close();
        return array;
    }

    /**
     * 获取每个单元格的数据
     *
     * @param cell   单元格对象
     * @param rowNum 第几行
     * @param index  该行第几个
     * @param book   主要用于关闭流
     * @param isKey  是否为键:true-是,false-不是。 如果解析Json键,值为空时报错;如果不是Json键,值为空不报错
     */
    public static String getValue(Cell cell, int rowNum, int index, Workbook book, boolean isKey) throws IOException {

        // 空白或空
        if (cell == null || cell.getCellTypeEnum() == CellType.BLANK) {
            if (isKey) {
                book.close();
                throw new NullPointerException(String.format("the key on row %s index %s is null ", ++rowNum, ++index));
            } else {
                return "";
            }
        }

        // 0. 数字 类型
        if (cell.getCellTypeEnum() == CellType.NUMERIC) {
            if (HSSFDateUtil.isCellDateFormatted(cell)) {
                Date date = cell.getDateCellValue();
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                return df.format(date);
            }
            String val = cell.getNumericCellValue() + "";
            val = val.toUpperCase();
            if (val.contains("E")) {
                val = val.split("E")[0].replace(".", "");
            }
            return val;
        }

        // 1. String类型
        if (cell.getCellTypeEnum() == CellType.STRING) {
            String val = cell.getStringCellValue();
            if (val == null || val.trim().isEmpty()) {
                if (book != null) {
                    book.close();
                }
                return "";
            }
            return val.trim();
        }

        // 2. 公式 CELL_TYPE_FORMULA
        if (cell.getCellTypeEnum() == CellType.FORMULA) {
            return cell.getStringCellValue();
        }

        // 4. 布尔值 CELL_TYPE_BOOLEAN
        if (cell.getCellTypeEnum() == CellType.BOOLEAN) {
            return cell.getBooleanCellValue() + "";
        }

        // 5.	错误 CELL_TYPE_ERROR
        return "";
    }
}

3.使用方式

public static void main(String[] args) throws IOException, InvalidFormatException {
   //导出Excel
   var json = "[{\"name\":\"张三\",\"age\":\"18\"},{\"name\":\"李四\",\"age\":\"19\"}]";
   System.out.println(jsonToExcel(json, "D:\\test.xlsx"));

   //读取Excel
   System.out.println(excelToJsonArray("D:\\test.xlsx"));
}

到此这篇关于Java利用Apache POI实现Excel文件读写操作的文章就介绍到这了,更多相关Java读写Excel内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JavaCV获取视频文件时长的方法

    JavaCV获取视频文件时长的方法

    这篇文章主要为大家详细介绍了JavaCV获取视频文件时长的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • 分布式医疗挂号系统Nacos微服务Feign远程调用数据字典

    分布式医疗挂号系统Nacos微服务Feign远程调用数据字典

    这篇文章主要为大家介绍了分布式医疗挂号系统Nacos微服务Feign远程调用数据字典,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2022-04-04
  • 详解SpringBoot实现fastdfs防盗链功能的示例代码

    详解SpringBoot实现fastdfs防盗链功能的示例代码

    我们可以通过fastdfs实现一个分布式文件系统,如果fastdfs部署在外网,那么任何一个人知道了上传接口,就可以实现文件的上传和访问。那么如何阻止他人访问我们fastdfs服务器上的文件呢?此处就需要使用fastdfs的防盗链功能,本文就来讲讲如何实现这一功能
    2022-10-10
  • JavaWeb.servlet的基本使用方法详解

    JavaWeb.servlet的基本使用方法详解

    Servlet指在服务器端执行的一段Java代码,可以接收用户的请求和返回给用户响应结果,下面这篇文章主要给大家介绍了关于JavaWeb.servlet基本使用的相关资料,需要的朋友可以参考下
    2022-04-04
  • Java的jmap命令的具体使用

    Java的jmap命令的具体使用

    jmap是JDK提供的一个可以生成Java虚拟机的堆转储快照dump文件的命令行工具,本文主要介绍了Java的jmap命令的具体使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Java中的HashMap实现原理深入理解

    Java中的HashMap实现原理深入理解

    HashMap是一种非常常见和实用的数据结构,它被广泛应用于Java编程中,这篇文章主要介绍了Java中HashMap实现原理的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-12-12
  • Java中Set与List的关系与区别介绍

    Java中Set与List的关系与区别介绍

    这篇文章主要介绍了Java中Set与List的关系与区别介绍,本文总结它们两个接口都是继承自Collection、它们之间的存储方式不一样,需要的朋友可以参考下
    2015-03-03
  • 解析Arthas协助排查线上skywalking不可用问题

    解析Arthas协助排查线上skywalking不可用问题

    这篇文章主要为大家介绍了解析Arthas协助排查线上skywalking不可用的问题详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-02-02
  • 通过实例了解Java 8创建Stream流的5种方法

    通过实例了解Java 8创建Stream流的5种方法

    这篇文章主要介绍了通过实例了解Java 8创建Stream流的5种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Java 如何调用long的最大值和最小值

    Java 如何调用long的最大值和最小值

    这篇文章主要介绍了Java 如何调用long的最大值和最小值的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07

最新评论