Generalised API for adding ignored errors, e.g. number stored as text.

https://bz.apache.org/bugzilla/show_bug.cgi?id=56892

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1724469 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
David North 2016-01-13 17:54:24 +00:00
parent 8793846bc6
commit a08539ef02
3 changed files with 248 additions and 41 deletions

View File

@ -0,0 +1,106 @@
/* ====================================================================
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================== */
package org.apache.poi.xssf.usermodel;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIgnoredError;
/**
* Types of ignored error.
*/
public enum IgnoredErrorType {
CALCULATED_COLUMN,
EMPTY_CELL_REFERENCE,
EVALUATION_ERROR,
FORMULA,
FORMULA_RANGE,
LIST_DATA_VALIDATION,
NUMBER_STORED_AS_TEXT,
TWO_DIGIT_TEXT_YEAR,
UNLOCKED_FORMULA;
// Methods below are not part of the public API
boolean isSet(CTIgnoredError error) {
switch(this) {
case CALCULATED_COLUMN:
return error.isSetCalculatedColumn();
case EMPTY_CELL_REFERENCE:
return error.isSetEmptyCellReference();
case EVALUATION_ERROR:
return error.isSetEvalError();
case FORMULA:
return error.isSetFormula();
case FORMULA_RANGE:
return error.isSetFormulaRange();
case LIST_DATA_VALIDATION:
return error.isSetListDataValidation();
case NUMBER_STORED_AS_TEXT:
return error.isSetNumberStoredAsText();
case TWO_DIGIT_TEXT_YEAR:
return error.isSetTwoDigitTextYear();
case UNLOCKED_FORMULA:
return error.isSetUnlockedFormula();
default:
throw new IllegalStateException();
}
}
void set(CTIgnoredError error) {
switch(this) {
case CALCULATED_COLUMN:
error.setCalculatedColumn(true);
break;
case EMPTY_CELL_REFERENCE:
error.setEmptyCellReference(true);
break;
case EVALUATION_ERROR:
error.setEvalError(true);
break;
case FORMULA:
error.setFormula(true);
break;
case FORMULA_RANGE:
error.setFormulaRange(true);
break;
case LIST_DATA_VALIDATION:
error.setListDataValidation(true);
break;
case NUMBER_STORED_AS_TEXT:
error.setNumberStoredAsText(true);
break;
case TWO_DIGIT_TEXT_YEAR:
error.setTwoDigitTextYear(true);
break;
case UNLOCKED_FORMULA:
error.setUnlockedFormula(true);
break;
default:
throw new IllegalStateException();
}
}
}

View File

@ -31,8 +31,11 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
@ -78,47 +81,7 @@ import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
import org.apache.poi.xssf.usermodel.helpers.XSSFRowShifter;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAutoFilter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBreak;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidation;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidations;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTLegacyDrawing;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOutlinePr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageBreak;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetUpPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPane;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPrintOptions;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSelection;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetCalcPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetView;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTablePart;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableParts;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPaneState;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
/**
* High level representation of a SpreadsheetML worksheet.
@ -4051,4 +4014,69 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
}
return col.getOutlineLevel();
}
/**
* Add ignored errors (usually to suppress them in the UI of a consuming
* application).
*
* @param cell Cell.
* @param ignoredErrorTypes Types of error to ignore there.
*/
public void addIgnoredErrors(CellReference cell, IgnoredErrorType... ignoredErrorTypes) {
addIgnoredErrors(cell.formatAsString(), ignoredErrorTypes);
}
/**
* Ignore errors across a range of cells.
*
* @param region Range of cells.
* @param ignoredErrorTypes Types of error to ignore there.
*/
public void addIgnoredErrors(CellRangeAddress region, IgnoredErrorType... ignoredErrorTypes) {
region.validate(SpreadsheetVersion.EXCEL2007);
addIgnoredErrors(region.formatAsString(), ignoredErrorTypes);
}
/**
* Returns the errors currently being ignored and the ranges
* where they are ignored.
*
* @return Map of error type to the range(s) where they are ignored.
*/
public Map<IgnoredErrorType, Set<CellRangeAddress>> getIgnoredErrors() {
Map<IgnoredErrorType, Set<CellRangeAddress>> result = new LinkedHashMap<IgnoredErrorType, Set<CellRangeAddress>>();
if (worksheet.isSetIgnoredErrors()) {
for (CTIgnoredError err : worksheet.getIgnoredErrors().getIgnoredErrorList()) {
for (IgnoredErrorType errType : getErrorTypes(err)) {
if (!result.containsKey(errType)) {
result.put(errType, new LinkedHashSet<CellRangeAddress>());
}
for (Object ref : err.getSqref()) {
result.get(errType).add(CellRangeAddress.valueOf(ref.toString()));
}
}
}
}
return result;
}
private void addIgnoredErrors(String ref, IgnoredErrorType... ignoredErrorTypes) {
CTIgnoredErrors ctIgnoredErrors = worksheet.isSetIgnoredErrors() ? worksheet.getIgnoredErrors() : worksheet.addNewIgnoredErrors();
CTIgnoredError ctIgnoredError = ctIgnoredErrors.addNewIgnoredError();
ctIgnoredError.setSqref(Arrays.asList(ref));
for (IgnoredErrorType errType : ignoredErrorTypes) {
errType.set(ctIgnoredError);
}
}
private Set<IgnoredErrorType> getErrorTypes(CTIgnoredError err) {
Set<IgnoredErrorType> result = new LinkedHashSet<IgnoredErrorType>();
for (IgnoredErrorType errType : IgnoredErrorType.values()) {
if (errType.isSet(err)) {
result.add(errType);
}
}
return result;
}
}

View File

@ -33,6 +33,7 @@ import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.poi.POIXMLException;
@ -68,6 +69,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIgnoredError;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection;
@ -1828,4 +1830,75 @@ public final class TestXSSFSheet extends BaseTestSheet {
public void testCopyMultipleRows() throws IOException {
testCopyMultipleRows("XSSFSheet.copyRows.xlsx");
}
@Test
public void testIgnoredErrors() throws IOException {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet();
CellRangeAddress region = CellRangeAddress.valueOf("B2:D4");
sheet.addIgnoredErrors(region, IgnoredErrorType.NUMBER_STORED_AS_TEXT);
final CTIgnoredError ignoredError = sheet.getCTWorksheet().getIgnoredErrors().getIgnoredErrorArray(0);
assertEquals(1, ignoredError.getSqref().size());
assertEquals("B2:D4", ignoredError.getSqref().get(0));
assertTrue(ignoredError.getNumberStoredAsText());
Map<IgnoredErrorType, Set<CellRangeAddress>> ignoredErrors = sheet.getIgnoredErrors();
assertEquals(1, ignoredErrors.size());
assertEquals(1, ignoredErrors.get(IgnoredErrorType.NUMBER_STORED_AS_TEXT).size());
assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.NUMBER_STORED_AS_TEXT).iterator().next().formatAsString());
workbook.close();
}
@Test
public void testIgnoredErrorsMultipleTypes() throws IOException {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet();
CellRangeAddress region = CellRangeAddress.valueOf("B2:D4");
sheet.addIgnoredErrors(region, IgnoredErrorType.FORMULA, IgnoredErrorType.EVALUATION_ERROR);
final CTIgnoredError ignoredError = sheet.getCTWorksheet().getIgnoredErrors().getIgnoredErrorArray(0);
assertEquals(1, ignoredError.getSqref().size());
assertEquals("B2:D4", ignoredError.getSqref().get(0));
assertFalse(ignoredError.getNumberStoredAsText());
assertTrue(ignoredError.getFormula());
assertTrue(ignoredError.getEvalError());
Map<IgnoredErrorType, Set<CellRangeAddress>> ignoredErrors = sheet.getIgnoredErrors();
assertEquals(2, ignoredErrors.size());
assertEquals(1, ignoredErrors.get(IgnoredErrorType.FORMULA).size());
assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.FORMULA).iterator().next().formatAsString());
assertEquals(1, ignoredErrors.get(IgnoredErrorType.EVALUATION_ERROR).size());
assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.EVALUATION_ERROR).iterator().next().formatAsString());
workbook.close();
}
@Test
public void testIgnoredErrorsMultipleCalls() throws IOException {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet();
CellRangeAddress region = CellRangeAddress.valueOf("B2:D4");
// Two calls means two elements, no clever collapsing just yet.
sheet.addIgnoredErrors(region, IgnoredErrorType.EVALUATION_ERROR);
sheet.addIgnoredErrors(region, IgnoredErrorType.FORMULA);
CTIgnoredError ignoredError = sheet.getCTWorksheet().getIgnoredErrors().getIgnoredErrorArray(0);
assertEquals(1, ignoredError.getSqref().size());
assertEquals("B2:D4", ignoredError.getSqref().get(0));
assertFalse(ignoredError.getFormula());
assertTrue(ignoredError.getEvalError());
ignoredError = sheet.getCTWorksheet().getIgnoredErrors().getIgnoredErrorArray(1);
assertEquals(1, ignoredError.getSqref().size());
assertEquals("B2:D4", ignoredError.getSqref().get(0));
assertTrue(ignoredError.getFormula());
assertFalse(ignoredError.getEvalError());
Map<IgnoredErrorType, Set<CellRangeAddress>> ignoredErrors = sheet.getIgnoredErrors();
assertEquals(2, ignoredErrors.size());
assertEquals(1, ignoredErrors.get(IgnoredErrorType.FORMULA).size());
assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.FORMULA).iterator().next().formatAsString());
assertEquals(1, ignoredErrors.get(IgnoredErrorType.EVALUATION_ERROR).size());
assertEquals("B2:D4", ignoredErrors.get(IgnoredErrorType.EVALUATION_ERROR).iterator().next().formatAsString());
workbook.close();
}
}