]> source.dussan.org Git - poi.git/commitdiff
Generalised API for adding ignored errors, e.g. number stored as text.
authorDavid North <dnorth@apache.org>
Wed, 13 Jan 2016 17:54:24 +0000 (17:54 +0000)
committerDavid North <dnorth@apache.org>
Wed, 13 Jan 2016 17:54:24 +0000 (17:54 +0000)
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

src/ooxml/java/org/apache/poi/xssf/usermodel/IgnoredErrorType.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java

diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/IgnoredErrorType.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/IgnoredErrorType.java
new file mode 100644 (file)
index 0000000..335d578
--- /dev/null
@@ -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();
+        }
+    }
+    
+}
index fa8d85b261c4c006c3caa04a7a922d75dc3af1a1..c0ea0681a7c1f579b7a752dfa4a20ddb097c78c7 100644 (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;
+    }
+    
 }
index 3f67825bb7340a46ab51f621f2fd75d7ea2c2b9a..2066d2d4a9fd961b93642317b967dfc0ce74edc9 100644 (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();
+    }
 }
\ No newline at end of file