Apache POI Java操作Excel文件的利器

举报
tea_year 发表于 2025/09/27 20:36:57 2025/09/27
【摘要】 Apache POI是一个开源的Java库,广泛应用于读取和修改Microsoft Office格式的文件,尤其是Excel、Word和PowerPoint。它是利用Java处理Microsoft Office文档最流行的库之一,使得在Java应用程序中操作这些文件变得可行。1 POI介绍Apache POI是用Java编写的免费开源的跨平台的Java API,Apache POI提供API...

Apache POI是一个开源的Java库,广泛应用于读取和修改Microsoft Office格式的文件,尤其是Excel、Word和PowerPoint。它是利用Java处理Microsoft Office文档最流行的库之一,使得在Java应用程序中操作这些文件变得可行。

1 POI介绍

Apache POI是用Java编写的免费开源的跨平台的Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能,其中使用最多的就是使用POI操作Excel文件。

Apache POI 的应用场景

  • 银行网银系统导出交易明细
  • 各种业务系统导出Excel报表
  • 批量导入业务数据

官网:https://poi.apache.org/https://poi.apache.org/

0.png

jxl:专门操作Excel

maven坐标:

<dependency>
 <groupId>org.apache.poi</groupId>
 <artifactId>poi</artifactId>
 <version>3.14</version>
</dependency>
<dependency>
 <groupId>org.apache.poi</groupId>
 <artifactId>poi-ooxml</artifactId>
 <version>3.14</version>
</dependency>

POI结构:

HSSF - 提供读写Microsoft Excel XLS格式档案的功能
XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能
HWPF - 提供读写Microsoft Word DOC格式档案的功能
HSLF - 提供读写Microsoft PowerPoint格式档案的功能
HDGF - 提供读Microsoft Visio格式档案的功能
HPBF - 提供读Microsoft Publisher格式档案的功能
HSMF - 提供读Microsoft Outlook格式档案的功能

2 入门案例

2.2.1 从Excel文件读取数据

使用POI可以从一个已经存在的Excel文件中读取数据

//创建工作簿
XSSFWorkbook workbook = new XSSFWorkbook("D:\\hello.xlsx");
//获取工作表,既可以根据工作表的顺序获取,也可以根据工作表的名称获取
XSSFSheet sheet = workbook.getSheetAt(0);
//遍历工作表获得行对象
for (Row row : sheet) {
 //遍历行对象获取单元格对象
 for (Cell cell : row) {
   //获得单元格中的值
   String value = cell.getStringCellValue();
   System.out.println(value);
}
}
workbook.close();

通过上面的入门案例可以看到,POI操作Excel表格封装了几个核心对象:

XSSFWorkbook:工作簿
XSSFSheet:工作表
Row:行
Cell:单元格

上面案例是通过遍历工作表获得行,遍历行获得单元格,最终获取单元格中的值。

还有一种方式就是获取工作表最后一个行号,从而根据行号获得行对象,通过行获取最后一个单元格索引,从而根据单元格索引获取每行的一个单元格对象,代码如下:

//创建工作簿
XSSFWorkbook workbook = new XSSFWorkbook("D:\\hello.xlsx");
//获取工作表,既可以根据工作表的顺序获取,也可以根据工作表的名称获取
XSSFSheet sheet = workbook.getSheetAt(0);
//获取当前工作表最后一行的行号,行号从0开始
int lastRowNum = sheet.getLastRowNum();
for(int i=0;i<=lastRowNum;i++){
 //根据行号获取行对象
 XSSFRow row = sheet.getRow(i);
 short lastCellNum = row.getLastCellNum();
 for(short j=0;j<lastCellNum;j++){
   String value = row.getCell(j).getStringCellValue();
   System.out.println(value);
}
}
workbook.close();

2.2.2 向Excel文件写入数据

使用POI可以在内存中创建一个Excel文件并将数据写入到这个文件,最后通过输出流将内存中的Excel文件下载到磁盘

//在内存中创建一个Excel文件
XSSFWorkbook workbook = new XSSFWorkbook();
//创建工作表,指定工作表名称
XSSFSheet sheet = workbook.createSheet("传智播客");

//创建行,0表示第一行
XSSFRow row = sheet.createRow(0);
//创建单元格,0表示第一个单元格
row.createCell(0).setCellValue("编号");
row.createCell(1).setCellValue("名称");
row.createCell(2).setCellValue("年龄");

XSSFRow row1 = sheet.createRow(1);
row1.createCell(0).setCellValue("1");
row1.createCell(1).setCellValue("小明");
row1.createCell(2).setCellValue("10");

XSSFRow row2 = sheet.createRow(2);
row2.createCell(0).setCellValue("2");
row2.createCell(1).setCellValue("小王");
row2.createCell(2).setCellValue("20");

//通过输出流将workbook对象下载到磁盘
FileOutputStream out = new FileOutputStream("D:\\itcast.xlsx");
workbook.write(out);
out.flush();
out.close();
workbook.close();

3. 批量导入预约设置信息

预约设置信息对应的数据表为t_ordersetting,预约设置操作对应的页面为ordersetting.html

t_ordersetting表结构:

2.png

orderDate:预约日期

number:可预约人数

reservations:已预约人数


批量导入预约设置信息操作过程:

1、点击模板下载按钮下载Excel模板文件

2、将预约设置信息录入到模板文件中

3、点击上传文件按钮将录入完信息的模板文件上传到服务器

4、通过POI读取上传文件的数据并保存到数据库

3.1 Springboot对接POI

3.1.1 提供模板文件

资料中已经提供了Excel模板文件ordersetting_template.xlsx,将文件放在health_backend工程的template目录

3.1.2 实现模板文件下载

为模板下载按钮绑定事件实现模板文件下载

<el-button style="margin-bottom: 20px;margin-right: 20px" type="primary" 
          @click="downloadTemplate()">模板下载</el-button>
//模板文件下载
downloadTemplate(){
window.location.href="../../template/ordersetting_template.xlsx";
}

3.1.3 文件上传

使用ElementUI的上传组件实现文件上传并绑定相关事件

<el-upload action="/ordersetting/upload.do"
          name="excelFile"
          :show-file-list="false"
          :on-success="handleSuccess"
          :before-upload="beforeUpload">
 <el-button type="primary">上传文件</el-button>
</el-upload>
handleSuccess(response, file) {
 if(response.flag){
   this.$message({
     message: response.message,
     type: 'success'
  });
}else{
   this.$message.error(response.message);
}
}

beforeUpload(file){
 const isXLS = file.type === 'application/vnd.ms-excel';
 if(isXLS){
   return true;
}
 const isXLSX = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
 if (isXLSX) {
   return true;
}
 this.$message.error('上传文件只能是xls或者xlsx格式!');
 return false;
}

3.2 后台代码

3.2.1 Controller

将资料中的POIUtils工具类复制到health_common工程

在health_backend工程创建OrderSettingController并提供upload方法


/**
* 预约设置
*/
@RestController
@RequestMapping("/ordersetting")
public class OrderSettingController {
   @Reference
   private OrderSettingService orderSettingService;

   /**
    * Excel文件上传,并解析文件内容保存到数据库
    * @param excelFile
    * @return
    */
   @RequestMapping("/upload")
   public Result upload(@RequestParam("excelFile")MultipartFile excelFile){
       try {
           //读取Excel文件数据
           List<String[]> list = POIUtils.readExcel(excelFile);
           if(list != null && list.size() > 0){
               List<OrderSetting> orderSettingList = new ArrayList<>();
               for (String[] strings : list) {
                   OrderSetting orderSetting =
                     new OrderSetting(new Date(strings[0]), Integer.parseInt(strings[1]));
                   orderSettingList.add(orderSetting);
              }
               orderSettingService.add(orderSettingList);
          }
      } catch (IOException e) {
           e.printStackTrace();
           return new Result(false, MessageConstant.IMPORT_ORDERSETTING_FAIL);
      }
       return new Result(true,MessageConstant.IMPORT_ORDERSETTING_SUCCESS);
  }
}

3.2.2 服务接口

创建OrderSettingService服务接口并提供新增方法


public interface OrderSettingService {
   public void add(List<OrderSetting> list);
}

3.2.3 服务实现类

创建服务实现类OrderSettingServiceImpl并实现新增方法

/**
* 预约设置服务
*/
@Service(interfaceClass = OrderSettingService.class)
@Transactional
public class OrderSettingServiceImpl implements OrderSettingService {
   @Autowired
   private OrderSettingDao orderSettingDao;
   //批量添加
   public void add(List<OrderSetting> list) {
       if(list != null && list.size() > 0){
           for (OrderSetting orderSetting : list) {
               //检查此数据(日期)是否存在
               long count = orderSettingDao.findCountByOrderDate(orderSetting.getOrderDate());
               if(count > 0){
                   //已经存在,执行更新操作
                   orderSettingDao.editNumberByOrderDate(orderSetting);
              }else{
                   //不存在,执行添加操作
                   orderSettingDao.add(orderSetting);
              }
          }
      }
  }
}

3.2.4 Dao接口

创建Dao接口OrderSettingDao并提供更新和新增方法

public interface OrderSettingDao {
   public void add(OrderSetting orderSetting);
   public void editNumberByOrderDate(OrderSetting orderSetting);
public long findCountByOrderDate(Date orderDate);
}

3.2.5 Mapper映射文件

创建Mapper映射文件OrderSettingDao.xml并提供相关SQL

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.itheima.dao.OrderSettingDao" >
   <!--新增-->
   <insert id="add" parameterType="com.itheima.pojo.OrderSetting">
      insert into t_ordersetting
    (orderDate,number,reservations)
                    values
    (#{orderDate},#{number},#{reservations})
   </insert>
   <!--根据日期更新预约人数-->
   <update id="editNumberByOrderDate" parameterType="com.itheima.pojo.OrderSetting">
      update t_ordersetting set number = #{number} where orderDate = #{orderDate}
   </update>
   <!--根据预约日期查询-->
   <select id="findCountByOrderDate" parameterType="java.util.Date" resultType="long">
      select count(*) from t_ordersetting where orderDate = #{orderDate}
   </select>
</mapper>

总结

Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。

Java操作Excel的工具包,尤其是Apache POI,极大地方便了开发人员处理Excel数据。通过引入Apache POI,开发者可以创建、修改和显示MS Office文件。本文深入讲解了如何使用Apache POI进行Java操作Excel,包括安装、基本概念、创建、读取、修改Excel文件,以及一些高级功能如使用样式和格式、图表图片插入、公式支持和数据验证。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。