`
ssxxjjii
  • 浏览: 938406 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java解析获取Excel中的数据--同时兼容2003及2007

 
阅读更多

java解析Excel(兼容2003及2007)


刚开始从网上找了个例子使用new HSSFWorkbook(new FileInputStream(excelFile))来读取Workbook,
对Excel2003以前(包括2003)的版本没有问题,但读取Excel2007时发生如下异常:
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+XML保存的,而现在却调用OLE2 Office文档处理,应该使用POI不同的部分来处理这些数据,比如使用XSSF来代替HSSF。

        于是按提示使用XSSF代替HSSF,用new XSSFWorkbook(excelFile)来读取Workbook,对Excel2007没有问题了,可是在读取Excel2003以前(包括2003)的版本时却发生了如下新异常:
org.apache.poi.openxml4j.exceptions.InvalidOperationException: Can't open the specified file: '*.xls'
        该错误是说,操作无效,不能打开指定的xls文件。

        到网上查了下,原来是XSSF不能读取Excel2003以前(包括2003)的版本,这样的话,就需要在读取前判断文件是2003前的版本还是2007的版本,然后对应调用HSSF或XSSF来读取。
        这种做法比较麻烦,看了下API,发现XSSF和HSSF虽然在不同的包里,但却引用了同一接口Workbook,于是想到了这样的读取方法:
        Workbook book = null;
        try {
            book = new XSSFWorkbook(excelFile);
        } catch (Exception ex) {
            book = new HSSFWorkbook(new FileInputStream(excelFile));
        }
        
本认为程序应该没错了吧,但一运行还是报错(当时用得是poi3.6的zip包):

java.lang.ClassNotFoundException: org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet

网上搜了下,是少poi-ooxml-schemas-xxx.jar包,根据提示在Apache网站上(http://labs.renren.com/apache-mirror//poi/release/bin/)下载了3.7的zip文件(poi-bin-3.7-20101029.zip),解压后将poi相关的包和xml相关的包都放上去。

在各版本的Excel中测试,没有发生异常,问题解决。

下面是POI的API网址,不过是英文的:
POI API Documentation
http://poi.apache.org/apidocs/index.html

 

   转入正题:以下是代码,代码也是从别人的代码拿过来的,其中修改了部分

  1. package com.execl;  
  2.   
  3. import java.io.File;  
  4.   
  5. import java.io.FileInputStream;  
  6.   
  7. import java.io.IOException;  
  8.   
  9. import java.io.InputStream;  
  10.   
  11. import java.util.ArrayList;  
  12.   
  13. import java.util.List;  
  14.   
  15. import org.apache.poi.hssf.usermodel.HSSFCell;  
  16. import org.apache.poi.hssf.usermodel.HSSFWorkbook;  
  17.   
  18. import org.apache.poi.ss.usermodel.Cell;  
  19.   
  20. import org.apache.poi.ss.usermodel.Row;  
  21.   
  22. import org.apache.poi.ss.usermodel.Sheet;  
  23.   
  24. import org.apache.poi.ss.usermodel.Workbook;  
  25.   
  26. import org.apache.poi.xssf.usermodel.XSSFWorkbook;  
  27.   
  28. /** 
  29.  *  
  30.  * @描述:测试excel读取 
  31.  *  
  32.  *               导入的jar包 
  33.  *  
  34.  *               poi-3.8-beta3-20110606.jar 
  35.  *  
  36.  *               poi-ooxml-3.8-beta3-20110606.jar 
  37.  *  
  38.  *               poi-examples-3.8-beta3-20110606.jar 
  39.  *  
  40.  *               poi-excelant-3.8-beta3-20110606.jar 
  41.  *  
  42.  *               poi-ooxml-schemas-3.8-beta3-20110606.jar 
  43.  *  
  44.  *               poi-scratchpad-3.8-beta3-20110606.jar 
  45.  *  
  46.  *               xmlbeans-2.3.0.jar 
  47.  *  
  48.  *               dom4j-1.6.1.jar 
  49.  *  
  50.  *               jar包官网下载地址:http://poi.apache.org/download.html 
  51.  *  
  52.  *               下载poi-bin-3.8-beta3-20110606.zipp 
  53.  *  
  54.  * @作者:建宁 
  55.  *  
  56.  * @时间:2012-08-29 下午16:27:15 
  57.  */  
  58.   
  59. public class ImportExecl  
  60. {  
  61.   
  62.     /** 总行数 */  
  63.   
  64.     private int totalRows = 0;  
  65.   
  66.     /** 总列数 */  
  67.   
  68.     private int totalCells = 0;  
  69.   
  70.     /** 错误信息 */  
  71.   
  72.     private String errorInfo;  
  73.   
  74.     /** 构造方法 */  
  75.   
  76.     public ImportExecl()  
  77.     {  
  78.   
  79.     }  
  80.   
  81.     /** 
  82.      *  
  83.      * @描述:得到总行数 
  84.      *  
  85.      * @作者:建宁 
  86.      *  
  87.      * @时间:2012-08-29 下午16:27:15 
  88.      *  
  89.      * @参数:@return 
  90.      *  
  91.      * @返回值:int 
  92.      */  
  93.   
  94.     public int getTotalRows()  
  95.     {  
  96.   
  97.         return totalRows;  
  98.   
  99.     }  
  100.   
  101.     /** 
  102.      *  
  103.      * @描述:得到总列数 
  104.      *  
  105.      * @作者:建宁 
  106.      *  
  107.      * @时间:2012-08-29 下午16:27:15 
  108.      *  
  109.      * @参数:@return 
  110.      *  
  111.      * @返回值:int 
  112.      */  
  113.   
  114.     public int getTotalCells()  
  115.     {  
  116.   
  117.         return totalCells;  
  118.   
  119.     }  
  120.   
  121.     /** 
  122.      *  
  123.      * @描述:得到错误信息 
  124.      *  
  125.      * @作者:建宁 
  126.      *  
  127.      * @时间:2012-08-29 下午16:27:15 
  128.      *  
  129.      * @参数:@return 
  130.      *  
  131.      * @返回值:String 
  132.      */  
  133.   
  134.     public String getErrorInfo()  
  135.     {  
  136.   
  137.         return errorInfo;  
  138.   
  139.     }  
  140.   
  141.     /** 
  142.      *  
  143.      * @描述:验证excel文件 
  144.      *  
  145.      * @作者:建宁 
  146.      *  
  147.      * @时间:2012-08-29 下午16:27:15 
  148.      *  
  149.      * @参数:@param filePath 文件完整路径 
  150.      *  
  151.      * @参数:@return 
  152.      *  
  153.      * @返回值:boolean 
  154.      */  
  155.   
  156.     public boolean validateExcel(String filePath)  
  157.     {  
  158.   
  159.         /** 检查文件名是否为空或者是否是Excel格式的文件 */  
  160.   
  161.         if (filePath == null || !(WDWUtil.isExcel2003(filePath) || WDWUtil.isExcel2007(filePath)))  
  162.         {  
  163.   
  164.             errorInfo = "文件名不是excel格式";  
  165.   
  166.             return false;  
  167.   
  168.         }  
  169.   
  170.         /** 检查文件是否存在 */  
  171.   
  172.         File file = new File(filePath);  
  173.   
  174.         if (file == null || !file.exists())  
  175.         {  
  176.   
  177.             errorInfo = "文件不存在";  
  178.   
  179.             return false;  
  180.   
  181.         }  
  182.   
  183.         return true;  
  184.   
  185.     }  
  186.   
  187.     /** 
  188.      *  
  189.      * @描述:根据文件名读取excel文件 
  190.      *  
  191.      * @作者:建宁 
  192.      *  
  193.      * @时间:2012-08-29 下午16:27:15 
  194.      *  
  195.      * @参数:@param filePath 文件完整路径 
  196.      *  
  197.      * @参数:@return 
  198.      *  
  199.      * @返回值:List 
  200.      */  
  201.   
  202.     public List<List<String>> read(String filePath)  
  203.     {  
  204.   
  205.         List<List<String>> dataLst = new ArrayList<List<String>>();  
  206.   
  207.         InputStream is = null;  
  208.   
  209.         try  
  210.         {  
  211.   
  212.             /** 验证文件是否合法 */  
  213.   
  214.             if (!validateExcel(filePath))  
  215.             {  
  216.   
  217.                 System.out.println(errorInfo);  
  218.   
  219.                 return null;  
  220.   
  221.             }  
  222.   
  223.             /** 判断文件的类型,是2003还是2007 */  
  224.   
  225.             boolean isExcel2003 = true;  
  226.   
  227.             if (WDWUtil.isExcel2007(filePath))  
  228.             {  
  229.   
  230.                 isExcel2003 = false;  
  231.   
  232.             }  
  233.   
  234.             /** 调用本类提供的根据流读取的方法 */  
  235.   
  236.             File file = new File(filePath);  
  237.   
  238.             is = new FileInputStream(file);  
  239.   
  240.             dataLst = read(is, isExcel2003);  
  241.   
  242.             is.close();  
  243.   
  244.         }  
  245.         catch (Exception ex)  
  246.         {  
  247.   
  248.             ex.printStackTrace();  
  249.   
  250.         }  
  251.         finally  
  252.         {  
  253.   
  254.             if (is != null)  
  255.             {  
  256.   
  257.                 try  
  258.                 {  
  259.   
  260.                     is.close();  
  261.   
  262.                 }  
  263.                 catch (IOException e)  
  264.                 {  
  265.   
  266.                     is = null;  
  267.   
  268.                     e.printStackTrace();  
  269.   
  270.                 }  
  271.   
  272.             }  
  273.   
  274.         }  
  275.   
  276.         /** 返回最后读取的结果 */  
  277.   
  278.         return dataLst;  
  279.   
  280.     }  
  281.   
  282.     /** 
  283.      *  
  284.      * @描述:根据流读取Excel文件 
  285.      *  
  286.      * @作者:建宁 
  287.      *  
  288.      * @时间:2012-08-29 下午16:40:15 
  289.      *  
  290.      * @参数:@param inputStream 
  291.      *  
  292.      * @参数:@param isExcel2003 
  293.      *  
  294.      * @参数:@return 
  295.      *  
  296.      * @返回值:List 
  297.      */  
  298.   
  299.     public List<List<String>> read(InputStream inputStream, boolean isExcel2003)  
  300.     {  
  301.   
  302.         List<List<String>> dataLst = null;  
  303.   
  304.         try  
  305.         {  
  306.   
  307.             /** 根据版本选择创建Workbook的方式 */  
  308.   
  309.             Workbook wb = null;  
  310.   
  311.             if (isExcel2003)  
  312.             {  
  313.                 wb = new HSSFWorkbook(inputStream);  
  314.             }  
  315.             else  
  316.             {  
  317.                 wb = new XSSFWorkbook(inputStream);  
  318.             }  
  319.             dataLst = read(wb);  
  320.   
  321.         }  
  322.         catch (IOException e)  
  323.         {  
  324.   
  325.             e.printStackTrace();  
  326.   
  327.         }  
  328.   
  329.         return dataLst;  
  330.   
  331.     }  
  332.   
  333.     /** 
  334.      *  
  335.      * @描述:读取数据 
  336.      *  
  337.      * @作者:建宁 
  338.      *  
  339.      * @时间:2012-08-29 下午16:50:15 
  340.      *  
  341.      * @参数:@param Workbook 
  342.      *  
  343.      * @参数:@return 
  344.      *  
  345.      * @返回值:List<List<String>> 
  346.      */  
  347.   
  348.     private List<List<String>> read(Workbook wb)  
  349.     {  
  350.   
  351.         List<List<String>> dataLst = new ArrayList<List<String>>();  
  352.   
  353.         /** 得到第一个shell */  
  354.   
  355.         Sheet sheet = wb.getSheetAt(0);  
  356.   
  357.         /** 得到Excel的行数 */  
  358.   
  359.         this.totalRows = sheet.getPhysicalNumberOfRows();  
  360.   
  361.         /** 得到Excel的列数 */  
  362.   
  363.         if (this.totalRows >= 1 && sheet.getRow(0) != null)  
  364.         {  
  365.   
  366.             this.totalCells = sheet.getRow(0).getPhysicalNumberOfCells();  
  367.   
  368.         }  
  369.   
  370.         /** 循环Excel的行 */  
  371.   
  372.         for (int r = 0; r < this.totalRows; r++)  
  373.         {  
  374.   
  375.             Row row = sheet.getRow(r);  
  376.   
  377.             if (row == null)  
  378.             {  
  379.   
  380.                 continue;  
  381.   
  382.             }  
  383.   
  384.             List<String> rowLst = new ArrayList<String>();  
  385.   
  386.             /** 循环Excel的列 */  
  387.   
  388.             for (int c = 0; c < this.getTotalCells(); c++)  
  389.             {  
  390.   
  391.                 Cell cell = row.getCell(c);  
  392.   
  393.                 String cellValue = "";  
  394.   
  395.                 if (null != cell)  
  396.                 {  
  397.                     // 以下是判断数据的类型  
  398.                     switch (cell.getCellType())  
  399.                     {  
  400.                     case HSSFCell.CELL_TYPE_NUMERIC: // 数字  
  401.                         cellValue = cell.getNumericCellValue() + "";  
  402.                         break;  
  403.   
  404.                     case HSSFCell.CELL_TYPE_STRING: // 字符串  
  405.                         cellValue = cell.getStringCellValue();  
  406.                         break;  
  407.   
  408.                     case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean  
  409.                         cellValue = cell.getBooleanCellValue() + "";  
  410.                         break;  
  411.   
  412.                     case HSSFCell.CELL_TYPE_FORMULA: // 公式  
  413.                         cellValue = cell.getCellFormula() + "";  
  414.                         break;  
  415.   
  416.                     case HSSFCell.CELL_TYPE_BLANK: // 空值  
  417.                         cellValue = "";  
  418.                         break;  
  419.   
  420.                     case HSSFCell.CELL_TYPE_ERROR: // 故障  
  421.                         cellValue = "非法字符";  
  422.                         break;  
  423.   
  424.                     default:  
  425.                         cellValue = "未知类型";  
  426.                         break;  
  427.                     }  
  428.                 }  
  429.   
  430.                 rowLst.add(cellValue);  
  431.   
  432.             }  
  433.   
  434.             /** 保存第r行的第c列 */  
  435.   
  436.             dataLst.add(rowLst);  
  437.   
  438.         }  
  439.   
  440.         return dataLst;  
  441.   
  442.     }  
  443.   
  444.     /** 
  445.      *  
  446.      * @描述:main测试方法 
  447.      *  
  448.      * @作者:建宁 
  449.      *  
  450.      * @时间:2012-08-29 下午17:12:15 
  451.      *  
  452.      * @参数:@param args 
  453.      *  
  454.      * @参数:@throws Exception 
  455.      *  
  456.      * @返回值:void 
  457.      */  
  458.   
  459.     public static void main(String[] args) throws Exception  
  460.     {  
  461.   
  462.         ImportExecl poi = new ImportExecl();  
  463.   
  464.         // List<List<String>> list = poi.read("d:/aaa.xls");  
  465.   
  466.         List<List<String>> list = poi.read("c:/book.xlsx");  
  467.   
  468.         if (list != null)  
  469.         {  
  470.   
  471.             for (int i = 0; i < list.size(); i++)  
  472.             {  
  473.   
  474.                 System.out.print("第" + (i) + "行");  
  475.   
  476.                 List<String> cellList = list.get(i);  
  477.   
  478.                 for (int j = 0; j < cellList.size(); j++)  
  479.                 {  
  480.   
  481.                     // System.out.print("    第" + (j + 1) + "列值:");  
  482.   
  483.                     System.out.print("    " + cellList.get(j));  
  484.   
  485.                 }  
  486.                 System.out.println();  
  487.   
  488.             }  
  489.   
  490.         }  
  491.   
  492.     }  
  493.   
  494. }  
  495.   
  496. /** 
  497.  *  
  498.  * @描述:工具类 
  499.  *  
  500.  * @作者:建宁 
  501.  *  
  502.  * @时间:2012-08-29 下午16:30:40 
  503.  */  
  504.   
  505. class WDWUtil  
  506. {  
  507.   
  508.     /** 
  509.      *  
  510.      * @描述:是否是2003的excel,返回true是2003 
  511.      *  
  512.      * @作者:建宁 
  513.      *  
  514.      * @时间:2012-08-29 下午16:29:11 
  515.      *  
  516.      * @参数:@param filePath 文件完整路径 
  517.      *  
  518.      * @参数:@return 
  519.      *  
  520.      * @返回值:boolean 
  521.      */  
  522.   
  523.     public static boolean isExcel2003(String filePath)  
  524.     {  
  525.   
  526.         return filePath.matches("^.+\\.(?i)(xls)$");  
  527.   
  528.     }  
  529.   
  530.     /** 
  531.      *  
  532.      * @描述:是否是2007的excel,返回true是2007 
  533.      *  
  534.      * @作者:建宁 
  535.      *  
  536.      * @时间:2012-08-29 下午16:28:20 
  537.      *  
  538.      * @参数:@param filePath 文件完整路径 
  539.      *  
  540.      * @参数:@return 
  541.      *  
  542.      * @返回值:boolean 
  543.      */  
  544.   
  545.     public static boolean isExcel2007(String filePath)  
  546.     {  
  547.   
  548.         return filePath.matches("^.+\\.(?i)(xlsx)$");  
  549.   
  550.     }  
  551.   
  552. }  

 

 

分享到:
评论
1 楼 贝塔ZQ 2016-09-29  
java实现操作excel文件,PageOffice插件可以实现的,兼容03,07office文件,用起来是很方便的。他们官网上有不少事例代码的,可以下载看看,集成起来也方便,可以根据事例进行了解的。

相关推荐

    Java解析Excel兼容2003和2007(有实例和类包)

    本篇将深入探讨如何使用POI库来解析和创建2003及2007版本的Excel文件,并提供相关实例和类包。 Apache POI提供了两个主要的API,HSSF(Horrible Spreadsheet Format)用于处理老版的BIFF8格式(.xls,Excel 2003及...

    java读取excel(兼容2003和2007)

    Excel文件格式有两种主要版本,即2003年的.xls格式和2007年及以后的.xlsx格式。为了兼容这两种格式,Java引入了Apache POI库,这是一个用于处理Microsoft Office文档的开源API。 Apache POI提供了HSSF(Horrible ...

    java处理excel库,poi-bin-4.1.0-20190412

    ava解析Excel(兼容2003及2007):解析2003及以下使用HSSFWorkbook类, 解析2007及以上使用XSSFWorkbook, 如果解析类与excel版本不对应,抛出相应的异常,例如HSSFWorkbook解析2007: org.apache.poi.poifs....

    java编写的兼容2003、2007Excel文件读取工程

    在本项目中,我们关注的是“java编写的兼容2003、2007Excel文件读取工程”。这个工程的目标是实现一个Java程序,能够读取Microsoft Excel的两种主要格式:.xls(用于2003及更早版本)和.xlsx(用于2007及更高版本)...

    Excel-nurbs-java_java_excel_

    - **读取Excel文件**:使用Apache POI解析Excel文件,提取NURBS数据。 - **NURBS计算**:实现NURBS算法,包括控制点、权重、knot向量的处理,生成曲线或曲面。 - **数据结构**:设计合适的Java类来存储和操作NURBS...

    Java读写Excel(基于xxl-excel)

    Java读写Excel是一项常见的任务,尤其在数据处理和报表生成中。Xxl-Excel是一个流行的Java库,专门用于处理Excel文件,提供了简单易用的API,使得开发人员能够方便地进行Excel的读取和写入操作。在这个示例中,我们...

    java读取数据量大的excel文件(2003及2007)

    在Java编程中,处理大量数据的Excel文件是一项常见的任务,特别是对于数据分析、数据导入或导出等场景。这里我们主要探讨如何使用Java有效地读取2003版和2007版这两种不同格式的大型Excel文件。 1. **Apache POI库*...

    导入Excel2003-2007兼容问题,4个包

    在Java开发中,如果需要操作Excel文件,开发者可以使用Apache POI、JExcelAPI等库,其中Apache POI提供了对不同版本Excel文件格式的支持,包括解决2003和2007版本的兼容问题。 具体到压缩包子文件的文件名称列表...

    java、Android实现Excel表的解析读取操作

    3. 解析Excel的注意事项: - 文件路径:在Java中,路径通常是文件系统的绝对路径;在Android中,可能是内部存储或外部存储的路径,或者从Assets或Raw资源中加载。 - 版本兼容:不同的Excel版本(如xls和xlsx)可能...

    好用的excel导入导出工具for Java(兼容2003和2007)

    本文将深入探讨如何使用一个优秀的Java库来高效地实现Excel的导入和导出,尤其针对Excel 2003和2007格式的兼容性。 标题中的“好用的excel导入导出工具for Java”指的是Java开发中的一种专门处理Excel的库,它允许...

    Java操作Excel之理解JXL-读取Excel.docx

    JXL是一个Java API,专为处理Microsoft Excel文件设计,支持在任何Java兼容的操作系统上运行。以下是详细的解析: 1. **JXL库介绍** - JXL是一个开源的Java库,用于读写Excel文件。 - 官方主页:...

    poi-3.16(Java解析Excel)

    Apache POI 是一个开源项目,专门用于处理微软...以上是关于Apache POI-3.16在Java中解析Excel的基本介绍和使用要点,通过这个库,开发者可以轻松地在Java应用程序中与Excel文件进行交互,实现数据的导入、导出和处理。

    Java解析Excel的opi.jar包

    Java解析Excel是一项常见的任务,特别是在数据处理和报告生成的场景中。`poi.jar`库是Apache POI项目的一部分,这是一个开源的Java API,专门用于处理Microsoft Office格式的文件,包括Excel(.xls和.xlsx)。在Java...

    java导出excel2007

    本文将深入探讨如何使用Apache POI库来实现在Java中导出Excel 2007文件,同时也会涉及如何处理Excel 2003的.xls格式。 Apache POI是Apache软件基金会的一个项目,它提供了一组API,用于读写Microsoft Office格式的...

    Excel2html-纯java实现excel转html

    在"Excel2html"中,开发者可能利用了POI库来解析Excel文件,获取每个单元格的内容、样式信息(如边框、颜色、字体、字号等),然后将这些信息转换为HTML标签和CSS样式,以重现Excel的视觉效果。 转换过程中,边框线...

    java类显示excel数据

    10. **版本兼容性**: 需要考虑Excel文件的不同版本(如97-2003的`.xls`和2007及以后的`.xlsx`),因为这可能需要不同的ODBC驱动或Apache POI的API。 通过以上知识点,你可以构建一个Java类,它能够连接到ODBC数据源...

    Java避免UTF-8的csv文件打开中文出现乱码的方法

    Java避免UTF-8的csv文件打开中文出现乱码的方法 在Java中,避免UTF-8的csv文件打开中文出现乱码的方法是非常重要的。...同时,需要考虑Excel版本的兼容性问题,以确保csv文件可以正确地被打开和读取。

    解析Excel格式数据的poi的jar包

    在这个场景中,我们将深入探讨如何使用Apache POI的jar包来解析Excel格式的数据。 首先,Apache POI提供了两个主要的API用于处理Excel文件:HSSF(Horrible Spreadsheet Format)用于处理老版的BIFF格式(.xls),...

Global site tag (gtag.js) - Google Analytics