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版本的差异之处)相关推荐

  1. 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 ...

  2. 利用POI读取excel文件(java)

    利用POI读取excel文件(java) 摘要:利用java读取excel文件,读取文件并获取文件中每一个sheet中的值. 一.需要提前导入的包: import java.io.File;impor ...

  3. java利用poi读取excel_java利用POI读取excel文件的方法

    摘要:利用java读取excel文件,读取文件并获取文件中每一个sheet中的值. 一.需要提前导入的包: import java.io.File; import java.io.FileInputS ...

  4. 使用POI 读取 Excel 文件,读取手机号码 变成 1.3471022771E10

    使用POI 读取 Excel 文件,读取手机号码 变成 1.3471022771E10 [问题点数:40分,结帖人xieyongqiu] 不显示删除回复             显示所有回复     ...

  5. java poi读取excel文件(xlsx)

    读取excel文件的方法有许多种,这篇文章主要描述通过poi读取excel文件. 先maven导入jar包 <dependency><groupId>org.apache.po ...

  6. 使用POI读取Excel文件

    使用POI读取Excel文件 一.前言 用户可以通过上传excel文件,后端通过读取excel文件的内容并将内容写入数据库中以便更好的使用. 本文档使用的excel的工具类既可以读取有合并单元格的文件 ...

  7. POI 读取word (word 2003 和 word 2007

    最近在给客户做系统的时候,用户提出需求,要能够导入 word 文件,现在 microsoft word 有好几个版本 97.2003.2007的,这三个版本存储数据的格式上都有相当大的差别,而现在 9 ...

  8. POI 读取word (word 2003 和 word 2007)

    最近在给客户做系统的时候,用户提出需求,要能够导入 word 文件,现在 microsoft word 有好几个版本 97.2003.2007的,这三个版本存储数据的格式上都有相当大的差别,而现在 9 ...

  9. java POI 读取Excel文件 将图片、表格生成到PPT

    临时有个需求,要求通过读取EXCEL文件,然后通过文件名称去给定的文件夹内查找图片,并将图片写入PPT中,详情以表格的形式写到图片右侧,每张图片一页PPT.效果如图所示: 用到的jar包如下(mave ...

  10. 记录使用poi读取excel文件

    最近有同事问到在Java程序中poi读取excel怎么做,虽然以前写过,但是最近没用到就差不多忘了,俗话说好记性不如烂笔头,趁现在有空,特此记录一下. 项目使用的是springBoot,首先添加依赖, ...

最新文章

  1. [转载]SSH框架搭建详细图文教程
  2. Windows 2008 R2+iis7.5环境下Discuz!X3论坛伪静态设置方法
  3. Linux中autoduck批量对接,求助:关于autodock模拟分子对接
  4. 【AOP 面向切面编程】Android Studio 使用 AspectJ 监控方法运行原理分析
  5. 关于iptables
  6. 现在的位置就是对的啊,意思就是当鼠标放上去的时候,停止滚动,鼠标离开,继续滚动(跑马灯项目功能)...
  7. How where used list in SAP GUI is implemented
  8. ActiveMQ 简单应用
  9. Flutter基础—应用实例
  10. js 各种事件 如:点击事件、失去焦点、键盘事件等
  11. C语言打印九九乘法表
  12. kettle 简介及入门
  13. c语言的异步回调函数,C语言函数的回调函数
  14. spark的作业提交流程
  15. 【原创】objdump 的使用
  16. python接口自动化测试视频教程百度云全集_python自动化运维测试框架实战视频教程百度云资源...
  17. 快速美化封面用word就可以
  18. 二极管与门电路及原理分析
  19. git --allow-unrelated-histories
  20. 你还在用notifyDataSetChanged? 你已经out了

热门文章

  1. IntelliJ IDEA中激活JRebel插件
  2. 移动web适配利器-rem
  3. 关于改良报告与学习总结(Ⅰ)
  4. 源码分析--SDWebImage
  5. 2015-12-06 第七天课程笔记
  6. android 解析XML方式(二)
  7. Product of Array Except Self
  8. Android架构师之路-oop
  9. QQ 静态截图程序模拟实现
  10. Adversarial learned Inference(对抗学习推断器)