Search code examples
javaapache-poiborderexcel-2013apache-poi-4

How to set border by leaving one cell space along each side of entire data using Apache POI 4.0.1 and java


  • Currently, I'm able to set border beside the entire data (You can refer following image).

Current output


Code snippet

  // Code to draw Border at left side
    int rowstart = 3, rowend = 9;
    int col = 2;
    for (rowstart = 1; rowstart <= rowend; rowstart++) {
        Row rowL = sheet.createRow(rowstart); 
        Cell cell = rowL.createCell(col); 
        {
            XSSFCellStyle style = workbook.createCellStyle();
            style.setBorderLeft(BorderStyle.MEDIUM);
            cell.setCellStyle(style);
        }
    }

    // Code to draw Border at bottom
    int colstart1 = 2, colend1 = 6;

    Row rowB = sheet.createRow(90);
    for (colstart1 = 2; colstart1 <= colend1; colstart1++) {
        Cell cellB = rowB.createCell(colstart1);
        XSSFCellStyle style = workbook.createCellStyle();
        style.setBorderTop(BorderStyle.MEDIUM);
        cellB.setCellStyle(style);
    }

    // Code to draw Border at top
    int colstart = 2, colend = 6;

    Row rowT = sheet.createRow(0);
    for (colstart = 2; colstart <= colend; colstart++) {
        Cell cell = rowT.createCell(colstart);
        XSSFCellStyle style = workbook.createCellStyle();
        style.setBorderBottom(BorderStyle.MEDIUM);
        cell.setCellStyle(style);
    }

    // Code to draw Border at Right side
    int rowstart1 = 1, rowend1 = 9;
    for (rowstart1 = 1; rowstart1 <= rowend1; rowstart1++) {
        Row rowR = sheet.getRow(rowstart1); 
        Cell cellR = rowR.createCell(20); 
        {
            XSSFCellStyle style = workbook.createCellStyle();
            style.setBorderRight(BorderStyle.MEDIUM);
            cellR.setCellStyle(style);
        }
    }

  • I want to set border beside entire data but by leaving one cell space between data and border (You can refer following image).

Expected output


Solution

  • Don't do drawing borders that complicated way.

    If one wants doing this that way (using single CellStyles) then one would need creating 8 single cell styles. One having borders for top left edge, one having borders for top line, one having borders for top right edge, one having borders for left line, one having borders for the right line, one having borders for bottom left edge, one having borders for bottom line and one having borders for bottom right edge. Then, after creating the cells and filling them with content, the correct cell style (one out of the 8 created before) must be applied to the cell.

    That's ugly and complicated to code. So people often are doing what you do and simply create a new cell style for each single cell. But Excel is limited in count of unique cell formats/cell styles. See Excel specifications and limits. So having big sheets having much data, one easily exceeds that limit of 64,000 unique cell formats/cell styles. So simply creating a new cell style for each single cell is wrong.

    Drawing Borders in Busy Developers' Guide to HSSF and XSSF Features shows how to do it better.

    Complete Example:

    import java.io.FileOutputStream;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.ss.util.PropertyTemplate;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    class ExcelDrawingBorders {
    
     public static void main(String[] args) throws Exception {
    
      try (Workbook workbook = new XSSFWorkbook(); 
           FileOutputStream fileout = new FileOutputStream("ExcelDrawingBorders.xlsx") ) {
    
       int startDataRow = 4;
       int endDataRow = 8;
       int startDataColumn = 2;
       int endDataColumn = 6;
    
       Sheet sheet = workbook.createSheet();
    
       for (int r = startDataRow; r <= endDataRow; r++) {
        Row row = sheet.createRow(r);
        for (int c = startDataColumn; c <= endDataColumn; c++) {
         Cell cell = row.createCell(c);
         cell.setCellFormula("RANDBETWEEN(10,50)");
        }
       }
    
       PropertyTemplate propertyTemplate = new PropertyTemplate();
       propertyTemplate.drawBorders(new CellRangeAddress(startDataRow-1, endDataRow+1, startDataColumn-1, endDataColumn+1), 
        BorderStyle.MEDIUM, BorderExtent.OUTSIDE);
    
       propertyTemplate.applyBorders(sheet);
    
       workbook.write(fileout);
    
      }
     }
    }
    

    Result:

    enter image description here

    Here the PropertyTemplate and CellUtil does the whole work for you. The PropertyTemplate creates the needed properties Maps. And while applying to the sheet, it uses CellUtil which creates the 8 needed cell styles on workbook level and applies them to the correct cells. Even not already present but needed cells will be created.