Lines 18-28
Link Here
|
18 |
package org.apache.poi.xssf.usermodel; |
18 |
package org.apache.poi.xssf.usermodel; |
19 |
|
19 |
|
20 |
import java.io.IOException; |
20 |
import java.io.IOException; |
|
|
21 |
import java.io.InputStream; |
21 |
import java.io.OutputStream; |
22 |
import java.io.OutputStream; |
22 |
import java.io.InputStream; |
23 |
import java.util.ArrayList; |
23 |
import java.util.*; |
24 |
import java.util.Arrays; |
|
|
25 |
import java.util.HashMap; |
26 |
import java.util.Iterator; |
27 |
import java.util.List; |
28 |
import java.util.Map; |
29 |
import java.util.TreeMap; |
30 |
|
24 |
import javax.xml.namespace.QName; |
31 |
import javax.xml.namespace.QName; |
25 |
|
32 |
|
|
|
33 |
import org.apache.poi.POIXMLDocumentPart; |
34 |
import org.apache.poi.POIXMLException; |
26 |
import org.apache.poi.hssf.util.PaneInformation; |
35 |
import org.apache.poi.hssf.util.PaneInformation; |
27 |
import org.apache.poi.ss.usermodel.CellStyle; |
36 |
import org.apache.poi.ss.usermodel.CellStyle; |
28 |
import org.apache.poi.ss.usermodel.Footer; |
37 |
import org.apache.poi.ss.usermodel.Footer; |
Lines 31-50
Link Here
|
31 |
import org.apache.poi.ss.usermodel.Sheet; |
40 |
import org.apache.poi.ss.usermodel.Sheet; |
32 |
import org.apache.poi.ss.util.CellRangeAddress; |
41 |
import org.apache.poi.ss.util.CellRangeAddress; |
33 |
import org.apache.poi.ss.util.CellReference; |
42 |
import org.apache.poi.ss.util.CellReference; |
|
|
43 |
import org.apache.poi.util.POILogFactory; |
44 |
import org.apache.poi.util.POILogger; |
34 |
import org.apache.poi.xssf.model.CommentsTable; |
45 |
import org.apache.poi.xssf.model.CommentsTable; |
35 |
import org.apache.poi.xssf.usermodel.helpers.ColumnHelper; |
46 |
import org.apache.poi.xssf.usermodel.helpers.ColumnHelper; |
36 |
import org.apache.poi.POIXMLDocumentPart; |
47 |
import org.apache.xmlbeans.XmlException; |
37 |
import org.apache.poi.POIXMLException; |
|
|
38 |
import org.apache.poi.util.POILogger; |
39 |
import org.apache.poi.util.POILogFactory; |
40 |
import org.apache.xmlbeans.XmlOptions; |
48 |
import org.apache.xmlbeans.XmlOptions; |
41 |
import org.apache.xmlbeans.XmlException; |
49 |
import org.openxml4j.exceptions.InvalidFormatException; |
42 |
import org.openxml4j.opc.PackagePart; |
50 |
import org.openxml4j.opc.PackagePart; |
43 |
import org.openxml4j.opc.PackageRelationship; |
51 |
import org.openxml4j.opc.PackageRelationship; |
44 |
import org.openxml4j.opc.PackageRelationshipCollection; |
52 |
import org.openxml4j.opc.PackageRelationshipCollection; |
45 |
import org.openxml4j.exceptions.InvalidFormatException; |
|
|
46 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; |
47 |
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; |
53 |
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; |
|
|
54 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBreak; |
55 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; |
56 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; |
57 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing; |
58 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; |
59 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink; |
60 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell; |
61 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells; |
62 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOutlinePr; |
63 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageBreak; |
64 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins; |
65 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetUpPr; |
66 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPane; |
67 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPrintOptions; |
68 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; |
69 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSelection; |
70 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet; |
71 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData; |
72 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr; |
73 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetPr; |
74 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetView; |
75 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews; |
76 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; |
77 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane; |
78 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPaneState; |
79 |
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument; |
48 |
|
80 |
|
49 |
|
81 |
|
50 |
/** |
82 |
/** |
Lines 320-325
Link Here
|
320 |
* Creates a split (freezepane). Any existing freezepane or split pane is overwritten. |
352 |
* Creates a split (freezepane). Any existing freezepane or split pane is overwritten. |
321 |
* @param colSplit Horizonatal position of split. |
353 |
* @param colSplit Horizonatal position of split. |
322 |
* @param rowSplit Vertical position of split. |
354 |
* @param rowSplit Vertical position of split. |
|
|
355 |
*/ |
356 |
public void createFreezePane(int colSplit, int rowSplit) { |
357 |
createFreezePane( colSplit, rowSplit, colSplit, rowSplit ); |
358 |
} |
359 |
|
360 |
|
361 |
/** |
362 |
* Creates a split (freezepane). Any existing freezepane or split pane is overwritten. |
363 |
* @param colSplit Horizonatal position of split. |
364 |
* @param rowSplit Vertical position of split. |
323 |
* @param topRow Top row visible in bottom pane |
365 |
* @param topRow Top row visible in bottom pane |
324 |
* @param leftmostColumn Left column visible in right pane. |
366 |
* @param leftmostColumn Left column visible in right pane. |
325 |
*/ |
367 |
*/ |
Lines 344-358
Link Here
|
344 |
CTSelection sel = ctView.addNewSelection(); |
386 |
CTSelection sel = ctView.addNewSelection(); |
345 |
sel.setPane(pane.getActivePane()); |
387 |
sel.setPane(pane.getActivePane()); |
346 |
} |
388 |
} |
|
|
389 |
|
347 |
|
390 |
|
348 |
/** |
|
|
349 |
* Creates a split (freezepane). Any existing freezepane or split pane is overwritten. |
350 |
* @param colSplit Horizonatal position of split. |
351 |
* @param rowSplit Vertical position of split. |
352 |
*/ |
353 |
public void createFreezePane(int colSplit, int rowSplit) { |
354 |
createFreezePane( colSplit, rowSplit, colSplit, rowSplit ); |
355 |
} |
356 |
|
391 |
|
357 |
/** |
392 |
/** |
358 |
* Creates a new comment for this sheet. You still |
393 |
* Creates a new comment for this sheet. You still |
Lines 388-407
Link Here
|
388 |
* @param leftmostColumn Left column visible in right pane. |
423 |
* @param leftmostColumn Left column visible in right pane. |
389 |
* @param activePane Active pane. One of: PANE_LOWER_RIGHT, |
424 |
* @param activePane Active pane. One of: PANE_LOWER_RIGHT, |
390 |
* PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT |
425 |
* PANE_UPPER_RIGHT, PANE_LOWER_LEFT, PANE_UPPER_LEFT |
391 |
* @see #PANE_LOWER_LEFT |
426 |
* @see org.apache.poi.ss.usermodel.Sheet#PANE_LOWER_LEFT |
392 |
* @see #PANE_LOWER_RIGHT |
427 |
* @see org.apache.poi.ss.usermodel.Sheet#PANE_LOWER_RIGHT |
393 |
* @see #PANE_UPPER_LEFT |
428 |
* @see org.apache.poi.ss.usermodel.Sheet#PANE_UPPER_LEFT |
394 |
* @see #PANE_UPPER_RIGHT |
429 |
* @see org.apache.poi.ss.usermodel.Sheet#PANE_UPPER_RIGHT |
395 |
*/ |
430 |
*/ |
396 |
public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) { |
431 |
public void createSplitPane(int xSplitPos, int ySplitPos, int leftmostColumn, int topRow, int activePane) { |
397 |
createFreezePane(xSplitPos, ySplitPos, leftmostColumn, topRow); |
432 |
createFreezePane(xSplitPos, ySplitPos, leftmostColumn, topRow); |
398 |
getPane().setActivePane(STPane.Enum.forInt(activePane)); |
433 |
getPane().setState(STPaneState.SPLIT); |
399 |
} |
434 |
getPane().setActivePane(STPane.Enum.forInt(activePane)); |
400 |
|
435 |
} |
|
|
436 |
|
401 |
public XSSFComment getCellComment(int row, int column) { |
437 |
public XSSFComment getCellComment(int row, int column) { |
402 |
if (sheetComments == null) return null; |
438 |
if (sheetComments == null) return null; |
403 |
else return sheetComments.findCellComment(row, column); |
439 |
else return sheetComments.findCellComment(row, column); |
404 |
} |
440 |
} |
|
|
441 |
|
405 |
|
442 |
|
406 |
public XSSFHyperlink getHyperlink(int row, int column) { |
443 |
public XSSFHyperlink getHyperlink(int row, int column) { |
407 |
String ref = new CellReference(row, column).formatAsString(); |
444 |
String ref = new CellReference(row, column).formatAsString(); |
Lines 1226-1241
Link Here
|
1226 |
} |
1263 |
} |
1227 |
|
1264 |
|
1228 |
public void setColumnGroupCollapsed(short columnNumber, boolean collapsed) { |
1265 |
public void setColumnGroupCollapsed(short columnNumber, boolean collapsed) { |
1229 |
// TODO Auto-generated method stub |
1266 |
if (collapsed) { |
|
|
1267 |
collapseColumn(columnNumber); |
1268 |
} else { |
1269 |
expandColumn(columnNumber); |
1270 |
} |
1271 |
} |
1230 |
|
1272 |
|
|
|
1273 |
private void collapseColumn(short columnNumber){ |
1274 |
CTCols cols=worksheet.getColsArray(0); |
1275 |
CTCol col=columnHelper.getColumn(columnNumber, false); |
1276 |
int colInfoIx = columnHelper.getIndexOfColumn(cols, col); |
1277 |
if (colInfoIx == -1) { |
1278 |
return; |
1279 |
} |
1280 |
// Find the start of the group. |
1281 |
int groupStartColInfoIx = findStartOfColumnOutlineGroup(colInfoIx); |
1282 |
|
1283 |
CTCol columnInfo = cols.getColArray(groupStartColInfoIx); |
1284 |
|
1285 |
// Hide all the columns until the end of the group |
1286 |
int lastColMax = setGroupHidden(groupStartColInfoIx, columnInfo.getOutlineLevel(), true); |
1287 |
|
1288 |
//write collapse field |
1289 |
setColumn((int)(lastColMax + 1), null,0, null, null, Boolean.TRUE); |
1290 |
|
1231 |
} |
1291 |
} |
1232 |
|
1292 |
|
1233 |
public void setRowGroupCollapsed(int row, boolean collapse) { |
|
|
1234 |
// TODO Auto-generated method stub |
1235 |
|
1293 |
|
|
|
1294 |
private void setColumn(int targetColumnIx, Short xfIndex, Integer style,Integer level, Boolean hidden, Boolean collapsed) { |
1295 |
CTCols cols=worksheet.getColsArray(0); |
1296 |
CTCol ci = null; |
1297 |
int k = 0; |
1298 |
for (k = 0; k < cols.sizeOfColArray(); k++) { |
1299 |
CTCol tci = cols.getColArray(k); |
1300 |
if (tci.getMin()>=targetColumnIx && tci.getMax()<=targetColumnIx) { |
1301 |
ci = tci; |
1302 |
break; |
1303 |
} |
1304 |
if (tci.getMin() > targetColumnIx) { |
1305 |
// call column infos after k are for later columns |
1306 |
break; // exit now so k will be the correct insert pos |
1307 |
} |
1308 |
} |
1309 |
|
1310 |
if (ci == null) { |
1311 |
// okay so there ISN'T a column info record that covers this column so lets create one! |
1312 |
CTCol nci = CTCol.Factory.newInstance(); |
1313 |
nci.setMin(targetColumnIx); |
1314 |
nci.setMax(targetColumnIx); |
1315 |
unsetCollapsed(collapsed,nci); |
1316 |
this.columnHelper.addCleanColIntoCols(cols, nci); |
1317 |
return; |
1318 |
} |
1319 |
|
1320 |
boolean styleChanged = style != null && ci.getStyle() != style.intValue(); |
1321 |
boolean levelChanged = level != null && ci.getOutlineLevel() != level.intValue(); |
1322 |
boolean hiddenChanged = hidden != null && ci.getHidden() != hidden.booleanValue(); |
1323 |
boolean collapsedChanged = collapsed != null && ci.getCollapsed() != collapsed.booleanValue(); |
1324 |
boolean columnChanged = levelChanged || hiddenChanged || collapsedChanged || styleChanged; |
1325 |
if (!columnChanged) { |
1326 |
// do nothing...nothing changed. |
1327 |
return; |
1328 |
} |
1329 |
|
1330 |
if (ci.getMin() == targetColumnIx && ci.getMax() == targetColumnIx) { |
1331 |
// ColumnInfo ci for a single column, the target column |
1332 |
unsetCollapsed(collapsed,ci); |
1333 |
return; |
1334 |
} |
1335 |
|
1336 |
if (ci.getMin() == targetColumnIx || ci.getMax() == targetColumnIx) { |
1337 |
// The target column is at either end of the multi-column ColumnInfo ci |
1338 |
// we'll just divide the info and create a new one |
1339 |
if (ci.getMin() == targetColumnIx) { |
1340 |
ci.setMin(targetColumnIx + 1); |
1341 |
} else { |
1342 |
ci.setMax(targetColumnIx - 1); |
1343 |
k++; // adjust insert pos to insert after |
1344 |
} |
1345 |
CTCol nci = columnHelper.cloneCol(cols,ci); |
1346 |
nci.setMin(targetColumnIx); |
1347 |
unsetCollapsed(collapsed, nci); |
1348 |
this.columnHelper.addCleanColIntoCols(cols,nci); |
1349 |
|
1350 |
} |
1351 |
else { |
1352 |
//split to 3 records |
1353 |
CTCol ciStart = ci; |
1354 |
CTCol ciMid = columnHelper.cloneCol(cols,ci); |
1355 |
CTCol ciEnd = columnHelper.cloneCol(cols,ci); |
1356 |
int lastcolumn = (int)ci.getMax(); |
1357 |
|
1358 |
ciStart.setMax(targetColumnIx - 1); |
1359 |
|
1360 |
ciMid.setMin(targetColumnIx); |
1361 |
ciMid.setMax(targetColumnIx); |
1362 |
unsetCollapsed(collapsed, ciMid); |
1363 |
this.columnHelper.addCleanColIntoCols(cols,ciMid); |
1364 |
|
1365 |
ciEnd.setMin(targetColumnIx+1); |
1366 |
ciEnd.setMax(lastcolumn); |
1367 |
this.columnHelper.addCleanColIntoCols(cols,ciEnd); |
1368 |
} |
1236 |
} |
1369 |
} |
1237 |
|
1370 |
|
|
|
1371 |
private void unsetCollapsed(boolean collapsed, CTCol ci){ |
1372 |
if(collapsed){ |
1373 |
ci.setCollapsed(collapsed); |
1374 |
} |
1375 |
else{ |
1376 |
ci.unsetCollapsed(); |
1377 |
} |
1378 |
} |
1379 |
|
1238 |
/** |
1380 |
/** |
|
|
1381 |
* Sets all adjacent columns of the same outline level to the specified hidden status. |
1382 |
* @param pIdx the col info index of the start of the outline group |
1383 |
* @return the column index of the last column in the outline group |
1384 |
*/ |
1385 |
private int setGroupHidden(int pIdx, int level, boolean hidden) { |
1386 |
CTCols cols=worksheet.getColsArray(0); |
1387 |
int idx = pIdx; |
1388 |
CTCol columnInfo = cols.getColArray(idx); |
1389 |
while (idx < cols.sizeOfColArray()) { |
1390 |
columnInfo.setHidden(hidden); |
1391 |
if (idx + 1 < cols.sizeOfColArray()) { |
1392 |
CTCol nextColumnInfo = cols.getColArray(idx+1); |
1393 |
|
1394 |
if (!isAdjacentBefore(columnInfo,nextColumnInfo)) { |
1395 |
break; |
1396 |
} |
1397 |
|
1398 |
if (nextColumnInfo.getOutlineLevel() < level) { |
1399 |
break; |
1400 |
} |
1401 |
columnInfo = nextColumnInfo; |
1402 |
} |
1403 |
idx++; |
1404 |
} |
1405 |
return (int)columnInfo.getMax(); |
1406 |
} |
1407 |
|
1408 |
|
1409 |
private boolean isAdjacentBefore(CTCol col,CTCol other_col) { |
1410 |
return (col.getMax() == (other_col.getMin() - 1)); |
1411 |
} |
1412 |
|
1413 |
private int findStartOfColumnOutlineGroup(int pIdx) { |
1414 |
// Find the start of the group. |
1415 |
CTCols cols=worksheet.getColsArray(0); |
1416 |
CTCol columnInfo = cols.getColArray(pIdx); |
1417 |
int level = columnInfo.getOutlineLevel(); |
1418 |
int idx = pIdx; |
1419 |
while (idx != 0) { |
1420 |
CTCol prevColumnInfo = cols.getColArray(idx - 1); |
1421 |
if (!isAdjacentBefore(prevColumnInfo,columnInfo)) { |
1422 |
break; |
1423 |
} |
1424 |
if (prevColumnInfo.getOutlineLevel() < level) { |
1425 |
break; |
1426 |
} |
1427 |
idx--; |
1428 |
columnInfo = prevColumnInfo; |
1429 |
} |
1430 |
return idx; |
1431 |
} |
1432 |
|
1433 |
private int findEndOfColumnOutlineGroup(int colInfoIndex) { |
1434 |
CTCols cols=worksheet.getColsArray(0); |
1435 |
// Find the end of the group. |
1436 |
CTCol columnInfo = cols.getColArray(colInfoIndex); |
1437 |
int level = columnInfo.getOutlineLevel(); |
1438 |
int idx = colInfoIndex; |
1439 |
while (idx < cols.sizeOfColArray() - 1) { |
1440 |
CTCol nextColumnInfo = cols.getColArray(idx + 1); |
1441 |
if (!isAdjacentBefore(columnInfo,nextColumnInfo)) { |
1442 |
break; |
1443 |
} |
1444 |
if (nextColumnInfo.getOutlineLevel() < level) { |
1445 |
break; |
1446 |
} |
1447 |
idx++; |
1448 |
columnInfo = nextColumnInfo; |
1449 |
} |
1450 |
return idx; |
1451 |
} |
1452 |
|
1453 |
|
1454 |
private void expandColumn(int columnIndex) { |
1455 |
CTCols cols=worksheet.getColsArray(0); |
1456 |
CTCol col= columnHelper.getColumn(columnIndex, false); |
1457 |
int colInfoIx = columnHelper.getIndexOfColumn(cols, col); |
1458 |
|
1459 |
int idx = findColInfoIdx((int)col.getMax(), colInfoIx); |
1460 |
if (idx == -1) { |
1461 |
return; |
1462 |
} |
1463 |
|
1464 |
// If it is already expanded do nothing. |
1465 |
if (!isColumnGroupCollapsed(idx)) { |
1466 |
return; |
1467 |
} |
1468 |
|
1469 |
// Find the start/end of the group. |
1470 |
int startIdx = findStartOfColumnOutlineGroup(idx); |
1471 |
int endIdx = findEndOfColumnOutlineGroup(idx); |
1472 |
|
1473 |
// expand: |
1474 |
// colapsed bit must be unset |
1475 |
// hidden bit gets unset _if_ surrounding groups are expanded you can determine |
1476 |
// this by looking at the hidden bit of the enclosing group. You will have |
1477 |
// to look at the start and the end of the current group to determine which |
1478 |
// is the enclosing group |
1479 |
// hidden bit only is altered for this outline level. ie. don't uncollapse contained groups |
1480 |
CTCol columnInfo = cols.getColArray(endIdx); |
1481 |
if (!isColumnGroupHiddenByParent(idx)) { |
1482 |
int outlineLevel = columnInfo.getOutlineLevel(); |
1483 |
boolean nestedGroup=false; |
1484 |
for (int i = startIdx; i <= endIdx; i++) { |
1485 |
CTCol ci = cols.getColArray(i); |
1486 |
if (outlineLevel == ci.getOutlineLevel()){ |
1487 |
ci.unsetHidden(); |
1488 |
if(nestedGroup){ |
1489 |
nestedGroup=false; |
1490 |
ci.setCollapsed(true); |
1491 |
} |
1492 |
} |
1493 |
else{ |
1494 |
nestedGroup=true; |
1495 |
} |
1496 |
} |
1497 |
} |
1498 |
// Write collapse flag (stored in a single col info record after this outline group) |
1499 |
setColumn((int)columnInfo.getMax() + 1, null, null, null, Boolean.FALSE, Boolean.FALSE); |
1500 |
} |
1501 |
|
1502 |
private boolean isColumnGroupHiddenByParent(int idx) { |
1503 |
CTCols cols=worksheet.getColsArray(0); |
1504 |
// Look out outline details of end |
1505 |
int endLevel = 0; |
1506 |
boolean endHidden = false; |
1507 |
int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup( idx ); |
1508 |
if (endOfOutlineGroupIdx < cols.sizeOfColArray()) { |
1509 |
CTCol nextInfo = cols.getColArray(endOfOutlineGroupIdx + 1); |
1510 |
if (isAdjacentBefore(cols.getColArray(endOfOutlineGroupIdx),nextInfo)) { |
1511 |
endLevel = nextInfo.getOutlineLevel(); |
1512 |
endHidden = nextInfo.getHidden(); |
1513 |
} |
1514 |
} |
1515 |
// Look out outline details of start |
1516 |
int startLevel = 0; |
1517 |
boolean startHidden = false; |
1518 |
int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup( idx ); |
1519 |
if (startOfOutlineGroupIdx > 0) { |
1520 |
CTCol prevInfo = cols.getColArray(startOfOutlineGroupIdx - 1); |
1521 |
|
1522 |
if (isAdjacentBefore(prevInfo,cols.getColArray(startOfOutlineGroupIdx))) { |
1523 |
startLevel = prevInfo.getOutlineLevel(); |
1524 |
startHidden = prevInfo.getHidden(); |
1525 |
} |
1526 |
|
1527 |
} |
1528 |
if (endLevel > startLevel) { |
1529 |
return endHidden; |
1530 |
} |
1531 |
return startHidden; |
1532 |
} |
1533 |
|
1534 |
|
1535 |
|
1536 |
private int findColInfoIdx(int columnValue, int fromColInfoIdx) { |
1537 |
CTCols cols=worksheet.getColsArray(0); |
1538 |
|
1539 |
if (columnValue < 0) { |
1540 |
throw new IllegalArgumentException( "column parameter out of range: " + columnValue ); |
1541 |
} |
1542 |
if (fromColInfoIdx < 0) { |
1543 |
throw new IllegalArgumentException( "fromIdx parameter out of range: " + fromColInfoIdx ); |
1544 |
} |
1545 |
|
1546 |
for (int k = fromColInfoIdx; k < cols.sizeOfColArray(); k++) { |
1547 |
CTCol ci = cols.getColArray(k); |
1548 |
|
1549 |
if (containsColumn(ci,columnValue)) { |
1550 |
return k; |
1551 |
} |
1552 |
|
1553 |
if (ci.getMin() > fromColInfoIdx) { |
1554 |
break; |
1555 |
} |
1556 |
|
1557 |
} |
1558 |
return -1; |
1559 |
} |
1560 |
|
1561 |
private boolean containsColumn(CTCol col,int columnIndex) { |
1562 |
return col.getMin() <= columnIndex && columnIndex <= col.getMax(); |
1563 |
} |
1564 |
|
1565 |
/** |
1566 |
* 'Collapsed' state is stored in a single column col info record immediately after the outline group |
1567 |
* @param idx |
1568 |
* @return a boolean represented if the column is collapsed |
1569 |
*/ |
1570 |
private boolean isColumnGroupCollapsed(int idx) { |
1571 |
CTCols cols=worksheet.getColsArray(0); |
1572 |
int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx); |
1573 |
int nextColInfoIx = endOfOutlineGroupIdx+1; |
1574 |
if (nextColInfoIx >= cols.sizeOfColArray()) { |
1575 |
return false; |
1576 |
} |
1577 |
CTCol nextColInfo = cols.getColArray(nextColInfoIx); |
1578 |
|
1579 |
CTCol col=cols.getColArray(endOfOutlineGroupIdx); |
1580 |
if (!isAdjacentBefore(col,nextColInfo)) { |
1581 |
return false; |
1582 |
} |
1583 |
|
1584 |
return nextColInfo.getCollapsed(); |
1585 |
} |
1586 |
|
1587 |
/** |
1239 |
* Get the visibility state for a given column. |
1588 |
* Get the visibility state for a given column. |
1240 |
* |
1589 |
* |
1241 |
* @param columnIndex - the column to get (0-based) |
1590 |
* @param columnIndex - the column to get (0-based) |
Lines 1327-1337
Link Here
|
1327 |
opts.setHorizontalCentered(value); |
1676 |
opts.setHorizontalCentered(value); |
1328 |
} |
1677 |
} |
1329 |
|
1678 |
|
|
|
1679 |
|
1330 |
/** |
1680 |
/** |
1331 |
* Whether the output is vertically centered on the page. |
1681 |
* group the row |
1332 |
* |
1682 |
* It is possible for collapsed to be false and yet still have the rows in question hidden. |
1333 |
* @param value true to vertically center, false otherwise. |
1683 |
* This can be achieved by having a lower outline level collapsed, thus hiding all the child rows. |
|
|
1684 |
* Note that in this case, if the lowest level were expanded, the middle level would remain |
1685 |
* collapsed. |
1686 |
* |
1687 |
* @param rowIndex - the row involved |
1688 |
* @param collapse - boolean value for collapse |
1334 |
*/ |
1689 |
*/ |
|
|
1690 |
public void setRowGroupCollapsed(int rowIndex, boolean collapse) { |
1691 |
if(collapse){ |
1692 |
collapseRow(rowIndex); |
1693 |
} |
1694 |
else{ |
1695 |
expandRow(rowIndex); |
1696 |
} |
1697 |
} |
1698 |
|
1699 |
private void collapseRow(int rowIndex){ |
1700 |
XSSFRow row=getRow(rowIndex-1); |
1701 |
if(row!=null){ |
1702 |
int startRow=findStartOfRowOutlineGroup(rowIndex-1); |
1703 |
|
1704 |
// Hide all the columns until the end of the group |
1705 |
int lastRow = writeHidden( row, startRow, true ); |
1706 |
if (getRow(lastRow+1) != null){ |
1707 |
getRow(lastRow+1).getCTRow().setCollapsed(true); |
1708 |
} |
1709 |
else{ |
1710 |
XSSFRow newRow=createRow(lastRow+1); |
1711 |
newRow.getCTRow().setCollapsed(true); |
1712 |
} |
1713 |
} |
1714 |
} |
1715 |
|
1716 |
private int findStartOfRowOutlineGroup(int rowIndex) { |
1717 |
// Find the start of the group. |
1718 |
int level = getRow( rowIndex ).getCTRow().getOutlineLevel(); |
1719 |
int currentRow = rowIndex; |
1720 |
while (getRow( currentRow) != null){ |
1721 |
if (getRow( currentRow).getCTRow().getOutlineLevel() < level) |
1722 |
return currentRow+1; |
1723 |
currentRow--; |
1724 |
} |
1725 |
return currentRow+1; |
1726 |
} |
1727 |
|
1728 |
private int writeHidden( XSSFRow xRow, int rowIndex, boolean hidden ) { |
1729 |
int level = xRow.getCTRow().getOutlineLevel(); |
1730 |
for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) { |
1731 |
xRow=(XSSFRow)it.next(); |
1732 |
if(xRow.getCTRow().getOutlineLevel() >= level){ |
1733 |
xRow.getCTRow().setHidden( hidden ); |
1734 |
rowIndex++; |
1735 |
} |
1736 |
|
1737 |
} |
1738 |
return rowIndex; |
1739 |
} |
1740 |
|
1741 |
private void expandRow( int rowNumber ) { |
1742 |
int idx = rowNumber; |
1743 |
if (idx == -1) |
1744 |
return; |
1745 |
XSSFRow row=getRow(rowNumber-1); |
1746 |
// If it is already expanded do nothing. |
1747 |
if (!row.getCTRow().isSetHidden()) |
1748 |
return; |
1749 |
|
1750 |
// Find the start of the group. |
1751 |
int startIdx = findStartOfRowOutlineGroup( idx - 1 ); |
1752 |
|
1753 |
// Find the end of the group. |
1754 |
int endIdx = findEndOfRowOutlineGroup( idx -1); |
1755 |
|
1756 |
// expand: |
1757 |
// collapsed must be unset |
1758 |
// hidden bit gets unset _if_ surrounding groups are expanded you can determine |
1759 |
// this by looking at the hidden bit of the enclosing group. You will have |
1760 |
// to look at the start and the end of the current group to determine which |
1761 |
// is the enclosing group |
1762 |
// hidden bit only is altered for this outline level. ie. don't un-collapse contained groups |
1763 |
if ( !isRowGroupHiddenByParent( idx -1) ) { |
1764 |
for ( int i = startIdx; i < endIdx; i++ ) { |
1765 |
if ( row.getCTRow().getOutlineLevel() == getRow( i ).getCTRow().getOutlineLevel() ){ |
1766 |
getRow( i ).getCTRow().unsetHidden(); |
1767 |
} |
1768 |
else if (!isRowGroupCollapsed(i)){ |
1769 |
getRow( i ).getCTRow().unsetHidden(); |
1770 |
} |
1771 |
} |
1772 |
} |
1773 |
// Write collapse field |
1774 |
getRow( endIdx + 1 ).getCTRow().unsetCollapsed(); |
1775 |
} |
1776 |
|
1777 |
public int findEndOfRowOutlineGroup( int row ) { |
1778 |
int level = getRow( row ).getCTRow().getOutlineLevel(); |
1779 |
int currentRow; |
1780 |
for (currentRow = row; currentRow < getLastRowNum(); currentRow++) { |
1781 |
if (getRow(currentRow) == null || getRow(currentRow).getCTRow().getOutlineLevel() < level) { |
1782 |
break; |
1783 |
} |
1784 |
} |
1785 |
return currentRow; |
1786 |
} |
1787 |
|
1788 |
private boolean isRowGroupHiddenByParent( int row ) { |
1789 |
// Look out outline details of end |
1790 |
int endLevel; |
1791 |
boolean endHidden; |
1792 |
int endOfOutlineGroupIdx = findEndOfRowOutlineGroup( row ); |
1793 |
if (getRow( endOfOutlineGroupIdx + 1 ) == null) { |
1794 |
endLevel = 0; |
1795 |
endHidden = false; |
1796 |
} |
1797 |
else { |
1798 |
endLevel = (int)(getRow( endOfOutlineGroupIdx + 1).getCTRow().getOutlineLevel()); |
1799 |
endHidden = getRow( endOfOutlineGroupIdx + 1).getCTRow().getHidden(); |
1800 |
} |
1801 |
|
1802 |
// Look out outline details of start |
1803 |
int startLevel; |
1804 |
boolean startHidden; |
1805 |
int startOfOutlineGroupIdx = findStartOfRowOutlineGroup( row ); |
1806 |
if (startOfOutlineGroupIdx - 1 < 0 || getRow(startOfOutlineGroupIdx - 1) == null) { |
1807 |
startLevel = 0; |
1808 |
startHidden = false; |
1809 |
} |
1810 |
else { |
1811 |
startLevel = getRow( startOfOutlineGroupIdx - 1).getCTRow().getOutlineLevel(); |
1812 |
startHidden = getRow( startOfOutlineGroupIdx - 1 ).getCTRow().getHidden(); |
1813 |
} |
1814 |
if (endLevel > startLevel){ |
1815 |
return endHidden; |
1816 |
} |
1817 |
else { |
1818 |
return startHidden; |
1819 |
} |
1820 |
} |
1821 |
|
1822 |
private boolean isRowGroupCollapsed( int row ) { |
1823 |
int collapseRow = findEndOfRowOutlineGroup( row ) + 1; |
1824 |
if (getRow(collapseRow) == null) |
1825 |
return false; |
1826 |
else |
1827 |
return getRow( collapseRow ).getCTRow().getCollapsed(); |
1828 |
} |
1829 |
|
1830 |
|
1335 |
public void setVerticallyCenter(boolean value) { |
1831 |
public void setVerticallyCenter(boolean value) { |
1336 |
CTPrintOptions opts = worksheet.isSetPrintOptions() ? |
1832 |
CTPrintOptions opts = worksheet.isSetPrintOptions() ? |
1337 |
worksheet.getPrintOptions() : worksheet.addNewPrintOptions(); |
1833 |
worksheet.getPrintOptions() : worksheet.addNewPrintOptions(); |
Lines 1416-1422
Link Here
|
1416 |
if (!copyRowHeight) { |
1912 |
if (!copyRowHeight) { |
1417 |
row.setHeight((short)-1); |
1913 |
row.setHeight((short)-1); |
1418 |
} |
1914 |
} |
1419 |
|
|
|
1420 |
if (resetOriginalRowHeight && getDefaultRowHeight() >= 0) { |
1915 |
if (resetOriginalRowHeight && getDefaultRowHeight() >= 0) { |
1421 |
row.setHeight(getDefaultRowHeight()); |
1916 |
row.setHeight(getDefaultRowHeight()); |
1422 |
} |
1917 |
} |
Lines 1425-1430
Link Here
|
1425 |
} |
1920 |
} |
1426 |
else if (row.getRowNum() >= startRow && row.getRowNum() <= endRow) { |
1921 |
else if (row.getRowNum() >= startRow && row.getRowNum() <= endRow) { |
1427 |
row.setRowNum(row.getRowNum() + n); |
1922 |
row.setRowNum(row.getRowNum() + n); |
|
|
1923 |
|
1924 |
modifyCellReference((XSSFRow)row); |
1925 |
|
1428 |
if (row.getFirstCellNum() > -1) { |
1926 |
if (row.getFirstCellNum() > -1) { |
1429 |
modifyCellReference((XSSFRow) row); |
1927 |
modifyCellReference((XSSFRow) row); |
1430 |
} |
1928 |
} |
Lines 1437-1451
Link Here
|
1437 |
} |
1935 |
} |
1438 |
|
1936 |
|
1439 |
|
1937 |
|
1440 |
private void modifyCellReference(XSSFRow row) { |
1938 |
private void modifyCellReference(XSSFRow row){ |
1441 |
for (int i = row.getFirstCellNum(); i <= row.getLastCellNum(); i++) { |
1939 |
int firstCellNum=row.getFirstCellNum(); |
1442 |
XSSFCell c = row.getCell(i); |
1940 |
//a row could have no cell |
1443 |
if (c != null) { |
1941 |
if(firstCellNum != -1){ |
1444 |
c.modifyCellReference(row); |
1942 |
for(int i=firstCellNum;i<=row.getLastCellNum();i++){ |
1445 |
} |
1943 |
XSSFCell c=(XSSFCell)row.getCell(i); |
1446 |
} |
1944 |
if(c!=null){ |
|
|
1945 |
c.modifyCellReference(row); |
1946 |
} |
1947 |
} |
1948 |
} |
1447 |
} |
1949 |
} |
1448 |
|
1950 |
|
|
|
1951 |
|
1449 |
/** |
1952 |
/** |
1450 |
* Location of the top left visible cell Location of the top left visible cell in the bottom right |
1953 |
* Location of the top left visible cell Location of the top left visible cell in the bottom right |
1451 |
* pane (when in Left-to-Right mode). |
1954 |
* pane (when in Left-to-Right mode). |
Lines 1456-1462
Link Here
|
1456 |
public void showInPane(short toprow, short leftcol) { |
1959 |
public void showInPane(short toprow, short leftcol) { |
1457 |
CellReference cellReference = new CellReference(toprow, leftcol); |
1960 |
CellReference cellReference = new CellReference(toprow, leftcol); |
1458 |
String cellRef = cellReference.formatAsString(); |
1961 |
String cellRef = cellReference.formatAsString(); |
1459 |
getSheetTypeSheetView().setTopLeftCell(cellRef); |
1962 |
// getSheetTypeSheetView().setTopLeftCell(cellRef); |
|
|
1963 |
getPane().setTopLeftCell(cellRef); |
1460 |
} |
1964 |
} |
1461 |
|
1965 |
|
1462 |
public void ungroupColumn(short fromColumn, short toColumn) { |
1966 |
public void ungroupColumn(short fromColumn, short toColumn) { |