poi2与poi3差异及解决excel2003和excel2007兼容性研究报告_v1.1

上传人:第*** 文档编号:31311480 上传时间:2018-02-06 格式:DOC 页数:9 大小:112KB
返回 下载 相关 举报
poi2与poi3差异及解决excel2003和excel2007兼容性研究报告_v1.1_第1页
第1页 / 共9页
poi2与poi3差异及解决excel2003和excel2007兼容性研究报告_v1.1_第2页
第2页 / 共9页
poi2与poi3差异及解决excel2003和excel2007兼容性研究报告_v1.1_第3页
第3页 / 共9页
poi2与poi3差异及解决excel2003和excel2007兼容性研究报告_v1.1_第4页
第4页 / 共9页
poi2与poi3差异及解决excel2003和excel2007兼容性研究报告_v1.1_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《poi2与poi3差异及解决excel2003和excel2007兼容性研究报告_v1.1》由会员分享,可在线阅读,更多相关《poi2与poi3差异及解决excel2003和excel2007兼容性研究报告_v1.1(9页珍藏版)》请在金锄头文库上搜索。

1、POI2 与 POI3 差异及解决 excel2003 和excel2007 兼容性研究报告 第 1 页1 现有问题:近期发现报表系统(使用 EXCEL 作报表) ,在不知情的用户使用了 EXCEL2007 版本之后,出现了一系列兼容性问题:1、用 POI2.x 操作 EXCEL2007 文件,会导致后台错误。org.apache.poi7.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of PO

2、I that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)2、涉及 EXCEL 导出的部分,若文件内容是 EXCEL2007,却使用.XLS,为后缀名的文件。那么使用 EXCEL2003 打开会导致乱码现象。3、目前新建报表模版,无论客户端安装的是什么版本的 OFFICE,后台都是用EXCEL2003(POI2)文件格式创建的。4、目前兼容性问题影响范围包含但不限于:模板制作、报表导出、模板版本化、

3、批量折合等所有用到 EXCEL 后台操作的功能。2 问题原因:报表平台现有系统在后台处理 Excel 都是使用 apache 的 POI2.x 进行解析处理,但是 poi2.x 是和 jdk1.4 兼容的,且 poi2.x 只能处理 excel2003 及以前的老版本 excel文件,客户机器上安装的往往是较新版的 office2007,要处理 excel2007 就必须使用poi3.5 以上的版本,poi3.5 及以上的版本适用 jdk1.5 版及以上,并支持 excel2007 的处理。3 POI2.x 与 POI3.x 的区别:3.1 什么是 POIApache POI 是 Apache

4、 软件基金会的开放源码函式库,POI 提供 API 给 Java 程式对Microsoft Office 格式档案读和写的功能。现在较新较稳定的 POI 版本是 3.7,即常说的 POI7,最新的 POI3.8 已经出了 beta2 版本,支持 EXCEL2010 的操作。 第 2 页3.2 如何使用 POI完整的 POI3.8 beta2 包含如下类库:poi-3.8-beta2-20110408.jarpoi-examples-3.8-beta2-20110408.jarpoi-excelant-3.8-beta2-20110408.jarpoi-ooxml-3.8-beta2-20110

5、408.jar ( Office Open XML) poi-ooxml-schemas-3.8-beta2-20110408.jarpoi-scratchpad-3.8-beta2-20110408.jar另需要一些配套包的支持dom4j-1.6.1.jarstax-api-1.0.1.jarxmlbeans-2.3.0.jar (必须使用 2.3 或以上的版本)commons-logging-1.1.jarjunit-3.8.1.jarlog4j-1.2.13.jarPOI3.8 的具体 API 及实现方法不在本文详述。3.3 POI 结构及版本区别:1、首先,相对于 POI2.X 及以下

6、版本,POI3.X 支持较高版本的 Office 操作,在本文中关注的是能够对 EXCEL2007 进行操作,并可兼容操作 EXCEL2003。部分类图如下: 第 3 页(图 1)如上图,POI2.x 的结构只有类图中左半部分,POI3.x 新增了以 XSSF 前缀的 EXCEL文件操作对象,用于对 OOM 格式的 EXCEL 操作。POI3 完整具体结构和作用如下:结构: HSSF 提供读写 Microsoft Excel 格式档案的功能。 XSSF 提供读写 Microsoft Excel OOXML 格式档案的功能。 HWPF 提供读写 Microsoft Word 格式档案的功能。 H

7、SLF 提供读写 Microsoft PowerPoint 格式档案的功能。 HDGF 提供读写 Microsoft Visio 格式档案的功能。 2、其次,另一个重要区别就是,excel2007 文件格式与之前版本不同,之前版本采用的是微软自己的存储格式。07 版内容的存储采用 XML 格式(OOM) 。 第 4 页4 现有问题解决方案:4.1 解决方案要求:1、解决目前 EXCEL2003 和 EXCEL2007 兼容性问题。2、提供后续 EXCEL 版本,如 EXCEL2010 的可扩展性。4.2 算法(实现逻辑)1、兼容性:如(图1)所示,我们可以看到,操作EXCEL2003的对象(H

8、SSF为前缀)与操作EXCEL2007的对象(XSSF为前缀)共用一套接口,在遇到未知版本的EXCEL文件时,可以通过POI提供的方法判断文件头来获取版本信息,构造具体版本的Workbook实例。再返回统一的接口达到兼容性要求。创建兼容性Workbook的工厂方法代码如下:public static Workbook createCommonWorkbook(InputStream inp)throws IOException, InvalidFormatException / 首先判断流是否支持mark和reset方法,最后两个if分支中的方法才能支持if (!inp.markSupport

9、ed() / 还原流信息inp = new PushbackInputStream(inp, 8);/ EXCEL2003使用的是微软的文件系统if (POIFSFileSystem.hasPOIFSHeader(inp) return new HSSFWorkbook(inp);/ EXCEL2007使用的是OOM文件格式if (POIXMLDocument.hasOOXMLHeader(inp) / 可以直接传流参数,但是推荐使用OPCPackage容器打开return new XSSFWorkbook(OPCPackage.open(inp);throw new IOException(

10、不能解析的excel 版本 );通过传入的文件流,获取到通用的Workbook接口,就可以进行一系列不同的业务操作了,实际上到这一步EXCEL2003与EXCEL2007的兼容性问题已经基本解决了,简单吧?具体实例请阅读本文最后的DEMO,此处不详述。当然,HSSFWorkbook(EXCEL2003)会与XSSFWorkbook(EXCEL2007)有很多差异,通用接口只能满足这两者的交集部分。如下图: 第 5 页(图 2)若接口不能完全满足要求,可以通过判断Workbook类型,强制转换成其对应版本的对象,分别作两套或多套方法来处理。这是为满足兼容性值得牺牲,也是必须牺牲的部分。根据实际操

11、作经验,接口能满足绝大部分EXCEL的基本操作,不能满足需要的情况非常少见。具体功能差异未作深究,感兴趣的读者可自行对比API。伪码如下:Workbook wb = createCommonWorkbook(不确定的版本的EXCEL文件流);if (wb instanceof HSSFWorkbook) HSSFWorkbook hwb = (HSSFWorkbook)wb;EXCEL2003的处理部分 else if (wb instanceof XSSFWorkbook) XSSFWorkbook xwb = (XSSFWorkbook)wb;EXCEL2007的处理部分 else thr

12、ow new IOException(不能解析的excel 版本 );2、扩展性:我们在兼容性部分已经创建了获取兼容Workbook的工厂方法,若遇到其它版本,如EXCEL2010的需求,在工厂方法里添加一个创建EXCEL2010的Workbook条件就行了。修改createCommonWorkbook方法,伪码如下:public static Workbook createCommonWorkbook(InputStream inp)throws IOException, InvalidFormatException . if (输入文件的文件头为EXCEL2010格式) return ne

13、w EXCEL2010Workbook(inp);. throw new IOException(不能解析的excel 版本 ); 第 6 页既然版本都是固定的,那么再提供一个版本枚举类,不就可以更方便管理不同的EXCEL版本了吗,如果将枚举的VALUE值定义为文件后缀名,也一并解决了不同版本的EXCEL文件后缀名不同的恼人问题,真是一举多得呢。后续即使有更高的Office版本,如EXCEL2010,也只需要添加一个工厂条件,再添加一个枚举项即可实现无缝升级了。枚举类属性如下:/ KEY:版本号/ VALUE:文件后缀名/* EXCEL2003版本 */EXCEL_2003(2003, .xl

14、s),/* EXCEL2007版本 */EXCEL_2007(2007, .xlsx);/* 后续添加扩展添加的EXCEL2010版本 */EXCEL_2010(2010, .xlsx);再创建一个根据Workbook取得版本信息的工具方法,如下:public static ExcelVersionTypeEnum checkExcelVersion(Workbook wb)throws IOException if (wb instanceof HSSFWorkbook) return ExcelVersionTypeEnum.EXCEL_2003; else if (wb instanceof XSSFWorkbook) return ExcelVersionTypeEnum.EXCEL_2007; else throw new IOException(不能解析的excel 版本 );以后获取版本信息或后缀名就方便了:ExcelVersionTypeEnum ev =CompatibleExcelUtil.checkExcelVersion(wb);String suffix = ev.getValue();3、DEMO: 源码如下:public class Test public static

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 建筑/环境 > 工程造价

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号