Hi everyone!
I am copying cells (value and cellstyle) from one workbook to another,
using the code below.
Now i have two xlsx files, where src.xlsx is the source - where the values are copied from - and the
second one is dst.xlsx.
The dst.xlsx has conditional formatting, e.g. the cells of the first column are "green" if the value is "1" (numeric).
The problem is, the copied cells are not formatted automatically anymore.
That means, the copied cell in column one has the value "1" but is not green (at least not in excel, in libreoffice it is).
It's easy to fix it by hand: Simply select the cell, right click, select filling options and click on the already selected "automatic" or "none".
Afterwards, the cell is correctly displayed in green.
The reason for this behaviour seems to be the following:
POI creates a new FillStyle:
Code:
<patternFill>
<fgColor indexed="64"/>
<bgColor indexed="64"/>
</patternFill>
even if a cell is set to NONE by:
Code:
CellUtil.setCellStyleProperty(newCell, CellUtil.FILL_PATTERN, FillPatternType.NO_FILL);
The correct (or at least "working") solution would be to set the cell to the predefined (fillId=0):
Code:
<fill>
<patternFill patternType="none"/>
</fill>
Excel seems to apply conditional formatting only to two sorts of cells:
1) Those who have the "default" fillstyle - that means fillId=0
2) Those, who have set the fillstyle to: patternType="solid">
Looks like a bug in POI, or at least in Excel... right?
Any suggestions for a workaround? What I need is a way to set the FillStyle (only) to the default one (fillId=0)
Greetings, Flo
Code:
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellUtil;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
public class copyHelper{
private final XSSFSheet srcSheet;
private final XSSFSheet dstSheet;
public copyHelper(XSSFSheet srcWorksheet, XSSFSheet dstWorkheet){
this.srcSheet = srcWorksheet;
this.dstSheet = dstWorkheet;
}
public void copyMergedRegions(){
List<CellRangeAddress> rgLst = srcSheet.getMergedRegions();
for(CellRangeAddress rg : rgLst)
dstSheet.addMergedRegion(rg);
}
public void copyRow(int srcRowNum, int dstRowNum) {
// Get the srcSheet row at srcRowNum
// and the dstSheet row at dstRowNum
XSSFRow srcRow = srcSheet.getRow(srcRowNum);
// If the row doesn't exist in the destination worksheet, create
if(dstSheet.getRow(dstRowNum) == null)
dstSheet.createRow(dstRowNum);
XSSFRow dstRow = dstSheet.getRow(dstRowNum);
// Loop through srcSheet columns to add to new row
for (int i = 0; i < srcRow.getLastCellNum(); i++) {
// Grab a referencing copy of the old/new cell
XSSFCell oldCell = srcRow.getCell(i);
XSSFCell newCell = dstRow.createCell(i);
// If the old cell is null jump to next cell
if (oldCell == null) {
newCell = null;
continue;
}
// Copy style from old cell and apply to new cell
// TODO: Do not copy each and every CellStyle since that leads to
// some sort of CellStyle explosion
// XSSFCellStyle newStyle = dstSheet.getWorkbook().createCellStyle();
// newStyle.cloneStyleFrom(oldCell.getCellStyle());
// newCell.setCellStyle(newStyle);
Map<String, Object> prop = new HashMap<>();
prop.put(CellUtil.ROTATION, oldCell.getCellStyle().getRotation());
CellUtil.setCellStyleProperties(newCell, prop);
// If there is a cell comment, copy
if (oldCell.getCellComment() != null)
newCell.setCellComment(oldCell.getCellComment());
// If there is a cell hyperlink, copy
if (oldCell.getHyperlink() != null)
newCell.setHyperlink(oldCell.getHyperlink());
// Set the cell data type
newCell.setCellType(oldCell.getCellType());
// Set the cell data value
switch (oldCell.getCellType()) {
case Cell.CELL_TYPE_BLANK:
newCell.setCellValue(oldCell.getStringCellValue());
break;
case Cell.CELL_TYPE_BOOLEAN:
newCell.setCellValue(oldCell.getBooleanCellValue());
break;
case Cell.CELL_TYPE_ERROR:
newCell.setCellErrorValue(oldCell.getErrorCellValue());
break;
case Cell.CELL_TYPE_FORMULA:
newCell.setCellFormula(oldCell.getCellFormula());
break;
case Cell.CELL_TYPE_NUMERIC:
newCell.setCellValue(oldCell.getNumericCellValue());
break;
case Cell.CELL_TYPE_STRING:
newCell.setCellValue(oldCell.getRichStringCellValue());
break;
}
}
}
}