2013-02-23 10 views
1

Я пытаюсь преобразовать файл .xlsx в формат DataTable с помощью библиотеки NPOI 2.0. Все в порядке, но у меня проблема с преобразованием в строку date date. Когда я пытаюсь использовать конструкцию типа row.GetCell (j) .ToString() - это исключение «Невозможно получить числовое значение из текстовой ячейки». Я попытался использовать свойство DateCellValue, но он также исключил это исключение. С другими форматами ящиков это хорошо. функции, которые я использую это:C#. Импорт ячейки xlsx в DataTable с помощью NPOI 2.0

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; 
    } 

UPDATE: Если вставить код, как

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

в проблемной ячейке у меня есть значение, как "36496.392581018517". Другие ячейки преобразовывались правильно

+0

Я попытался это с ячейкой даты и ошибки не было. Каково содержимое вашей камеры? –

+0

MD.Unicorn, 02.12.1999 9:25:19. Свойство ячейки написано, что это формат даты, но теперь я вижу, что если я скопирую и вставляю ячейку (а не значение ячейки) - она ​​только вставляется «02.12.1999» ... – user2102277

+0

Ничего не кажется неправильным. Какова ценность 'CellType'? –

ответ

2

Второй столбец вашего файла excel имеет формат даты (12/2/1999). Этот формат не распознается NPOI в вашей текущей культуре («ru-RU»). Это похоже на ошибку в 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; 
    } 
} 
+0

Большое спасибо! Это работает! – user2102277

0
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; 
    } 
} 
+0

Если это 'Numeric', лучше проверить, является ли это датой, используя' DateUtil.IsCellDateFormatted (cell) '. Если да, 'dataRow [j] = cell.DateCellValue;' – user3454439

-1

Это правильный код XLS

public DataTable GetDataTableFromExcelFile(string excel_file_Path) 
{ 
    HSSFWorkbook wb; 
    NPOI.SS.UserModel.ISheet sh; 
    string Sheet_name; 

    using (var fs = new FileStream(excel_file_Path, FileMode.Open, FileAccess.Read)) 
    { 
     wb = new HSSFWorkbook(fs); 

     Sheet_name = wb.GetSheetAt(0).SheetName; //get first sheet name 
    } 
    DataTable DT = new DataTable(); 
    DT.Rows.Clear(); 
    DT.Columns.Clear(); 

    // get sheet 
    sh = wb.GetSheet(Sheet_name); 

    // add neccessary columns 
    if (DT.Columns.Count < sh.GetRow(0).Cells.Count) 
    { 
     for (int j = 0; j < sh.GetRow(0).Cells.Count; j++) 
     { 
      DT.Columns.Add(Convert.ToString(sh.GetRow(0).Cells[j]), typeof(string)); 
     } 
    } 

    // add row 
    DT.Rows.Add(); 

    int i = 1; 
    while (sh.GetRow(i) != null) 
    { 
     // write row value 
     for (int j = 0; j < sh.GetRow(i).Cells.Count; j++) 
     { 
      var cell = sh.GetRow(i).GetCell(j); 

      if (cell != null) 
      { 
       // TODO: you can add more cell types capatibility, e. g. formula 
       switch (cell.CellType) 
       { 
        case CellType.Numeric: 
         DT.Rows[i][j] = sh.GetRow(i).GetCell(j).NumericCellValue; 
         //dataGridView1[j, i].Value = sh.GetRow(i).GetCell(j).NumericCellValue; 

         break; 
        case CellType.String: 
         DT.Rows[i-1][j] = sh.GetRow(i).GetCell(j).StringCellValue; 

         break; 
       } 
      } 
     } 

     i++; 
    } 

    return DT; 
} 
+1

Не могли бы вы объяснить, что делает ваш код? Хотя он * может * быть технически корректным, блок кода поможет другим гораздо больше с блоком текста, объясняющим, что он делает, и * why *. BTW, кто-то [отметил ваш ответ как сообщение низкого качества] (http://stackoverflow.com/review/low-quality-posts/10891310), потому что [ответы на основе кода недоверчивы] (http: //meta.stackexchange .com/д/148272/284827). –

Смежные вопросы