【问题标题】:Error while reading Excel sheet using Java使用 Java 读取 Excel 工作表时出错
【发布时间】:2012-03-08 16:27:12
【问题描述】:

我正在使用 NetBeans 6.9.1 处理 Spring/Hibernet。我正在尝试读取 Excel 文件 (.xlsx-Office 2007)。读取 Excel 文件的代码如下,使用 Vactor 存储 Excel 工作表中的数据。

import java.io.FileInputStream;
import java.util.Iterator;
import java.util.Vector;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import model.NewHibernateUtil;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.hibernate.Session;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

private Vector importExcelSheet(ModelAndView mv)
{
    Vector cellVectorHolder = new Vector();
    try
    {         
        HSSFWorkbook myWorkBook = new HSSFWorkbook(new POIFSFileSystem(new FileInputStream("E:/Project/SpringHibernet/MultiplexTicketBookingNew/web/excelSheets/Country.xlsx")));
        HSSFSheet mySheet = myWorkBook.getSheetAt(0);
        Iterator rowIter = mySheet.rowIterator();
        System.out.println(mySheet.getRow(1).getCell(0));
        while(rowIter.hasNext())
        {
            HSSFRow myRow = (HSSFRow) rowIter.next();
            Iterator cellIter = myRow.cellIterator();
            Vector cellStoreVector=new Vector();
            while(cellIter.hasNext())
            {
                HSSFCell myCell = (HSSFCell) cellIter.next();
                cellStoreVector.addElement(myCell);
            }
            cellVectorHolder.addElement(cellStoreVector);
        }
    }
    catch (Exception e)
    {
        mv.addObject("msg", e.getMessage());
    }
    return cellVectorHolder;
}

下面是我Controller中的一个方法,调用上面的方法读取指定的Excel文件


@Override
protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors) throws Exception
{
    ModelAndView mv=new ModelAndView();

    try
    {
        if(request.getParameter("import")!=null)
        {
            session=NewHibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();

            Vector dataHolder=importExcelSheet(mv);
            for (int i=0;i<dataHolder.size(); i++)
            {
                Vector cellStoreVector=(Vector)dataHolder.elementAt(i);
                for (int j=0; j < cellStoreVector.size();j++)
                {
                    HSSFCell myCell = (HSSFCell)cellStoreVector.elementAt(j);
                    String st = myCell.toString();
                    System.out.println(st.substring(0,1)+"\t");
                }
                System.out.println();
            }

            session.flush();
            session.getTransaction().commit();
        }
    }
    catch (Exception e)
    {
        mv.addObject("msg", e.getMessage());
    }
    return mv;
}

在执行此代码时,会引发以下异常。

提供的数据似乎在 Office 2007+ XML 中。你是 调用处理 OLE2 Office 文档的 POI 部分。你 需要调用 POI 的不同部分来处理这些数据(例如 XSSF 而不是 HSSF)

是我使用了错误的源代码还是上面的代码有其他问题?解决办法是什么?

代码取自here

【问题讨论】:

  • 我下载了另一个apache.poi api并使用org.apache.poi.xssf.usermodel.*包而不是使用org.apache.poi.hssf.usermodel.*包,它适用于xlsxlsx
  • 请尽快将其作为答案发布并接受。

标签: java excel apache-poi


【解决方案1】:

您的代码目前明确请求 HSSF,因此仅适用于较旧的 .xls(二进制)文件。

如果您愿意,您可以要求 POI 自动检测您拥有的文件类型,并为您的案例选择适当的 HSSF 或 XSSF 之一。但是,要做到这一点,您需要稍微更改代码,并使用接口而不是具体类(因此无论您获得 HSSF 还是 XSSF 对象,您的代码都可以正常工作)

POI 网站上有一个guide to making these changes,它应该会引导您完成。

作为一个例子,当你遵循这个时,你的前几行是:

    HSSFWorkbook myWorkBook = new HSSFWorkbook(new POIFSFileSystem(new FileInputStream("E:/Project/SpringHibernet/MultiplexTicketBookingNew/web/excelSheets/Country.xlsx")));
    HSSFSheet mySheet = myWorkBook.getSheetAt(0);
    Iterator rowIter = mySheet.rowIterator();
    System.out.println(mySheet.getRow(1).getCell(0));

将成为新系统:

    Workbook wb = WorkbookFactory.create(new File("/path/to/your/excel/file"));
    Sheet mySheet = wb.getSheetAt(0);
    Iterator<Row> rowIter = mySheet.rowIterator();
    System.out.println(mySheet.getRow(1).getCell(0));

这将适用于 .xls 和 .xlsx 文件

【讨论】:

  • 我使用了与您提到的相同的方法,并且按预期工作。谢谢。
  • 为了回答的完整性,WorbookFactory 是 poi-ooxml.jar 的一部分
【解决方案2】:

您也可以将 HSSF 替换为 XSSF。

确保在 poi .jar 之外添加 poi-ooxml .jar。 poi-ooxml 提供对 XSSF 的支持。确保您还添加了Apache POI components page 中列出的给定依赖项。

【讨论】:

  • 这就是我知道后一直在做的事情。不过谢谢你的接力。附言由于日程繁忙,我不能经常访问这个网站。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-08
  • 1970-01-01
相关资源
最近更新 更多