NPOI是否支持.xlsx格式?

10

NPOI DLL能够识别.xlsx文件吗?

目前我正在使用NPOI 1.2.5版本DLL来处理Microsoft Excel 97-2003文件,但我也需要访问扩展名为.xlsx的Excel表格文件。

NPOI是否支持上述功能?

代码片段:

static void Main(string[] args) {
    XSSFWorkbook xssfwb;

    using(FileStream file=new FileStream(
            @"C:\Users\347702\Desktop\Hello.xlsx",
            FileMode.Open, FileAccess.Read)) {
        xssfwb=new XSSFWorkbook(file);
    }

    ISheet sheet=xssfwb.GetSheet("sheet1");
    sheet.GetRow(1048576);
    Console.WriteLine(sheet.GetRow(1048576).GetCell(0).StringCellValue);
}

1
是的,我经常使用NPOI导入.xlsx文件 - 没有任何问题 - 只需编写代码即可! - marc_s
但是当我尝试使用 .xlsx 文件加载时,导入失败了? - Ganeshja
根据这篇博客文章,NPOI从1.6版本开始支持.xlsx。该博客文章还展示了早期版本NPOI的“解决方法”。 - marc_s
是的,但在上面的代码片段中,我试图加载 .xlsx 文件并尝试获取最后一行的值,最后一行为:1,048,576,因此我在第1048576行列A处提到了一个示例值称为“Test”,但它在控制台输出时抛出以下错误:对象引用未设置为对象的实例。 - Ganeshja
所以你使用列0(getcell(0))。在这种情况下,我猜行从0到...?1048575! - K_B
只是补充一下,NPOI在幕后使用了微软的Open XML SDK for Office - undefined
4个回答

19
你可以使用NPOI读取扩展名为.xls和.xlsx的Excel文件,只需要在using部分添加以下内容。
using NPOI.HSSF.UserModel;
using NPOI.HPSF;
using NPOI.POIFS.FileSystem;
using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;

重要的是在打开文件时区分文件扩展名,使用相应的组件,并使用ISheet接口,这样可以独立于文件扩展名引用工作表。

//We get the file extension
fileExt = Path.GetExtension(fileName);

//Declare the sheet interface
ISheet sheet;

//Get the Excel file according to the extension
if (fileExt.ToLower() == ".xls")
{
    //Use the NPOI Excel xls object
    HSSFWorkbook hssfwb;
    using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        hssfwb = new HSSFWorkbook(file);
    }

    //Assign the sheet
    sheet = hssfwb.GetSheet(sheetName);
}
else //.xlsx extension
{
    //Use the NPOI Excel xlsx object
    XSSFWorkbook hssfwb;
    using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        hssfwb = new XSSFWorkbook(file);
    }

    //Assign the sheet
    sheet = hssfwb.GetSheet(sheetName);
}

一旦您拥有了 Excel 对象,您只需要读取它(在 NPOI 中,行和列都是从零开始计数)

//Loop through the rows until we find an empty one
for (int row = 0; row <= sheet.LastRowNum; row++)
{
    //Get the cell value
    string cellValue = sheet.GetRow(row).GetCell(0).ToString().Trim(); //In the method GetCell you specify the column number you want to read, in the method GetRow you spacify the row
    string cellValue2 = sheet.GetRow(row).GetCell(0).StringCellValue.Trim();
}

要读取单元格的值,您可以使用 .ToString() 方法或 StringCellValue 属性,但请注意,StringCellValue 仅适用于字符串单元格,对于数字和日期单元格,它会抛出异常。


14

是的,它可以。NPOI 2.0 beta 可以工作。这是一个示例代码,可以帮助你入门:

class Program
{
static XSSFWorkbook hssfworkbook;
static DataSet dataSet1 = new DataSet();

static void Main(string[] args)
{
    InitializeWorkbook(@"E:\Docs\HoursWidget_RTM.xlsx");
    xlsxToDT();

    DisplayData(dataSet1.Tables[0]);

    Console.ReadLine();
}

static void InitializeWorkbook(string path)
{
    using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read))
    {
        hssfworkbook = new XSSFWorkbook(file);
    }
}

static void xlsxToDT()
{
    DataTable dt = new DataTable();
    ISheet sheet = hssfworkbook.GetSheetAt(1);
    IRow headerRow = sheet.GetRow(0);
    IEnumerator rows = sheet.GetRowEnumerator();

    int colCount = headerRow.LastCellNum;
    int rowCount = sheet.LastRowNum;

    for (int c = 0; c < colCount; c++)
    {

        dt.Columns.Add(headerRow.GetCell(c).ToString());
    }

    bool skipReadingHeaderRow = rows.MoveNext();
    while (rows.MoveNext())
    {
        IRow row = (XSSFRow)rows.Current;
        DataRow dr = dt.NewRow();

        for (int i = 0; i < colCount; i++)
        {
            ICell cell = row.GetCell(i);

            if (cell != null)
            {
                dr[i] = cell.ToString();
            }
        }
        dt.Rows.Add(dr);
    }

    hssfworkbook = null;
    sheet = null;
    dataSet1.Tables.Add(dt);
}

static void DisplayData(DataTable table)
{
    foreach (DataRow row in table.Rows)
    {
        foreach (DataColumn col in table.Columns)
        {
            Console.WriteLine("{0} = {1}", col.ColumnName, row[col]);
        }
        Console.WriteLine("-------------------------------------------");
    }
}
}

OP说:“目前我正在使用NPOI 1.2.5版本”,而不是2.0版本... - Just a HK developer

3

也许在原始答案提供时,该库没有这个功能,但现在您可以使用相同的代码基础处理xls和xlsx,而无需检查文件扩展名。

这个技巧是使用WorkbookFactory类来透明地加载两种类型的文件。只要不使用特定于任一版本的特殊功能,就可以正常工作。

using (FileStream fileStream = File.OpenRead(fullPathToExcelFile)) //fullPathToExcelFile can hold either a xls or xlsx, we don't care
{
   IWorkbook workbook = WorkbookFactory.Create(fileStream);
   ISheet worksheet = workbook.GetSheet("SampleSheet");

   //Now read from the worksheet anyway you like
   var value = worksheet.GetRow(1).GetCell(1);
}

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接