Apache POI - CellStyles applied to cells on cloned sheet appear on original sheet

Mike :

In a program I'm writing, I prepare an excel sheet ("master") and clone it multiple times. Each time I clone this master sheet I apply CellStyles to specific cells on the new cloned sheet. The problem is, every time I apply CellStyles to the cells on the sheet(s) I clone, the styles kept appearing on the master sheet and all other cloned sheets. Here's the snippet that shows how I'm doing the cloning:

for (Member member : allMembers) {
    memberName = member.getFirstName();
    // `schedule` below is a WorkBook object
    XSSFSheet individualSheet = schedule.cloneSheet(0, memberName);

    highlightMemberNames(individualSheet, memberName);
}

What highlightMemberNames(individualSheet, memberName) is doing is highlighting the cells in individualSheet that contain memberName. Here's it's code:

void highlightMemberNames(XSSFSheet individualSheet, String memberName) {
    for (Row row : individualSheet) {
        for (Cell cell : row) {
            if (cell.getStringCellValue().equals(memberName)) {
                cell.getCellStyle().setFillBackgroundColor(IndexedColors.LIGHT_GREEN.index);
                cell.getCellStyle().setFillForegroundColor(IndexedColors.LIGHT_GREEN.index);
                cell.getCellStyle().setFillPattern(FillPatternType.SOLID_FOREGROUND);
                cell.getCellStyle().setAlignment(HorizontalAlignment.CENTER);
            }
        }
    }
}

Is there a way to avoid this problem?

Axel Richter :

In Excel files cell styles are on workbook level and not on worksheet level or on cell level. So your cell.getCellStyle() gets a cell style from workbook level which also may be applied to other cells in other worksheets already. If you then change that style this changes all cells in all worksheets which have that cell style applied.

You need creating all needed cell styles on workbook level first and then applying those styles to cells or you need using CellUtil methods. Using CellUtil methods should be the preferred approach.

CellUtil methods are made for setting single cell style properties to single cells. The methods then internally decide whether new cell styles needs to be created on workbook level or whether there are such styles already which only needs to be applied.

In your case this could look like:

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellUtil;

import java.util.Map;
import java.util.HashMap;

...

 void highlightMemberNames(Sheet individualSheet, String memberName) {
  Map<String, Object> properties = new HashMap<String, Object>();
  properties.put(CellUtil.FILL_PATTERN, FillPatternType.SOLID_FOREGROUND);
  properties.put(CellUtil.FILL_FOREGROUND_COLOR, IndexedColors.LIGHT_GREEN.getIndex());
  properties.put(CellUtil.ALIGNMENT, HorizontalAlignment.CENTER);
  for (Row row : individualSheet) {
   for (Cell cell : row) {
    if (cell.getCellType() == CellType.STRING && cell.getStringCellValue().equals(memberName)) {
     CellUtil.setCellStyleProperties(cell, properties); 
    }
   }
  }
 }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=130687&siteId=1