POI 读取 Excel 文件(2003版本与2007版本的差异之处)
2019独角兽企业重金招聘Python工程师标准>>>
已整理成完整项目,并进行了优化。看参考地址:
https://gitee.com/andy_longjie/exceltools 或者 https://github.com/youmulongjie/exceltools
我们在做用POI读物 Excel文件时,往往会忽略了Excel的版本,到底是2003还是2007。于是在读取或写入Excel文件时,用2003版本的Excel和用2007版本的Excel文件,会出现不兼容情况。抛出异常,大概信息如下:org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF);
异常指出我们用了Office2007以上的版本(包含2007),要我们用XSSF来代替HSSF。
于是我们开始替换我们的代码,用XSSF代替HSSF。可是我们却意外的发现poi.jar包中,并不包含XSSF,那么XSSF到底从哪来的呢?百度一下发现,他们来自不同的星球:
(1)XSSFWorkbook:poi-ooxml-.jar org.apache.poi.xssf.usermodel.XSSFWorkbook
(2)HSSFWorkbook:poi.jar org.apache.poi.hssf.usermodel.HSSFWorkbook
查看源码:
多么的巧合啊!HSSFWorkbook 和 XSSFWorkbook 都实现了 Workbook 接口!
所以思路就来了,我们用时引入这两种jar包,在判断出Excel的版本号,根据Excel版本的不同来用HSSFWorkbook 或者XSSFWorkbook 的实现 Workbook。下面就直接上代码吧!
POI的版本号:
<poi.version>3.12</poi.version>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>${poi.version}</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>${poi.version}</version>
</dependency>
读取Excel文件的Java类:
/*** @package :com.changhongit.andy.util<br>* @author :wanglongjie<br>* @createDate :2015年8月31日下午1:37:32<br>*/
package com.changhongit.andy.util;import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;/*** @package :com.changhongit.andy.util<br>* @file :ExcelReader.java<br>* @describe :读取 Excel 文件<br>* @author :wanglongjie<br>* @createDate :2015年8月31日下午1:37:32<br>* @updater :<br>* @updateDate :<br>* @updateContent :<br>*/
public class ExcelReader {static private Workbook wb;static private Sheet sheet;static private Row row;/*** * @method :readExcelTitle<br>* @describe :读取 Excel 文件<br>* @author :wanglongjie<br>* @createDate :2015年8月31日下午2:41:25 <br>* @param fileName* :Excel 文件路径* @return String[]*/public static String[] readExcelTitle(String fileName) {InputStream is;try {is = new FileInputStream(fileName);String postfix = fileName.substring(fileName.lastIndexOf("."),fileName.length());if (postfix.equals(".xls")) {// 针对 2003 Excel 文件wb = new HSSFWorkbook(new POIFSFileSystem(is));sheet = wb.getSheetAt(0);} else {// 针对2007 Excel 文件wb = new XSSFWorkbook(is);sheet = wb.getSheetAt(0);}} catch (IOException e) {e.printStackTrace();}sheet = wb.getSheetAt(0);row = sheet.getRow(0);// 获取第一行(约定第一行是标题行)int colNum = row.getPhysicalNumberOfCells();// 获取行的列数String[] titles = new String[colNum];for (int i = 0; i < titles.length; i++) {titles[i] = getCellFormatValue(row.getCell(i));}return titles;}/*** * @method :readExcelContent<br>* @describe :读取 Excel 内容<br>* @author :wanglongjie<br>* @createDate :2015年8月31日下午3:12:06 <br>* @param fileName* :Excel 文件路径* @return List<Map<String,String>>*/public static List<Map<String, String>> readExcelContent(String fileName) {List<Map<String, String>> list = new ArrayList<>();Map<String, String> content = null;try {InputStream is;is = new FileInputStream(fileName);String postfix = fileName.substring(fileName.lastIndexOf("."),fileName.length());if (postfix.equals(".xls")) {// 针对 2003 Excel 文件wb = new HSSFWorkbook(new POIFSFileSystem(is));sheet = wb.getSheetAt(0);} else {// 针对2007 Excel 文件wb = new XSSFWorkbook(is);sheet = wb.getSheetAt(0);}} catch (IOException e) {e.printStackTrace();}sheet = wb.getSheetAt(0);int rowNum = sheet.getLastRowNum();// 得到总行数row = sheet.getRow(0);int colNum = row.getPhysicalNumberOfCells();String titles[] = readExcelTitle(fileName);// 正文内容应该从第二行开始,第一行为表头的标题for (int i = 1; i <= rowNum; i++) {int j = 0;row = sheet.getRow(i);content = new LinkedHashMap<>();do {content.put(titles[j], getCellFormatValue(row.getCell(j)).trim());j++;} while (j < colNum);list.add(content);}return list;}/*** 根据Cell类型设置数据* * @param cell* @return*/private static String getCellFormatValue(Cell cell) {String cellvalue = "";if (cell != null) {// 判断当前Cell的Typeswitch (cell.getCellType()) {// 如果当前Cell的Type为NUMERICcase Cell.CELL_TYPE_NUMERIC:case Cell.CELL_TYPE_FORMULA: {// 判断当前的cell是否为Dateif (HSSFDateUtil.isCellDateFormatted(cell)) {// 方法2:这样子的data格式是不带带时分秒的:2011-10-12Date date = cell.getDateCellValue();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");cellvalue = sdf.format(date);} else {// 如果是纯数字取得当前Cell的数值cellvalue = String.valueOf(cell.getNumericCellValue());}break;}// 如果当前Cell的Type为STRINcase Cell.CELL_TYPE_STRING:// 取得当前的Cell字符串cellvalue = cell.getRichStringCellValue().getString();break;default:// 默认的Cell值cellvalue = " ";}} else {cellvalue = "";}return cellvalue;}public static void main(String[] args) {String file = "E://Andy/work/Tomcat 7.0/webapps/customer/WEB-INF/upload/客户收支配置.xlsx";List<Map<String, String>> list = ExcelReader.readExcelContent(file);Map<String, String> map = null;for (int i = 0; i < list.size(); i++) {map = list.get(i);Entry<String, String> entry = null;for (Iterator<Entry<String, String>> it = map.entrySet().iterator(); it.hasNext();) {entry = it.next();System.out.println(entry.getKey() + "-->" + entry.getValue());}System.out.println("............");}}}
主要的思路就是,我们在定义成员变量时不在定义某一种实现类,而是定义成接口:
static private Workbook wb;
static private Sheet sheet;
static private Row row;
然后根据上传文件的后缀名,判断是2003Excel还是2007Excel,再决定用不同的类实现成员变量的接口,从而达到代码既支持2003Excel有支持2007Excel:
InputStream is = new FileInputStream(fileName);
String postfix = fileName.substring(fileName.lastIndexOf("."),
fileName.length());
if (postfix.equals(".xls")) {
// 针对 2003 Excel 文件
wb = new HSSFWorkbook(new POIFSFileSystem(is));
sheet = wb.getSheetAt(0);
} else {
// 针对2007 Excel 文件
wb = new XSSFWorkbook(is);
sheet = wb.getSheetAt(0);
}
最后纠结了半天的问题终于解决了,欧耶
已整理成完整项目,并进行了优化。看参考地址:
https://gitee.com/andy_longjie/exceltools 或者 https://github.com/youmulongjie/exceltools
转载于:https://my.oschina.net/andy1989/blog/499605
POI 读取 Excel 文件(2003版本与2007版本的差异之处)相关推荐
- java word 2003_[Java教程]POI 读取word (word 2003 和 word 2007)(转)
[Java教程]POI 读取word (word 2003 和 word 2007)(转) 0 2017-09-27 16:00:29 POI 读取word (word 2003 和 word 200 ...
- 利用POI读取excel文件(java)
利用POI读取excel文件(java) 摘要:利用java读取excel文件,读取文件并获取文件中每一个sheet中的值. 一.需要提前导入的包: import java.io.File;impor ...
- java利用poi读取excel_java利用POI读取excel文件的方法
摘要:利用java读取excel文件,读取文件并获取文件中每一个sheet中的值. 一.需要提前导入的包: import java.io.File; import java.io.FileInputS ...
- 使用POI 读取 Excel 文件,读取手机号码 变成 1.3471022771E10
使用POI 读取 Excel 文件,读取手机号码 变成 1.3471022771E10 [问题点数:40分,结帖人xieyongqiu] 不显示删除回复 显示所有回复 ...
- java poi读取excel文件(xlsx)
读取excel文件的方法有许多种,这篇文章主要描述通过poi读取excel文件. 先maven导入jar包 <dependency><groupId>org.apache.po ...
- 使用POI读取Excel文件
使用POI读取Excel文件 一.前言 用户可以通过上传excel文件,后端通过读取excel文件的内容并将内容写入数据库中以便更好的使用. 本文档使用的excel的工具类既可以读取有合并单元格的文件 ...
- POI 读取word (word 2003 和 word 2007
最近在给客户做系统的时候,用户提出需求,要能够导入 word 文件,现在 microsoft word 有好几个版本 97.2003.2007的,这三个版本存储数据的格式上都有相当大的差别,而现在 9 ...
- POI 读取word (word 2003 和 word 2007)
最近在给客户做系统的时候,用户提出需求,要能够导入 word 文件,现在 microsoft word 有好几个版本 97.2003.2007的,这三个版本存储数据的格式上都有相当大的差别,而现在 9 ...
- java POI 读取Excel文件 将图片、表格生成到PPT
临时有个需求,要求通过读取EXCEL文件,然后通过文件名称去给定的文件夹内查找图片,并将图片写入PPT中,详情以表格的形式写到图片右侧,每张图片一页PPT.效果如图所示: 用到的jar包如下(mave ...
- 记录使用poi读取excel文件
最近有同事问到在Java程序中poi读取excel怎么做,虽然以前写过,但是最近没用到就差不多忘了,俗话说好记性不如烂笔头,趁现在有空,特此记录一下. 项目使用的是springBoot,首先添加依赖, ...
最新文章
- [转载]SSH框架搭建详细图文教程
- Windows 2008 R2+iis7.5环境下Discuz!X3论坛伪静态设置方法
- Linux中autoduck批量对接,求助:关于autodock模拟分子对接
- 【AOP 面向切面编程】Android Studio 使用 AspectJ 监控方法运行原理分析
- 关于iptables
- 现在的位置就是对的啊,意思就是当鼠标放上去的时候,停止滚动,鼠标离开,继续滚动(跑马灯项目功能)...
- How where used list in SAP GUI is implemented
- ActiveMQ 简单应用
- Flutter基础—应用实例
- js 各种事件 如:点击事件、失去焦点、键盘事件等
- C语言打印九九乘法表
- kettle 简介及入门
- c语言的异步回调函数,C语言函数的回调函数
- spark的作业提交流程
- 【原创】objdump 的使用
- python接口自动化测试视频教程百度云全集_python自动化运维测试框架实战视频教程百度云资源...
- 快速美化封面用word就可以
- 二极管与门电路及原理分析
- git --allow-unrelated-histories
- 你还在用notifyDataSetChanged? 你已经out了