Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to speed up autosizing columns in apache POI?

I use the following code in order to autosize columns in my spreadsheet:

for (int i = 0; i < columns.size(); i++) {    sheet.autoSizeColumn(i, true);    sheet.setColumnWidth(i, sheet.getColumnWidth(i) + 600); } 

The problem is it takes more than 10 minutes to autosize each column in case of large spreadsheets with more than 3000 rows. It goes very fast for small documents though. Is there anything which could help autosizing to work faster?

like image 286
antken Avatar asked Sep 24 '13 13:09

antken


People also ask

How do I automatically adjust column width in Excel using Apache POI?

sheetName. autoSizeColumn(columnIndex);

How do I set cell width in Hssfworkbook?

The real answer is that Sheet. setColumnWidth(int index, int width) sets the column with for the column to width*256. You are correct in your assertion that index is zero based column number. The width is specified in 1/256 of a character.

How do I wrap text in Excel using Apache POI?

setWrapText(true); cell. setCellStyle(cellStyle); Saving a file generated with the above code and viewing it in Microsoft Excel will show multiline text in a cell.

What is autoSizeColumn?

autoSizeColumn(int column) Adjusts the column width to fit the contents. void. autoSizeColumn(int column, boolean useMergedCells) Adjusts the column width to fit the contents.


2 Answers

Solution which worked for me:

It was possible to avoid merged regions, so I could iterate through the other cells and finally autosize to the largest cell like this:

int width = ((int)(maxNumCharacters * 1.14388)) * 256; sheet.setColumnWidth(i, width); 

where 1.14388 is a max character width of the "Serif" font and 256 font units.

Performance of autosizing improved from 10 minutes to 6 seconds.

like image 97
antken Avatar answered Sep 24 '22 23:09

antken


The autoSizeColumn function itself works not perfect and some columns width not exactly fit the data inside. So, I found some solution that works for me.

  1. To avoid crazy calculations let give that to autoSizeColumn() function:
   sheet.autoSizeColumn(<columnIndex>); 
  1. Now, our column autosized by library but we wont to add a little bit more to the current column width to make table looks fine:
   // get autosized column width    int currentColumnWidth = sheet.getColumnWidth(<columnIndex>);     // add custom value to the current width and apply it to column    sheet.setColumnWidth(<columnIndex>, (currentColumnWidth + 2500)); 
  1. The full function could looks like:
   public void autoSizeColumns(Workbook workbook) {         int numberOfSheets = workbook.getNumberOfSheets();         for (int i = 0; i < numberOfSheets; i++) {             Sheet sheet = workbook.getSheetAt(i);             if (sheet.getPhysicalNumberOfRows() > 0) {                 Row row = sheet.getRow(sheet.getFirstRowNum());                 Iterator<Cell> cellIterator = row.cellIterator();                 while (cellIterator.hasNext()) {                     Cell cell = cellIterator.next();                     int columnIndex = cell.getColumnIndex();                     sheet.autoSizeColumn(columnIndex);                     int currentColumnWidth = sheet.getColumnWidth(columnIndex);                     sheet.setColumnWidth(columnIndex, (currentColumnWidth + 2500));                 }             }         }     } 

P.S. Thanks Ondrej Kvasnovsky for the function https://stackoverflow.com/a/35324693/13087091

like image 43
Vladimir Shcherbukhin Avatar answered Sep 22 '22 23:09

Vladimir Shcherbukhin