4

NPOI 2.0 ライブラリを使用して .xlsx ファイルを DataTable 形式に変換しようとしています。大丈夫ですが、文字列の日付セルへの変換に問題があります。row.GetCell(j).ToString() のような構造を使用しようとすると、「テキスト セルから数値を取得できません」という例外がスローされます。DateCellValue プロパティを使用しようとしましたが、この例外もスローされました。他のセル形式ではうまく機能します。私が使用する機能は次のとおりです。

private DataTable xlsxToDT(string fileName)
    {
        DataTable table = new DataTable();
        XSSFWorkbook workbook = new XSSFWorkbook(new FileStream(fileName, FileMode.Open, FileAccess.Read));
        ISheet sheet = workbook.GetSheetAt(0);
        IRow headerRow = sheet.GetRow(0);
        int cellCount = headerRow.LastCellNum;
        for (int i = headerRow.FirstCellNum; i < cellCount; i++)
        {
            DataColumn column = new DataColumn(headerRow.GetCell(i).StringCellValue);
            table.Columns.Add(column);
        }
        int rowCount = sheet.LastRowNum;
        for (int i = (sheet.FirstRowNum); i < sheet.LastRowNum; i++)
        {
            IRow row = sheet.GetRow(i);
            DataRow dataRow = table.NewRow();
            for (int j = row.FirstCellNum; j < cellCount; j++)
            {
                if (row.GetCell(j) != null)
                {
                    //EXCEPTION GENERATING IN THIS CODE
                    dataRow[j] = row.GetCell(j).ToString();
                    ////////////////////////////
                }
            }
            table.Rows.Add(dataRow);
        }
        workbook = null;
        sheet = null;
        return table;
    }

更新:次のようなコードを挿入すると

row.GetCell(j).SetCellType(CellType.STRING);

問題のセルには、「36496.392581018517」のような値があります。別のセルが正しく変換されました

4

4 に答える 4

3

Excel ファイルの 2 列目に日付形式 ( 12/2/1999) があります。この形式は、現在のカルチャ (「ru-RU」) では NPOI によって認識されません。これは NPOI のバグのようです。これが発生すると、そのセルから何も読み取る方法がないためです。私がたどり着いた唯一の方法は、Excelファイルを読み取る前にスレッドのカルチャを変更することです(その後、元に戻す):

private DataTable xlsxToDT(string fileName)
{
    var prevCulture = Thread.CurrentThread.CurrentCulture;
    Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
    try
    {
        // Put your whole method body here.
    }
    finally
    {
        Thread.CurrentThread.CurrentCulture = prevCulture;
    }
}
于 2013-02-24T11:34:20.310 に答える
2
ICell cell = row.GetCell(j);
if (cell != null)
{
    switch (cell.CellType)
    {
        case CellType.String:
            dataRow[j] = cell.StringCellValue;
            break;
        case CellType.Numeric:
            dataRow[j] = cell.NumericCellValue;
            break;
        case CellType.Boolean:
            dataRow[j] = cell.BooleanCellValue;
            break;
        default: dataRow[j] = "ERROR";
            break;
    }
}
于 2014-04-02T02:01:01.067 に答える