137

I am using Apache POI API to generate excel spreadsheet to output some data.

The problem I am facing is when the spreadsheet is created and opened, columns are not expanded so that some long text like Date formatted text is not showing up on first glance.

I could just double click the column border in excel to expand or drag the border to adjust the column width but there could be 20+ columns and there is no way I want to do that manually every time I open the spreadsheet :(

I found out (though could be wrong method) groupRow() and setColumnGroupCollapsed() might be able to do the trick but no luck. Maybe I'm using it in wrong way.

Sample Code snippet

        Workbook wb = new HSSFWorkbook();
        CreationHelper createHelper = wb.getCreationHelper();
        //create sheet
        Sheet sheet = wb.createSheet("masatoSheet");

        //not really working yet.... :(
        //set group for expand/collapse
        //sheet.groupRow(0, 10); //just random fromRow toRow argument values...
        //sheet.setColumnGroupCollapsed(0, true);

        //create row
        Row row = sheet.createRow((short)0);
        //put a cell in the row and store long text data
        row.createCell(0).setCellValue("Loooooooong text not to show up first");

When this spreadsheet is created, the "Looooooong text not to show up first" string is in the cell but since the column is not expanded only "Loooooooo" is showing up.

How can I configure it so that when I open my spreadsheet, the column is already expanded???

Meow
  • 18,371
  • 52
  • 136
  • 180
  • http://stackoverflow.com/questions/20190317/apache-poi-excel-big-auto-column-width – gavenkoa Feb 07 '14 at 11:07
  • You seem to be looking for a way to use POI to accomplish this. But to do it simply in Excel select the entire sheet and double click the A-B column heading boundary. If you need to do this to several sheets a coded solution may serve you better. – avg Apr 11 '14 at 18:21
  • Check out my answer in other post: https://stackoverflow.com/a/73571342/13227834 – Jakub Słowikowski Sep 01 '22 at 14:49

12 Answers12

215

After you have added all your data to the sheet, you can call autoSizeColumn(int column) on your sheet to autofit the columns to the proper size

Here is a link to the API.

See this post for more reference Problem in fitting the excel cell size to the size of the content when using apache poi

IvanRF
  • 7,115
  • 5
  • 47
  • 71
Sean
  • 7,597
  • 1
  • 24
  • 26
  • 14
    Just wanted to point out that `autoSizeColumn` does not scale well and will be *super* slow if you have lots of rows. I had to get a little hacky and do something similar to what was suggested [in this question](http://stackoverflow.com/questions/18983203/how-to-speed-up-autosizing-columns-in-apache-poi). – lbstr Apr 17 '14 at 20:17
  • 14
    **Warning about** *autoSizeColumn*, this requires java Font be available. This is not part of the headless java jre used on servers and will throw a NullPointerException. – Stephen Dillon Oct 02 '17 at 20:28
  • @StephenDillon Any idea how to fix the null pointer for font configuration ? – Vishal Jul 16 '20 at 17:03
  • The best way we found was to loop over each row in the col, find the longest char length and multiply by x + add a buffer. X use trial and error to see what fits but it should be a average width of a char. Without font I don't believe you can actually get it right but we get pretty close. Otherwise you can add a macro to excel to fix it all the first time the user opens it, that was the best method but requires macros be enabled – Stephen Dillon Jul 17 '20 at 19:26
  • 1
    As others pointed out in comments, autoSizeColumn works, but it slows down A LOT, I used it in my project and the difference was about 3 seconds on 10 rows, imagine having hunders - thousands of rows –  Jul 01 '21 at 17:19
  • It works but it is too slow. Check my answer here -> https://stackoverflow.com/a/73571342/13227834 – Jakub Słowikowski Sep 01 '22 at 14:50
55

If you want to auto size all columns in a workbook, here is a method that might be useful:

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);
            }
        }
    }
}
paul
  • 13,312
  • 23
  • 81
  • 144
Ondrej Kvasnovsky
  • 4,592
  • 3
  • 30
  • 40
  • I am getting `NullPointerException` at `row.cellIterator()`. Is it because i have no value in one of the cell? – rakeeee Jun 18 '20 at 13:09
  • Have you tried to create a more general solution? Because the current one doesn't seem to work well with merged regions. I mean if you use somewhere sheet.addMergedRegion(new CellRangeAddress(...)) the approach won't work well. – ka3ak Mar 03 '23 at 13:33
54

Tip : To make Auto size work , the call to sheet.autoSizeColumn(columnNumber) should be made after populating the data into the excel.

Calling the method before populating the data, will have no effect.

Unni Kris
  • 3,081
  • 4
  • 35
  • 57
  • 1
    https://stackoverflow.com/questions/37069820/android-poi-crash-when-using-autosizecolumn sometimes that not working – Roman Soviak Mar 26 '19 at 12:19
  • The answer provided here is related to Java, whereas the link provided in the comment is related to Android. The answer still works in all Java cases (except for headless java JREs which don't have the java Font available). – Unni Kris Mar 29 '19 at 08:28
  • thanks, I calculated func, and used setColumnWidth in the following way: `(5 until row.lastCellNum).forEach { colNum -> val columnWidth = (row.getCell(colNum).toString().length * 0.44 + 2.24) * 768 reportSheet.setColumnWidth(colNum, columnWidth.toInt()) } ` – Roman Soviak Mar 29 '19 at 15:03
  • @user7856586 can u elaborate this method in a little more detail for me – Mehroz Mustafa Jul 20 '20 at 15:31
11

You can try something like this:

HSSFSheet summarySheet = wb.createSheet();
summarySheet.setColumnWidth(short column, short width);

Here params are:column number in sheet and its width But,the units of width are pretty small, you can try 4000 for example.

John Joe
  • 12,412
  • 16
  • 70
  • 135
UVM
  • 9,776
  • 6
  • 41
  • 66
  • Good to know thanks! I think for my purpose where the column string might get generated dynamically, auto-sizing method would fit in the case. – Meow Jan 06 '11 at 08:57
8

For Excel POI:

sheetName.autoSizeColumn(cellnum); 
Rolando Isidoro
  • 4,983
  • 2
  • 31
  • 43
Adnan Ghaffar
  • 1,345
  • 7
  • 26
  • 46
8

If you know the count of your columns (f.e. it's equal to a collection list). You can simply use this one liner to adjust all columns of one sheet (if you use at least java 8):

IntStream.range(0, columnCount).forEach(sheet::autoSizeColumn)
snap
  • 1,598
  • 1
  • 14
  • 21
  • A few years old, but when you're at it, make it shorter by using the method reference: `IntStream.range(0, columnCount).forEach(sheet::autoSizeColumn)` – BAERUS May 24 '22 at 11:32
  • @BAERUS thanks! i have adjusted it to use your suggested shorter variant – snap May 24 '22 at 11:52
6

sample code below

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("your sheet name");
HSSFRow row = sheet.createRow(0);

cell = row.createCell(0);
cell.setCellValue("A BIG NAME WITH AUTO SIZE FEATURE ENABLED");

//this is crucial

sheet.autoSizeColumn(0);

//argument must be cell number

cell = row.createCell(1);
cell.setCellValue("a big name without auto size feature enabled");

Check the output and go nuts :)

Mateen
  • 1,631
  • 1
  • 23
  • 27
4

You can add this, after your loop.

for (int i = 0; i<53;i++) {
    sheet.autoSizeColumn(i);
}
Italo Oré
  • 67
  • 4
3

I use below simple solution:

This is your workbook and sheet:

XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("YOUR Workshhet");

then add data to your sheet with columns and rows. Once done with adding data to sheet write following code to autoSizeColumn width.

for (int columnIndex = 0; columnIndex < 15; columnIndex++) {
                    sheet.autoSizeColumn(columnIndex);
                }

Here, instead 15, you add the number of columns in your sheet.

Hope someone helps this.

Rahul Mahadik
  • 11,668
  • 6
  • 41
  • 54
0

You can use setColumnWidth() if you want to expand your cell more.

Petter Friberg
  • 21,252
  • 9
  • 60
  • 109
0

Its very simple, use this one line code dataSheet.autoSizeColumn(0)

or give the number of column in bracket dataSheet.autoSizeColumn(cell number )

0

You can wrap the text as well. PFB sample code:

CellStyle wrapCellStyle = new_workbook.createCellStyle();
                    wrapCellStyle.setWrapText(true);
Akash
  • 89
  • 5