POI2与POI3差异及解决excel2003和excel2007兼容研究报告_V1.1.doc_第1页
POI2与POI3差异及解决excel2003和excel2007兼容研究报告_V1.1.doc_第2页
POI2与POI3差异及解决excel2003和excel2007兼容研究报告_V1.1.doc_第3页
POI2与POI3差异及解决excel2003和excel2007兼容研究报告_V1.1.doc_第4页
POI2与POI3差异及解决excel2003和excel2007兼容研究报告_V1.1.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

POI2与POI3差异及解决excel2003和excel2007兼容性研究报告 第8页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 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)2、 涉及EXCEL导出的部分,若文件内容是EXCEL2007,却使用.XLS,为后缀名的文件。那么使用EXCEL2003打开会导致乱码现象。3、 目前新建报表模版,无论客户端安装的是什么版本的OFFICE,后台都是用EXCEL2003(POI2)文件格式创建的。4、 目前兼容性问题影响范围包含但不限于:模板制作、报表导出、模板版本化、批量折合等所有用到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软件基金会的开放源码函式库,POI提供API给Java程式对Microsoft Office格式档案读和写的功能。现在较新较稳定的POI版本是3.7,即常说的POI7,最新的POI3.8已经出了beta2版本,支持EXCEL2010的操作。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-20110408.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及以下版本,POI3.X支持较高版本的Office操作,在本文中关注的是能够对EXCEL2007进行操作,并可兼容操作EXCEL2003。部分类图如下:(图1)如上图,POI2.x的结构只有类图中左半部分,POI3.x新增了以XSSF前缀的EXCEL文件操作对象,用于对OOM格式的EXCEL操作。POI3完整具体结构和作用如下:结构: HSSF 提供读写Microsoft Excel格式档案的功能。 XSSF 提供读写Microsoft Excel OOXML格式档案的功能。 HWPF 提供读写Microsoft Word格式档案的功能。 HSLF 提供读写Microsoft PowerPoint格式档案的功能。 HDGF 提供读写Microsoft Visio格式档案的功能。 2、其次,另一个重要区别就是,excel2007文件格式与之前版本不同,之前版本采用的是微软自己的存储格式。07版内容的存储采用XML格式(OOM)。4 现有问题解决方案:4.1 解决方案要求:1、 解决目前EXCEL2003和EXCEL2007兼容性问题。2、 提供后续EXCEL版本,如EXCEL2010的可扩展性。4.2 算法(实现逻辑)1、 兼容性:如(图1)所示,我们可以看到,操作EXCEL2003的对象(HSSF为前缀)与操作EXCEL2007的对象(XSSF为前缀)共用一套接口,在遇到未知版本的EXCEL文件时,可以通过POI提供的方法判断文件头来获取版本信息,构造具体版本的Workbook实例。再返回统一的接口达到兼容性要求。创建兼容性Workbook的工厂方法代码如下:public static Workbook createCommonWorkbook(InputStream inp)throws IOException, InvalidFormatException / 首先判断流是否支持mark和reset方法,最后两个if分支中的方法才能支持if (!inp.markSupported() / 还原流信息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(不能解析的excel版本);通过传入的文件流,获取到通用的Workbook接口,就可以进行一系列不同的业务操作了,实际上到这一步EXCEL2003与EXCEL2007的兼容性问题已经基本解决了,简单吧?具体实例请阅读本文最后的DEMO,此处不详述。当然,HSSFWorkbook(EXCEL2003)会与XSSFWorkbook(EXCEL2007)有很多差异,通用接口只能满足这两者的交集部分。如下图:(图2)若接口不能完全满足要求,可以通过判断Workbook类型,强制转换成其对应版本的对象,分别作两套或多套方法来处理。这是为满足兼容性值得牺牲,也是必须牺牲的部分。根据实际操作经验,接口能满足绝大部分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 throw new IOException(不能解析的excel版本);2、 扩展性:我们在兼容性部分已经创建了获取兼容Workbook的工厂方法,若遇到其它版本,如EXCEL2010的需求,在工厂方法里添加一个创建EXCEL2010的Workbook条件就行了。修改createCommonWorkbook方法,伪码如下:public static Workbook createCommonWorkbook(InputStream inp)throws IOException, InvalidFormatException . if (输入文件的文件头为EXCEL2010格式) return new EXCEL2010Workbook(inp);. throw new IOException(不能解析的excel版本);既然版本都是固定的,那么再提供一个版本枚举类,不就可以更方便管理不同的EXCEL版本了吗,如果将枚举的VALUE值定义为文件后缀名,也一并解决了不同版本的EXCEL文件后缀名不同的恼人问题,真是一举多得呢。后续即使有更高的Office版本,如EXCEL2010,也只需要添加一个工厂条件,再添加一个枚举项即可实现无缝升级了。枚举类属性如下:/ KEY:版本号/ VALUE:文件后缀名/* EXCEL2003版本 */EXCEL_2003(2003, .xls),/* 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 void main(String args) String path2007 = d:2007.xlsx;String path2003 = d:2003.xls;Test.Demo(path2003);public static void Demo(String filePath)InputStream is = null;try is = new BufferedInputStream(new FileInputStream(new File(filePath);/调用工具类,获取兼容的Workbook接口(兼容性)Workbook wb = CompatibleExcelUtil.createCommonWorkbook(is);/获取首个单元格值(具体业务处理)Sheet sheet = wb.getSheetAt(0);sheet.getRow(0);Row row = sheet.getRow(0);Cell cell = row.getCell(0);/调用工具类,返回版本枚举ExcelVersionTypeEnum ev =CompatibleExcelUtil.checkExcelVersion(wb);/控制台打印信息System.out.println(EXCEL版本号: + ev);System.out.println(文件后缀名: + ev.getValue() + (即使此DEMO中文件后缀名不规范,此处也能正确识别);System.out.println(首个单元格值: + cell.getNumericCellValue(); catch (Exception e) e.printStackTra

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论