View | Details | Raw Unified | Return to bug 58070
Collapse All | Expand All

(-)src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java (-79 / +104 lines)
Lines 17-41 Link Here
17
17
18
package org.apache.poi.xssf.usermodel;
18
package org.apache.poi.xssf.usermodel;
19
19
20
import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.setPassword;
21
import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.validatePassword;
22
23
import java.io.IOException;
24
import java.io.InputStream;
25
import java.io.OutputStream;
26
import java.util.ArrayList;
27
import java.util.Arrays;
28
import java.util.Comparator;
29
import java.util.HashMap;
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.Map;
33
import java.util.Set;
34
import java.util.SortedMap;
35
import java.util.TreeMap;
36
37
import javax.xml.namespace.QName;
38
39
import org.apache.poi.POIXMLDocumentPart;
20
import org.apache.poi.POIXMLDocumentPart;
40
import org.apache.poi.POIXMLException;
21
import org.apache.poi.POIXMLException;
41
import org.apache.poi.hssf.util.PaneInformation;
22
import org.apache.poi.hssf.util.PaneInformation;
Lines 49-70 Link Here
49
import org.apache.poi.ss.SpreadsheetVersion;
30
import org.apache.poi.ss.SpreadsheetVersion;
50
import org.apache.poi.ss.formula.FormulaShifter;
31
import org.apache.poi.ss.formula.FormulaShifter;
51
import org.apache.poi.ss.formula.SheetNameFormatter;
32
import org.apache.poi.ss.formula.SheetNameFormatter;
52
import org.apache.poi.ss.usermodel.Cell;
33
import org.apache.poi.ss.usermodel.*;
53
import org.apache.poi.ss.usermodel.CellRange;
34
import org.apache.poi.ss.util.*;
54
import org.apache.poi.ss.usermodel.CellStyle;
55
import org.apache.poi.ss.usermodel.DataValidation;
56
import org.apache.poi.ss.usermodel.DataValidationHelper;
57
import org.apache.poi.ss.usermodel.Footer;
58
import org.apache.poi.ss.usermodel.Header;
59
import org.apache.poi.ss.usermodel.IndexedColors;
60
import org.apache.poi.ss.usermodel.Row;
61
import org.apache.poi.ss.usermodel.Sheet;
62
import org.apache.poi.ss.util.AreaReference;
63
import org.apache.poi.ss.util.CellRangeAddress;
64
import org.apache.poi.ss.util.CellRangeAddressList;
65
import org.apache.poi.ss.util.CellReference;
66
import org.apache.poi.ss.util.SSCellRange;
67
import org.apache.poi.ss.util.SheetUtil;
68
import org.apache.poi.util.Beta;
35
import org.apache.poi.util.Beta;
69
import org.apache.poi.util.Internal;
36
import org.apache.poi.util.Internal;
70
import org.apache.poi.util.POILogFactory;
37
import org.apache.poi.util.POILogFactory;
Lines 75-122 Link Here
75
import org.apache.xmlbeans.XmlException;
42
import org.apache.xmlbeans.XmlException;
76
import org.apache.xmlbeans.XmlOptions;
43
import org.apache.xmlbeans.XmlOptions;
77
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
44
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
78
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAutoFilter;
45
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
79
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBreak;
80
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCalcPr;
81
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
82
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula;
83
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
84
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;
85
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
86
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment;
87
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList;
88
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidation;
89
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidations;
90
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing;
91
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter;
92
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink;
93
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTLegacyDrawing;
94
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell;
95
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells;
96
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOutlinePr;
97
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageBreak;
98
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins;
99
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetUpPr;
100
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPane;
101
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPrintOptions;
102
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
103
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSelection;
104
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet;
105
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetCalcPr;
106
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr;
107
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetPr;
108
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection;
109
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetView;
110
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews;
111
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTablePart;
112
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableParts;
113
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
114
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCalcMode;
115
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType;
116
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane;
117
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPaneState;
118
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument;
119
46
47
import javax.xml.namespace.QName;
48
import java.io.IOException;
49
import java.io.InputStream;
50
import java.io.OutputStream;
51
import java.util.*;
52
53
import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.setPassword;
54
import static org.apache.poi.xssf.usermodel.helpers.XSSFPaswordHelper.validatePassword;
55
120
/**
56
/**
121
 * High level representation of a SpreadsheetML worksheet.
57
 * High level representation of a SpreadsheetML worksheet.
122
 *
58
 *
Lines 334-342 Link Here
334
        // a multi-cell array formula defined in this sheet
270
        // a multi-cell array formula defined in this sheet
335
        validateArrayFormulas(region);
271
        validateArrayFormulas(region);
336
272
337
        CTMergeCells ctMergeCells = worksheet.isSetMergeCells() ? worksheet.getMergeCells() : worksheet.addNewMergeCells();
273
        CTMergeCells ctMergeCells;
338
        CTMergeCell ctMergeCell = ctMergeCells.addNewMergeCell();
274
        if (worksheet.isSetMergeCells() == false) {
339
        ctMergeCell.setRef(region.formatAsString());
275
            ctMergeCells = worksheet.addNewMergeCells();
276
            CTMergeCell ctMergeCell = ctMergeCells.addNewMergeCell();
277
            ctMergeCell.setRef(region.formatAsString());
278
        }
279
        else {
280
            ctMergeCells = worksheet.getMergeCells();
281
            addMergedRegionToExistingRegions(ctMergeCells, region);
282
        }
283
340
        return ctMergeCells.sizeOfMergeCellArray();
284
        return ctMergeCells.sizeOfMergeCellArray();
341
    }
285
    }
342
286
Lines 368-374 Link Here
368
312
369
    }
313
    }
370
314
315
    private boolean doesTopLeftCellOverlap(CellRangeAddress src, CellRangeAddress target) {
316
317
        return     src.getFirstColumn() >= target.getFirstColumn()
318
                && src.getFirstColumn() <= target.getLastColumn()
319
                && src.getFirstRow() >= target.getFirstRow()
320
                && src.getFirstRow() <= target.getLastRow();
321
    }
322
323
    private boolean doesTopRightCellOverlap(CellRangeAddress src, CellRangeAddress target) {
324
325
        return     src.getLastColumn() >= target.getFirstColumn()
326
                && src.getLastColumn() <= target.getLastColumn()
327
                && src.getFirstRow() >= target.getFirstColumn()
328
                && src.getFirstRow() <= target.getLastRow();
329
    }
330
331
    private boolean doesBottomLeftCellOverlap(CellRangeAddress src, CellRangeAddress target) {
332
333
        return     src.getFirstColumn() >= target.getFirstColumn()
334
                && src.getFirstColumn() <= target.getLastColumn()
335
                && src.getLastRow() >= target.getFirstRow()
336
                && src.getLastRow() <= target.getLastRow();
337
    }
338
339
    private boolean doesBottomRightCellOverlap(CellRangeAddress src, CellRangeAddress target) {
340
341
        return     src.getLastColumn() >= target.getFirstColumn()
342
                && src.getLastColumn() <= target.getLastColumn()
343
                && src.getLastRow() >= target.getFirstColumn()
344
                && src.getLastRow() <= target.getLastRow();
345
    }
346
347
    private boolean doCellRangeAddressesOverlap(CellRangeAddress address1, CellRangeAddress address2) {
348
349
        return     doesTopLeftCellOverlap(address1, address2)
350
                || doesTopRightCellOverlap(address1, address2)
351
                || doesBottomLeftCellOverlap(address1, address2)
352
                || doesBottomRightCellOverlap(address1, address2);
353
    }
354
355
    private CellRangeAddress mergeCellRangeAddresses(CellRangeAddress range1, CellRangeAddress range2) {
356
357
        int mergedFirstRow =
358
                range1.getFirstRow() < range2.getFirstRow() ? range1.getFirstRow() : range2.getFirstRow();
359
        int mergedLastRow =
360
                range1.getLastRow() > range2.getLastRow() ? range1.getLastRow() : range2.getLastRow();
361
        int mergedFirstColumn =
362
                range1.getFirstColumn() < range2.getFirstColumn() ? range1.getFirstColumn() : range2.getFirstColumn();
363
        int mergedLastColumn =
364
                range1.getLastColumn() > range2.getLastColumn() ? range1.getLastColumn() : range2.getLastColumn();
365
366
        return new CellRangeAddress(mergedFirstRow, mergedLastRow, mergedFirstColumn, mergedLastColumn);
367
    }
368
371
    /**
369
    /**
370
     * Add the new merged region to the existing ones, keeping into account that it may overlap
371
     * with one or more of them. In that case, overlapping regions will be merged.
372
     *
373
     * @param ctMergeCells
374
     * @param region
375
     */
376
    private void addMergedRegionToExistingRegions(CTMergeCells ctMergeCells, CellRangeAddress region) {
377
378
        List<CTMergeCell> ctMergeCellsToRemove = new ArrayList<CTMergeCell>();
379
        CellRangeAddress existing;
380
        for (CTMergeCell ctMergeCell : ctMergeCells.getMergeCellList()) {
381
            existing = CellRangeAddress.valueOf(ctMergeCell.getRef());
382
            if (doCellRangeAddressesOverlap(region, existing)) {
383
                region = mergeCellRangeAddresses(region, existing);
384
                ctMergeCellsToRemove.add(ctMergeCell);
385
            }
386
        }
387
388
        // Remove the ones that were merged with the new one
389
        ctMergeCells.getMergeCellList().removeAll(ctMergeCellsToRemove);
390
391
        // Add the new one
392
        CTMergeCell ctMergeCell = ctMergeCells.addNewMergeCell();
393
        ctMergeCell.setRef(region.formatAsString());
394
    }
395
396
    /**
372
     * Adjusts the column width to fit the contents.
397
     * Adjusts the column width to fit the contents.
373
     *
398
     *
374
     * This process can be relatively slow on large sheets, so this should
399
     * This process can be relatively slow on large sheets, so this should

Return to bug 58070