使用NPOI获取Excel表格数据

每一个xls都对应一个唯一的HSSFWorkbook,每一个HSSFWorkbook会有若干个HSSFSheet,而每一个HSSFSheet包含若干HSSFRow(Excel 2003中不得超过65535行),每一个HSSFRow又包含若干个HSSFCell(Excel 2003中不得超过256列)。

为了遍历所有的单元格,我们就得获得某一个HSSFSheet的所有HSSFRow,通常可以用HSSFSheet.GetRowEnumerator()。如果要获得某一特定行,可以直接用HSSFSheet.GetRow(rowIndex)。另外要遍历我们就必须知道边界,有一些属性我们是可以用的,比如

HSSFSheet.FirstRowNum(工作表中第一个有数据行的行号)、HSSFSheet.LastRowNum(工作表中最后一个有数据行的行号)、HSSFRow.FirstCellNum(一行中第一个有数据列的列号)、HSSFRow.LastCellNum(一行中最后一个有数据列的列号)。

首先我们要准备一个用于打开文件流的函数InitializeWorkbook,由于文件读完后就没用了,所以这里直接用using。

using (var file = new FileStream(path, FileMode.Open, FileAccess.Read))
{
    var hssfworkbook = new HSSFWorkbook(file);
    var sheet = hssfworkbook.GetSheetAt(0);
    var rows = sheet.GetRowEnumerator();
    var dt = new DataTable();
    for (var j = 0; j < 5; j++)
    {
        dt.Columns.Add(Convert.ToChar(((int) 'A') + j).ToString());
    }
    while (rows.MoveNext())
    {
        var row = (HSSFRow) rows.Current;
        var dr = dt.NewRow();
        for (var i = 0; i < row.LastCellNum; i++)
        {
            var cell = row.GetCell(i);
            if (cell == null)
            {
                dr[i] = null;
            }
            else
            {
                dr[i] = cell.ToString();
            }
        }
        dt.Rows.Add(dr);
    }
}

上面的结构大家都应该能看懂吧,无非就是先遍历行,再遍历行中的每一列。这里引出了一个难点,由于Excel的单元格有好几种类型,类型不同显示的东西就不同,具体的类型有 布尔型、数值型、文本型、公式型、空白、错误。

public enum HSSFCellType
{
    Unknown = -1,
    NUMERIC = 0,
    STRING = 1,
    FORMULA = 2,
    BLANK = 3,
    BOOLEAN = 4,
    ERROR = 5
}

这里的HSSFCellType描述了所有的类型,但细心的朋友可能已经发现了,这里没有日期型,这是为什么呢?这是因为Excel底层并没有一定日期型,而是通过数值型来替代,至于如何区分日期和数字,都是由文本显示的样式决定的,在NPOI中则是由

HSSFDataFormat来处理。为了能够方便的获得所需要的类型所对应的文本,我们可以使用HSSFCell.ToString()来处理。

于是刚才的代码则变成了这样:

switch(cell.CellType)
{
    case HSSFCellType.BLANK:
    dr[i] = "[null]";
    break;
    case HSSFCellType.BOOLEAN:
    dr[i] = cell.BooleanCellValue;
    break;
    case HSSFCellType.NUMERIC:
    dr[i] = cell.ToString();
    break;
    case HSSFCellType.STRING:
    dr[i] = cell.StringCellValue;
    break;
    case HSSFCellType.ERROR:
    dr[i] = cell.ErrorCellValue;
    break;
    case HSSFCellType.FORMULA:
    default:
    dr[i] = "=" + cell.CellFormula;
    break;
}

 

posted @ 2012-12-17 14:43  coolbing  阅读(5140)  评论(3编辑  收藏  举报