bug 61474, github #81: implement updateConditionalFormatting for ColumnShifter

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1814259 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Javen O'Neal 2017-11-04 07:58:41 +00:00
parent 7c88f32408
commit 4d526bfd01
3 changed files with 67 additions and 59 deletions

View File

@ -61,10 +61,9 @@ public final class XSSFColumnShifter extends ColumnShifter {
throw new NotImplementedException("updateSheetFormulas");
}
@NotImplemented
@Override
public void updateConditionalFormatting(FormulaShifter formulaShifter) {
throw new NotImplementedException("updateConditionalformatting");
XSSFRowColShifter.updateConditionalFormatting(sheet, formulaShifter);
}
/**

View File

@ -26,7 +26,11 @@ import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCfRule;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTConditionalFormatting;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
import java.util.ArrayList;
import java.util.List;
/**
@ -57,6 +61,67 @@ import java.util.List;
}
}
/*package*/ static void updateConditionalFormatting(Sheet sheet, FormulaShifter formulaShifter) {
XSSFSheet xsheet = (XSSFSheet) sheet;
XSSFWorkbook wb = xsheet.getWorkbook();
int sheetIndex = wb.getSheetIndex(sheet);
final int rowIndex = -1; //don't care, structured references not allowed in conditional formatting
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
CTWorksheet ctWorksheet = xsheet.getCTWorksheet();
CTConditionalFormatting[] conditionalFormattingArray = ctWorksheet.getConditionalFormattingArray();
// iterate backwards due to possible calls to ctWorksheet.removeConditionalFormatting(j)
for (int j = conditionalFormattingArray.length - 1; j >= 0; j--) {
CTConditionalFormatting cf = conditionalFormattingArray[j];
ArrayList<CellRangeAddress> cellRanges = new ArrayList<>();
for (Object stRef : cf.getSqref()) {
String[] regions = stRef.toString().split(" ");
for (String region : regions) {
cellRanges.add(CellRangeAddress.valueOf(region));
}
}
boolean changed = false;
List<CellRangeAddress> temp = new ArrayList<>();
for (CellRangeAddress craOld : cellRanges) {
CellRangeAddress craNew = shiftRange(formulaShifter, craOld, sheetIndex);
if (craNew == null) {
changed = true;
continue;
}
temp.add(craNew);
if (craNew != craOld) {
changed = true;
}
}
if (changed) {
int nRanges = temp.size();
if (nRanges == 0) {
ctWorksheet.removeConditionalFormatting(j);
continue;
}
List<String> refs = new ArrayList<>();
for(CellRangeAddress a : temp) refs.add(a.formatAsString());
cf.setSqref(refs);
}
for(CTCfRule cfRule : cf.getCfRuleArray()){
String[] formulaArray = cfRule.getFormulaArray();
for (int i = 0; i < formulaArray.length; i++) {
String formula = formulaArray[i];
Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex, rowIndex);
if (formulaShifter.adjustFormula(ptgs, sheetIndex)) {
String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
cfRule.setFormulaArray(i, shiftedFmla);
}
}
}
}
}
/*package*/ static void updateHyperlinks(Sheet sheet, FormulaShifter formulaShifter) {
int sheetIndex = sheet.getWorkbook().getSheetIndex(sheet);
List<? extends Hyperlink> hyperlinkList = sheet.getHyperlinkList();

View File

@ -169,63 +169,7 @@ public final class XSSFRowShifter extends RowShifter {
@Override
public void updateConditionalFormatting(FormulaShifter formulaShifter) {
XSSFSheet xsheet = (XSSFSheet) sheet;
XSSFWorkbook wb = xsheet.getWorkbook();
int sheetIndex = wb.getSheetIndex(sheet);
final int rowIndex = -1; //don't care, structured references not allowed in conditional formatting
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create(wb);
CTWorksheet ctWorksheet = xsheet.getCTWorksheet();
CTConditionalFormatting[] conditionalFormattingArray = ctWorksheet.getConditionalFormattingArray();
// iterate backwards due to possible calls to ctWorksheet.removeConditionalFormatting(j)
for (int j = conditionalFormattingArray.length - 1; j >= 0; j--) {
CTConditionalFormatting cf = conditionalFormattingArray[j];
ArrayList<CellRangeAddress> cellRanges = new ArrayList<>();
for (Object stRef : cf.getSqref()) {
String[] regions = stRef.toString().split(" ");
for (String region : regions) {
cellRanges.add(CellRangeAddress.valueOf(region));
}
}
boolean changed = false;
List<CellRangeAddress> temp = new ArrayList<>();
for (CellRangeAddress craOld : cellRanges) {
CellRangeAddress craNew = shiftRange(formulaShifter, craOld, sheetIndex);
if (craNew == null) {
changed = true;
continue;
}
temp.add(craNew);
if (craNew != craOld) {
changed = true;
}
}
if (changed) {
int nRanges = temp.size();
if (nRanges == 0) {
ctWorksheet.removeConditionalFormatting(j);
continue;
}
List<String> refs = new ArrayList<>();
for(CellRangeAddress a : temp) refs.add(a.formatAsString());
cf.setSqref(refs);
}
for(CTCfRule cfRule : cf.getCfRuleArray()){
String[] formulaArray = cfRule.getFormulaArray();
for (int i = 0; i < formulaArray.length; i++) {
String formula = formulaArray[i];
Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex, rowIndex);
if (formulaShifter.adjustFormula(ptgs, sheetIndex)) {
String shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
cfRule.setFormulaArray(i, shiftedFmla);
}
}
}
}
XSSFRowColShifter.updateConditionalFormatting(sheet, formulaShifter);
}
/**