NPOI: столбец Excel отформатирован в десятичный формат с помощью SXSSFWorkbook?

Я занимаюсь разработкой веб-сайта с ASP.net (VS2015 C #).

Мне нужно экспортировать MySql таблица с большим объемом данных (500000+ строк и 100 столбцов), чтобы преуспеть (xlsx), с форматом.

После многих опций библиотека NPOI (v 3.20) разрешает этот экспорт с использованием типов, использующих потоковую передачу (SXSSFWorkbook & SXSSFSheet).

Если я использую XSSFWorkbook Я получаю и из памяти заполняю строки.

С SXSSFWorkbook Я был в состоянии отформатировать xlsx с разными шрифтами и цветами, но у меня проблемы с типами экспортируемых данных:

  • Типы дат в порядке
  • Типы Int хорошо
  • Текст в порядке
  • Ввод десятичных дробей, например, 100.35 -> проблемы, я получаю текстовый столбец. Мне нужен выход, как число 100,35.

Код, который я использую для форматирования данных:

SXSSFWorkbook wb = new SXSSFWorkbook();
SXSSFSheet sh = (SXSSFSheet)wb.CreateSheet("Sheet 1");
sh.SetRandomAccessWindowSize(100);

ICellStyle testStyleHeader = wb.CreateCellStyle();
ICellStyle testStyleRow = wb.CreateCellStyle();

// Header Style
testStyleHeader.FillForegroundColor = NPOI.SS.UserModel.IndexedColors.RoyalBlue.Index;
testStyleHeader.FillPattern = FillPattern.SolidForeground;

// Double style (with 2 decimals like 453.65)
ICellStyle cellStyleDouble = wb.CreateCellStyle();
cellStyleDouble.DataFormat = wb.CreateDataFormat().GetFormat("0.00");

// Font 
XSSFFont hFontBlack = (XSSFFont)wb.CreateFont();
hFontBlack.FontHeightInPoints = 11;
hFontBlack.FontName = "Calibri";
hFontBlack.Color = NPOI.SS.UserModel.IndexedColors.Black.Index;
testStyleHeader.SetFont(hFontBlack);

IRow row = sh.CreateRow(0);
int j = 0;
ICell cell = row.CreateCell(j);

// Fill Header row
cell.SetCellValue("XXXX"); cell.CellStyle = testeStyleHeader; j++; cell = row.CreateCell(j);
cell.SetCellValue("YYYY"); cell.CellStyle = testeStyleHeader; j++; cell = row.CreateCell(j);
cell.SetCellValue("ZZZZ"); cell.CellStyle = testeStyleHeader; j++; cell = row.CreateCell(j);
cell.SetCellValue("WWWW"); cell.CellStyle = testeStyleHeader; j++; cell = row.CreateCell(j);

// Fill Rows
int i = 1; // row Number
IRow row2; // No Header Row
ICell cell2; // No Header cell

while (dr.Read())  // dr is the DataReader
{
   row2 = sh.CreateRow(i);

  for (int cont = 0; cont < NumColumns; cont++) 
  {
     if (cont == 0) // This column is a date
     {
       …. // code for date format
     }
     else if (cont == 3) // Double column with 2 decimals¡! (values samples 100.45   5654.80 etc.)
     {
        ICell cell3 = row2.CreateCell(j, NPOI.SS.UserModel.CellType.Numeric);
        cell3.CellStyle = cellStyleDouble;
        cell3.SetCellValue(Convert.ToDouble(dr[cont]));
      }
     else
     {…. // code for tex format, int format etc.
     }
   }
   i++;

}

С этим кодом в десятичном столбце (продолжение ==3) я получаю текстовый столбец.

Тем не менее, с тем же кодом, если я объявляю нет потоковых типов:

XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sh = (SSFSheet)wb.CreateSheet("Sheet 1");

Только с этими изменениями я получаю идеальный числовой столбец 3...

Для этой строки:

cellStyleDouble.DataFormat = wb.CreateDataFormat (). GetFormat ("0,00");

Я пробовал с разными типами:

  • "#. #"
  • "# ##0,000"
  • "##. #"
  • Так далее…

В некоторых случаях я получаю номер, но не с нужным форматом.

Итак... потоковые типы не позволяют это форматирование?

2 ответа

Просто измените информацию о культуре на en-US

        Thread.CurrentThread.CurrentCulture = new CultureInfo("en-Us");

        ISheet worksheet = Workbook.CreateSheet(dt.TableName);

        IRow HeaderRow = worksheet.CreateRow(0);

        for (int i = 0; i < dt.Columns.Count; i++)
        {
            ICell HeaderCell = HeaderRow.CreateCell(i);

            HeaderCell.SetCellValue(dt.Columns[i].ColumnName);
        }

        for (int j = 0; j < dt.Rows.Count; j++)
        {
            IRow Row = worksheet.CreateRow(j + 1);

            for (int i = 0; i < dt.Columns.Count; i++)
            {
                ICell Cell = Row.CreateCell(i);

                if (dt.Columns[i].DataType.IsOfType(typeof(decimal)) && dt.Rows[j][i] != DBNull.Value)
                {
                    Cell.SetCellType(CellType.Numeric);

                    Cell.SetCellValue((double)dt.Rows[j][i]);
                }
                else
                    Cell.SetCellValue(dt.Rows[j][i].ToString());
            }
        }

        Thread.CurrentThread.CurrentCulture = new CultureInfo("pt-Br");

Меня устраивает!

Можете ли вы попробовать форматирование на основе приведенного ниже фрагмента кода. Я использую этот подход для форматирования номера телефона.

XSSFCellStyle currencyCellStyle = (XSSFCellStyle)workbook.CreateCellStyle();
XSSFDataFormat currencyDataFormat = (XSSFDataFormat)workbook.CreateDataFormat();
currrencyCellStyle.SetDataFormat(currencyDataFormat.GetFormat("00000.00"));  //Formats: #####.##, 00000##.##

иногда сложно найти точное форматирование в NPOI:). Пожалуйста, попробуйте ниже подходов

 ICellStyle CellStyle = workbook.CreateCellStyle();
 CellStyle.DataFormat = workbook.CreateDataFormat().GetFormat("number"); // or Number

или же

CellStyle cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(wb.getCreationHelper().createDataFormat().getFormat("#.#")); // or #####.## or number
Другие вопросы по тегам