使用POI读取excel文件内容

article/2025/10/21 3:48:47

1.前言

项目中要求读取excel文件内容,并将其转化为xml格式。常见读取excel文档一般使用POI和JExcelAPI这两个工具。这里我们介绍使用POI实现读取excel文档。

2.代码实例:

复制代码
复制代码
package edu.sjtu.erplab.poi;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

/**
* 操作Excel表格的功能类
*/
public class ExcelReader {
private POIFSFileSystem fs;
private HSSFWorkbook wb;
private HSSFSheet sheet;
private HSSFRow row;

/**
* 读取Excel表格表头的内容
*
@param InputStream
*
@return String 表头内容的数组
*/
public String[] readExcelTitle(InputStream is) {
try {
fs = new POIFSFileSystem(is);
wb = new HSSFWorkbook(fs);
} catch (IOException e) {
e.printStackTrace();
}
sheet = wb.getSheetAt(0);
row = sheet.getRow(0);
// 标题总列数
int colNum = row.getPhysicalNumberOfCells();
System.out.println("colNum:" + colNum);
String[] title = new String[colNum];
for (int i = 0; i < colNum; i++) {
//title[i] = getStringCellValue(row.getCell((short) i));
title[i] = getCellFormatValue(row.getCell((short) i));
}
return title;
}

/**
* 读取Excel数据内容
*
@param InputStream
*
@return Map 包含单元格数据内容的Map对象
*/
public Map<Integer, String> readExcelContent(InputStream is) {
Map<Integer, String> content = new HashMap<Integer, String>();
String str = "";
try {
fs = new POIFSFileSystem(is);
wb = new HSSFWorkbook(fs);
} catch (IOException e) {
e.printStackTrace();
}
sheet = wb.getSheetAt(0);
// 得到总行数
int rowNum = sheet.getLastRowNum();
row = sheet.getRow(0);
int colNum = row.getPhysicalNumberOfCells();
// 正文内容应该从第二行开始,第一行为表头的标题
for (int i = 1; i <= rowNum; i++) {
row = sheet.getRow(i);
int j = 0;
while (j < colNum) {
// 每个单元格的数据内容用"-"分割开,以后需要时用String类的replace()方法还原数据
// 也可以将每个单元格的数据设置到一个javabean的属性中,此时需要新建一个javabean
// str += getStringCellValue(row.getCell((short) j)).trim() +
// "-";
str += getCellFormatValue(row.getCell((short) j)).trim() + " ";
j++;
}
content.put(i, str);
str = "";
}
return content;
}

/**
* 获取单元格数据内容为字符串类型的数据
*
*
@param cell Excel单元格
*
@return String 单元格数据内容
*/
private String getStringCellValue(HSSFCell cell) {
String strCell = "";
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_STRING:
strCell = cell.getStringCellValue();
break;
case HSSFCell.CELL_TYPE_NUMERIC:
strCell = String.valueOf(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_BOOLEAN:
strCell = String.valueOf(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_BLANK:
strCell = "";
break;
default:
strCell = "";
break;
}
if (strCell.equals("") || strCell == null) {
return "";
}
if (cell == null) {
return "";
}
return strCell;
}

/**
* 获取单元格数据内容为日期类型的数据
*
*
@param cell
* Excel单元格
*
@return String 单元格数据内容
*/
private String getDateCellValue(HSSFCell cell) {
String result = "";
try {
int cellType = cell.getCellType();
if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {
Date date = cell.getDateCellValue();
result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1)
+ "-" + date.getDate();
} else if (cellType == HSSFCell.CELL_TYPE_STRING) {
String date = getStringCellValue(cell);
result = date.replaceAll("[年月]", "-").replace("日", "").trim();
} else if (cellType == HSSFCell.CELL_TYPE_BLANK) {
result = "";
}
} catch (Exception e) {
System.out.println("日期格式不正确!");
e.printStackTrace();
}
return result;
}

/**
* 根据HSSFCell类型设置数据
*
@param cell
*
@return
*/
private String getCellFormatValue(HSSFCell cell) {
String cellvalue = "";
if (cell != null) {
// 判断当前Cell的Type
switch (cell.getCellType()) {
// 如果当前Cell的Type为NUMERIC
case HSSFCell.CELL_TYPE_NUMERIC:
case HSSFCell.CELL_TYPE_FORMULA: {
// 判断当前的cell是否为Date
if (HSSFDateUtil.isCellDateFormatted(cell)) {
// 如果是Date类型则,转化为Data格式

//方法1:这样子的data格式是带时分秒的:2011-10-12 0:00:00
//cellvalue = cell.getDateCellValue().toLocaleString();

//方法2:这样子的data格式是不带带时分秒的:2011-10-12
Date date = cell.getDateCellValue();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
cellvalue = sdf.format(date);

}
// 如果是纯数字
else {
// 取得当前Cell的数值
cellvalue = String.valueOf(cell.getNumericCellValue());
}
break;
}
// 如果当前Cell的Type为STRIN
case HSSFCell.CELL_TYPE_STRING:
// 取得当前的Cell字符串
cellvalue = cell.getRichStringCellValue().getString();
break;
// 默认的Cell值
default:
cellvalue = " ";
}
} else {
cellvalue = "";
}
return cellvalue;

}

public static void main(String[] args) {
try {
// 对读取Excel表格标题测试
InputStream is = new FileInputStream("d:\\test2.xls");
ExcelReader excelReader = new ExcelReader();
String[] title = excelReader.readExcelTitle(is);
System.out.println("获得Excel表格的标题:");
for (String s : title) {
System.out.print(s + " ");
}

// 对读取Excel表格内容测试
InputStream is2 = new FileInputStream("d:\\test2.xls");
Map<Integer, String> map = excelReader.readExcelContent(is2);
System.out.println("获得Excel表格的内容:");
for (int i = 1; i <= map.size(); i++) {
System.out.println(map.get(i));
}

} catch (FileNotFoundException e) {
System.out.println("未找到指定路径的文件!");
e.printStackTrace();
}
}
}
复制代码
复制代码

3.总结

因为excel单元格中的内容往往都有一定的格式,比如日期型,数字型,字符串型,因此在读取的时候要进行格式判断,不然会出现错误。常见的就是不能正常读取日期。在代码实例中有一个方法:

getCellFormatValue(HSSFCell cell)

往这个方法中传入excel单元格就能识别单元格格式,并转化为正确的格式。

ps:2012-2-23

代码实例中有一段代码:

int colNum = row.getPhysicalNumberOfCells();

其中的HSSFRow.getPhysicalNumberOfCells();这个方法是用于获取一行中存在的单元格数,POI的官方API中有给出getPhysicalNumberOfCells方法的解释

getPhysicalNumberOfCells

public int getPhysicalNumberOfCells()
gets the number of defined cells (NOT number of cells in the actual row!).  That is to say if only columns 0,4,5 have values then there would be 3.
Specified by:
getPhysicalNumberOfCells in interface  Row
Returns:
int representing the number of defined cells in the row.

http://chatgpt.dhexx.cn/article/36EBVASC.shtml

相关文章

使用POI读取Excel文件

使用POI读取Excel文件 一、前言 用户可以通过上传excel文件&#xff0c;后端通过读取excel文件的内容并将内容写入数据库中以便更好的使用。 本文档使用的excel的工具类既可以读取有合并单元格的文件也可以读取没有合并单元格的文件&#xff0c;并且读取到单元格的数据进行了…

POI读写Excel的基本使用

一、Excel导入导出的应用场景 1、数据导入&#xff1a;减轻录入工作量 2、数据导出&#xff1a;统计信息归档 3、数据传输&#xff1a;异构系统之间数据传输 二、POI简介&#xff08;Apache POI&#xff09; 1、什么是POI Apache POI是Apache软件基金会的开放源码函式库&…

C# 加载DotNetBar组件

C#作为前端的开发软件&#xff0c;使用的人很多&#xff0c;但是原生的C#界面较为简陋&#xff0c;已经不能满足公司级的开发工作了&#xff0c;今天这篇博客的主要内容是讲一下怎么在C#端使用一个可以提升界面美感的第三方控件&#xff0c;DotNetBar 首先去官网下载最新的DotN…

DevComponents.DotNetBar2 美化包使用以及验证教程

使用这个美化包是在别人项目上看到的&#xff0c;遇到一些懵逼问题&#xff0c;不断总结&#xff0c;所以写一下教程 DotNetBar 美化包控件不可编辑问题&#xff1a; 如图&#xff1a; 解决办法&#xff1a; 安装DotNetBar 这个软件&#xff08;有试用版&#xff09;&#xff…

winform DevComponents.DotNetBar2 添加到工具栏方法

当C#项目引入皮肤组件&#xff0c;或其他组件是&#xff0c;发现工具框里面没有引用的组件怎么办&#xff1f; 1.组件的引用 我是把下载好的*.dll组件&#xff0c;复制到项目的\bin\Debug\路径下&#xff0c;然后在项目处右键-->添加引用&#xff0c;这样组件就引入项目了…

DotNetBar控件的多文档界面的实现

DotNetBar是一个不错的DotNET控件套装&#xff0c;原来是一个DLL文件&#xff0c;能够做出很漂亮的界面效果&#xff0c;记得在8.0以前的版本&#xff0c;好像实现多文档界面稍显得麻烦一些&#xff0c;我的Winform框架、WCF框架虽然也提供了这样多文档的界面&#xff0c;不过都…

C#之DotNetBar2使用方法 - itemPanel1

用itemPanel做个按钮菜单&#xff0c;模拟用来操控开关按钮 对象buttonItem1的属性&#xff08;itempanel可以添加的子控件列表对象&#xff0c;根据需要选择&#xff0c;这里用到的Button&#xff09; 可以用控件自带的样式&#xff0c;也可以用代码控制&#xff0c;也可以预先…

winfrom DotNetBar sideNav控件使用问题

sideNav初始UI 在最开始的界面&#xff0c;不知道设置了什么东西&#xff0c;然后没有那个东西 最后又新建了个项目&#xff0c;一个一个对比参数。还是没找到&#xff01;倒是发现几个其他的参数属性 在这里记录下 这是分别对应的是对sideNav的sideNavPanel的折叠 最大化 隐藏…

界面控件DotNetBar for WinForms使用教程:highlight组件使用教程

DotNetBar for WinForms是一个拥有89个组件的用户界面控件套包&#xff0c;用户可以使用Visual Studio 2005-2015轻松地创建专业的用户界面。十多年来DotNetBar帮助开发人员轻松地创建易用的专业Windows Forms (WinForms) 用户界面。DotNetBar是全世界第一个引入全功能Office 2…

C#之DotNetBar2使用方法 - superTabControl1

C#版本&#xff1a;DevComponents.DotNetBar2 14.1.0 &#xff08;可以搜下各种版本&#xff09; 常用的控件使用属性&#xff0c;方法&#xff1b; 1&#xff09;superTabControl1 关闭和菜单设置方法 visibletrue/false closebox :关闭当前选中的TAB menubox:切换tab的菜…

DevComponents.DotNetBar2之SuperTabControl使用技巧

关于类似SuperTabControl的使用如何动态调整其TAB标签的顺序问题&#xff0c;搜了全网也没有找到类似答案&#xff0c;都提到tab键的顺序或者是通过控件界面进行调整其顺序&#xff0c;都不是想要的结果&#xff0c;有个网友问的类似问题但是没有一个答案可用。经过反复测试总结…

界面控件DotNetBar for WinForms使用教程:LayoutControl详解(二)

DotNetBar for WinForms是一个拥有89个组件的用户界面控件套包&#xff0c;用户可以使用Visual Studio 2005-2015轻松地创建专业的用户界面。十多年来DotNetBar帮助开发人员轻松地创建易用的专业Windows Forms (WinForms) 用户界面。 点击下载DotNetBar for WinForms最新试用版…

DotNetBar布局(一)

相信大家搞.NET桌面程序开发都会用到一些界面布局的组件&#xff0c;常用的由DotNetBar和devexpress。今天主要将DotNetBar在项目中布局简单介绍一下&#xff0c;个人感觉这个控件还是有很多bug的&#xff0c;不知道什么时候就出现莫名奇妙的排版问题错误。比如突然在设计视图D…

dotnetbar-SuperTabControl禁止调整顺序

superTabCtl.ReorderTabsEnabled false; 禁止调整TAB顺序 superTabCtl.CloseButtonOnTabsAlwaysDisplayedfalse; 禁止x关闭按钮一直在TAB上显示 superTabCtl.CloseButtonOnTabsVisibletrue/false;关闭按钮是否可见 注意&#xff1a; superTabitem.CloseButtonVisibletru…

Visual Studio 2019 中使用 DotNetBar

1、下载并安装DotNetBarSetupTrial 2、在新建项目或者现有项目中进行引用&#xff0c;找到DotNetBar安装路径中需要用到的dll引用&#xff0c;引用路径正确是关键 3、在工具箱中添加选项卡&#xff0c;加载需要用到的控件 先在工具箱空白处添加选项卡&#xff0c;方便管理&am…

DotNetBar for WinForms使用教程:图表控件用户指南(一)

DotNetBar for WinForms是一个拥有89个组件的用户界面控件套包&#xff0c;用户可以使用Visual Studio 2005-2015轻松地创建专业的用户界面。十多年来DotNetBar帮助开发人员轻松地创建易用的专业Windows Forms (WinForms) 用户界面。DotNetBar是全世界第一个引入全功能Office 2…

c# 使用dotnetbar 控件绘制曲线图形

废话不说,直接上过程 加载dotnetbar库后,将chartcontrol控件拖动到界面上,选择line polt 增加一个按钮,绘制曲线功能 private void buttonX26_Click(object sender, EventArgs e) { CreateChartSeries1(); } public void CreateChart…

经典:DotNetBar Suite UI 7.9 for WPF Crack

创建专业的 WPF 应用程序 DotNetBar Suite for WPF 是超过 38 个本机 Windows Presentation Foundation 控件的工具箱&#xff0c;用于创建专业的 WPF 应用程序。 Office 2016 类样式添加到功能区、日程安排和其他控件... 我们痴迷于控制性能和像素级细节。我们很自豪地说&…

DotNetBar SuperGridControl控件

1.添加表头 sgc.PrimaryGrid.SelectionGranularity SelectionGranularity.Row;//点击选中一行DevComponents.DotNetBar.SuperGrid.GridColumn gc null;gc new DevComponents.DotNetBar.SuperGrid.GridColumn("ID");sgc.PrimaryGrid.Columns.Add(gc);gc new DevCo…

DotNetBar第三方控件详解

DotNetBar是一款性价比很强的界面控件&#xff0c;带有56个Windows Form 控件的工具箱&#xff0c;使开发人员可以轻而易举地创建出专业美观的Windows Form应用程序用户界面&#xff0c;控件全部采用C#编写&#xff0c;引入了全部Office 2007 style Ribbon控件、Office 2003 of…