bug 61474, github #81: remove @Internal RowShifter#updateRowFormulas, move to XSSFRowColShifter; implement ColumnShifter#updateFormulas; remove duplicated JavaDocs (better to inherit)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1814260 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Javen O'Neal 2017-11-04 08:54:20 +00:00
parent 0f14370c21
commit 890d6e70e6
5 changed files with 121 additions and 172 deletions

View File

@ -20,9 +20,7 @@ package org.apache.poi.hssf.usermodel.helpers;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.formula.eval.NotImplementedException;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.helpers.RowShifter;
import org.apache.poi.util.Internal;
import org.apache.poi.util.NotImplemented;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
@ -51,13 +49,6 @@ public final class HSSFRowShifter extends RowShifter {
throw new NotImplementedException("updateFormulas");
}
@Override
@Internal
@NotImplemented
public void updateRowFormulas(Row row, FormulaShifter formulaShifter) {
throw new NotImplementedException("updateRowFormulas");
}
@Override
@NotImplemented
public void updateConditionalFormatting(FormulaShifter formulaShifter) {

View File

@ -135,11 +135,11 @@ public abstract class RowShifter extends BaseRowColShifter {
* @param row the row to update the formulas on
* @param formulaShifter the formula shifting policy
*/
@Internal
public abstract void updateRowFormulas(Row row, FormulaShifter formulaShifter);
//@Internal
//public abstract void updateRowFormulas(Row row, FormulaShifter formulaShifter);
public abstract void updateConditionalFormatting(FormulaShifter formulaShifter);
/**
* Shift the Hyperlink anchors (not the hyperlink text, even if the hyperlink
* is of type LINK_DOCUMENT and refers to a cell that was shifted). Hyperlinks

View File

@ -17,15 +17,12 @@
package org.apache.poi.xssf.usermodel.helpers;
import org.apache.poi.ss.formula.*;
import org.apache.poi.ss.formula.eval.NotImplementedException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.usermodel.helpers.ColumnShifter;
import org.apache.poi.util.Beta;
import org.apache.poi.util.NotImplemented;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
/**
* Helper for shifting columns up or down
@ -40,42 +37,23 @@ public final class XSSFColumnShifter extends ColumnShifter {
super(sh);
}
/**
* Updated named ranges
*/
@Override
public void updateNamedRanges(FormulaShifter formulaShifter) {
XSSFRowColShifter.updateNamedRanges(sheet, formulaShifter);
}
/**
* Update formulas.
*/
@NotImplemented
@Override
public void updateFormulas(FormulaShifter formulaShifter) {
throw new NotImplementedException("updateFormulas");
}
private void updateSheetFormulas(Sheet sh, FormulaShifter formulaShifter) {
throw new NotImplementedException("updateSheetFormulas");
XSSFRowColShifter.updateFormulas(sheet, formulaShifter);
}
@Override
public void updateConditionalFormatting(FormulaShifter formulaShifter) {
XSSFRowColShifter.updateConditionalFormatting(sheet, formulaShifter);
}
/**
* Shift the Hyperlink anchors (not the hyperlink text, even if the hyperlink
* is of type LINK_DOCUMENT and refers to a cell that was shifted). Hyperlinks
* do not track the content they point to.
*
* @param formulaShifter
*/
@Override
public void updateHyperlinks(FormulaShifter formulaShifter) {
XSSFRowColShifter.updateHyperlinks(sheet, formulaShifter);
}
}

View File

@ -17,7 +17,11 @@
package org.apache.poi.xssf.usermodel.helpers;
import org.apache.poi.ss.formula.*;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.FormulaRenderer;
import org.apache.poi.ss.formula.FormulaParseException;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.helpers.BaseRowColShifter;
@ -26,9 +30,7 @@ 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 org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
import java.util.ArrayList;
import java.util.List;
@ -45,7 +47,8 @@ import java.util.List;
/**
* Updated named ranges
*/
/*package*/ static void updateNamedRanges(Sheet sheet, FormulaShifter formulaShifter) {
/*package*/
static void updateNamedRanges(Sheet sheet, FormulaShifter formulaShifter) {
Workbook wb = sheet.getWorkbook();
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create((XSSFWorkbook) wb);
for (Name name : wb.getAllNames()) {
@ -61,6 +64,107 @@ import java.util.List;
}
}
/**
* Update formulas.
*/
/*package*/ static void updateFormulas(Sheet sheet, FormulaShifter formulaShifter) {
//update formulas on the parent sheet
updateSheetFormulas(sheet,formulaShifter);
//update formulas on other sheets
Workbook wb = sheet.getWorkbook();
for(Sheet sh : wb)
{
if (sheet == sh) continue;
updateSheetFormulas(sh, formulaShifter);
}
}
/*package*/ static void updateSheetFormulas(Sheet sh, FormulaShifter formulashifter) {
for (Row r : sh) {
XSSFRow row = (XSSFRow) r;
updateRowFormulas(row, formulashifter);
}
}
/**
* Update the formulas in specified row using the formula shifting policy specified by shifter
*
* @param row the row to update the formulas on
* @param formulaShifter the formula shifting policy
*/
/*package*/ static void updateRowFormulas(XSSFRow row, FormulaShifter formulaShifter) {
XSSFSheet sheet = (XSSFSheet) row.getSheet();
for (Cell c : row) {
XSSFCell cell = (XSSFCell) c;
CTCell ctCell = cell.getCTCell();
if (ctCell.isSetF()) {
CTCellFormula f = ctCell.getF();
String formula = f.getStringValue();
if (formula.length() > 0) {
String shiftedFormula = shiftFormula(row, formula, formulaShifter);
if (shiftedFormula != null) {
f.setStringValue(shiftedFormula);
if(f.getT() == STCellFormulaType.SHARED){
int si = (int)f.getSi();
CTCellFormula sf = sheet.getSharedFormula(si);
sf.setStringValue(shiftedFormula);
updateRefInCTCellFormula(row, formulaShifter, sf);
}
}
}
//Range of cells which the formula applies to.
updateRefInCTCellFormula(row, formulaShifter, f);
}
}
}
/**
* Shift a formula using the supplied FormulaShifter
*
* @param row the row of the cell this formula belongs to. Used to get a reference to the parent workbook.
* @param formula the formula to shift
* @param formulaShifter the FormulaShifter object that operates on the parsed formula tokens
* @return the shifted formula if the formula was changed,
* <code>null</code> if the formula wasn't modified
*/
/*package*/
static String shiftFormula(Row row, String formula, FormulaShifter formulaShifter) {
Sheet sheet = row.getSheet();
Workbook wb = sheet.getWorkbook();
int sheetIndex = wb.getSheetIndex(sheet);
final int rowIndex = row.getRowNum();
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create((XSSFWorkbook) wb);
try {
Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex, rowIndex);
String shiftedFmla = null;
if (formulaShifter.adjustFormula(ptgs, sheetIndex)) {
shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
}
return shiftedFmla;
} catch (FormulaParseException fpe) {
// Log, but don't change, rather than breaking
logger.log(POILogger.WARN, "Error shifting formula on row ", row.getRowNum(), fpe);
return formula;
}
}
/*package*/
static void updateRefInCTCellFormula(Row row, FormulaShifter formulaShifter, CTCellFormula f) {
if (f.isSetRef()) { //Range of cells which the formula applies to.
String ref = f.getRef();
String shiftedRef = shiftFormula(row, ref, formulaShifter);
if (shiftedRef != null) f.setRef(shiftedRef);
}
}
/*package*/ static void updateConditionalFormatting(Sheet sheet, FormulaShifter formulaShifter) {
XSSFSheet xsheet = (XSSFSheet) sheet;
XSSFWorkbook wb = xsheet.getWorkbook();

View File

@ -17,36 +17,13 @@
package org.apache.poi.xssf.usermodel.helpers;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.ss.formula.FormulaParseException;
import org.apache.poi.ss.formula.FormulaParser;
import org.apache.poi.ss.formula.FormulaRenderer;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.helpers.RowShifter;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFEvaluationWorkbook;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
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 org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
/**
* Helper for shifting rows up or down
@ -60,129 +37,28 @@ public final class XSSFRowShifter extends RowShifter {
super(sh);
}
/**
* Updated named ranges
*/
@Override
public void updateNamedRanges(FormulaShifter formulaShifter) {
XSSFRowColShifter.updateNamedRanges(sheet, formulaShifter);
}
/**
* Update formulas.
*/
@Override
public void updateFormulas(FormulaShifter formulaShifter) {
//update formulas on the parent sheet
updateSheetFormulas(sheet, formulaShifter);
//update formulas on other sheets
Workbook wb = sheet.getWorkbook();
for (Sheet sh : wb) {
if (sheet == sh) continue;
updateSheetFormulas(sh, formulaShifter);
}
XSSFRowColShifter.updateFormulas(sheet, formulaShifter);
}
private void updateSheetFormulas(Sheet sh, FormulaShifter formulashifter) {
for (Row r : sh) {
XSSFRow row = (XSSFRow) r;
updateRowFormulas(row, formulashifter);
}
}
/**
* Update the formulas in specified row using the formula shifting policy specified by shifter
*
* @param row the row to update the formulas on
* @param formulaShifter the formula shifting policy
*/
@Internal
@Override
public void updateRowFormulas(Row row, FormulaShifter formulaShifter) {
XSSFSheet sheet = (XSSFSheet) row.getSheet();
for (Cell c : row) {
XSSFCell cell = (XSSFCell) c;
CTCell ctCell = cell.getCTCell();
if (ctCell.isSetF()) {
CTCellFormula f = ctCell.getF();
String formula = f.getStringValue();
if (formula.length() > 0) {
String shiftedFormula = shiftFormula(row, formula, formulaShifter);
if (shiftedFormula != null) {
f.setStringValue(shiftedFormula);
if(f.getT() == STCellFormulaType.SHARED){
int si = (int)f.getSi();
CTCellFormula sf = sheet.getSharedFormula(si);
sf.setStringValue(shiftedFormula);
updateRefInCTCellFormula(row, formulaShifter, sf);
}
}
}
//Range of cells which the formula applies to.
updateRefInCTCellFormula(row, formulaShifter, f);
}
}
}
private void updateRefInCTCellFormula(Row row, FormulaShifter formulaShifter, CTCellFormula f) {
if (f.isSetRef()) { //Range of cells which the formula applies to.
String ref = f.getRef();
String shiftedRef = shiftFormula(row, ref, formulaShifter);
if (shiftedRef != null) f.setRef(shiftedRef);
}
}
/**
* Shift a formula using the supplied FormulaShifter
*
* @param row the row of the cell this formula belongs to. Used to get a reference to the parent workbook.
* @param formula the formula to shift
* @param formulaShifter the FormulaShifter object that operates on the parsed formula tokens
* @return the shifted formula if the formula was changed,
* <code>null</code> if the formula wasn't modified
*/
private static String shiftFormula(Row row, String formula, FormulaShifter formulaShifter) {
Sheet sheet = row.getSheet();
Workbook wb = sheet.getWorkbook();
int sheetIndex = wb.getSheetIndex(sheet);
final int rowIndex = row.getRowNum();
XSSFEvaluationWorkbook fpb = XSSFEvaluationWorkbook.create((XSSFWorkbook) wb);
try {
Ptg[] ptgs = FormulaParser.parse(formula, fpb, FormulaType.CELL, sheetIndex, rowIndex);
String shiftedFmla = null;
if (formulaShifter.adjustFormula(ptgs, sheetIndex)) {
shiftedFmla = FormulaRenderer.toFormulaString(fpb, ptgs);
}
return shiftedFmla;
} catch (FormulaParseException fpe) {
// Log, but don't change, rather than breaking
logger.log(POILogger.WARN, "Error shifting formula on row ", row.getRowNum(), fpe);
return formula;
}
@Internal(since="3.15 beta 2")
public void updateRowFormulas(XSSFRow row, FormulaShifter formulaShifter) {
XSSFRowColShifter.updateRowFormulas(row, formulaShifter);
}
@Override
public void updateConditionalFormatting(FormulaShifter formulaShifter) {
XSSFRowColShifter.updateConditionalFormatting(sheet, formulaShifter);
}
/**
* Shift the Hyperlink anchors (not the hyperlink text, even if the hyperlink
* is of type LINK_DOCUMENT and refers to a cell that was shifted). Hyperlinks
* do not track the content they point to.
*
* @param formulaShifter
*/
@Override
public void updateHyperlinks(FormulaShifter formulaShifter) {
XSSFRowColShifter.updateHyperlinks(sheet, formulaShifter);
}
}