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 |
1287 |
.getOutlineLevel(), true); |
1288 |
|
1289 |
// write collapse field |
1290 |
setColumn((int) (lastColMax + 1), null, 0, null, null, Boolean.TRUE); |
1291 |
|
1231 |
} |
1292 |
} |
1232 |
|
1293 |
|
1233 |
public void setRowGroupCollapsed(int row, boolean collapse) { |
1294 |
private void setColumn(int targetColumnIx, Short xfIndex, Integer style, |
1234 |
// TODO Auto-generated method stub |
1295 |
Integer level, Boolean hidden, Boolean collapsed) { |
|
|
1296 |
CTCols cols = worksheet.getColsArray(0); |
1297 |
CTCol ci = null; |
1298 |
int k = 0; |
1299 |
for (k = 0; k < cols.sizeOfColArray(); k++) { |
1300 |
CTCol tci = cols.getColArray(k); |
1301 |
if (tci.getMin() >= targetColumnIx |
1302 |
&& tci.getMax() <= targetColumnIx) { |
1303 |
ci = tci; |
1304 |
break; |
1305 |
} |
1306 |
if (tci.getMin() > targetColumnIx) { |
1307 |
// call column infos after k are for later columns |
1308 |
break; // exit now so k will be the correct insert pos |
1309 |
} |
1310 |
} |
1235 |
|
1311 |
|
|
|
1312 |
if (ci == null) { |
1313 |
// okay so there ISN'T a column info record that covers this column |
1314 |
// so lets create one! |
1315 |
CTCol nci = CTCol.Factory.newInstance(); |
1316 |
nci.setMin(targetColumnIx); |
1317 |
nci.setMax(targetColumnIx); |
1318 |
unsetCollapsed(collapsed, nci); |
1319 |
this.columnHelper.addCleanColIntoCols(cols, nci); |
1320 |
return; |
1321 |
} |
1322 |
|
1323 |
boolean styleChanged = style != null |
1324 |
&& ci.getStyle() != style.intValue(); |
1325 |
boolean levelChanged = level != null |
1326 |
&& ci.getOutlineLevel() != level.intValue(); |
1327 |
boolean hiddenChanged = hidden != null |
1328 |
&& ci.getHidden() != hidden.booleanValue(); |
1329 |
boolean collapsedChanged = collapsed != null |
1330 |
&& ci.getCollapsed() != collapsed.booleanValue(); |
1331 |
boolean columnChanged = levelChanged || hiddenChanged |
1332 |
|| collapsedChanged || styleChanged; |
1333 |
if (!columnChanged) { |
1334 |
// do nothing...nothing changed. |
1335 |
return; |
1336 |
} |
1337 |
|
1338 |
if (ci.getMin() == targetColumnIx && ci.getMax() == targetColumnIx) { |
1339 |
// ColumnInfo ci for a single column, the target column |
1340 |
unsetCollapsed(collapsed, ci); |
1341 |
return; |
1342 |
} |
1343 |
|
1344 |
if (ci.getMin() == targetColumnIx || ci.getMax() == targetColumnIx) { |
1345 |
// The target column is at either end of the multi-column ColumnInfo |
1346 |
// ci |
1347 |
// we'll just divide the info and create a new one |
1348 |
if (ci.getMin() == targetColumnIx) { |
1349 |
ci.setMin(targetColumnIx + 1); |
1350 |
} else { |
1351 |
ci.setMax(targetColumnIx - 1); |
1352 |
k++; // adjust insert pos to insert after |
1353 |
} |
1354 |
CTCol nci = columnHelper.cloneCol(cols, ci); |
1355 |
nci.setMin(targetColumnIx); |
1356 |
unsetCollapsed(collapsed, nci); |
1357 |
this.columnHelper.addCleanColIntoCols(cols, nci); |
1358 |
|
1359 |
} else { |
1360 |
// split to 3 records |
1361 |
CTCol ciStart = ci; |
1362 |
CTCol ciMid = columnHelper.cloneCol(cols, ci); |
1363 |
CTCol ciEnd = columnHelper.cloneCol(cols, ci); |
1364 |
int lastcolumn = (int) ci.getMax(); |
1365 |
|
1366 |
ciStart.setMax(targetColumnIx - 1); |
1367 |
|
1368 |
ciMid.setMin(targetColumnIx); |
1369 |
ciMid.setMax(targetColumnIx); |
1370 |
unsetCollapsed(collapsed, ciMid); |
1371 |
this.columnHelper.addCleanColIntoCols(cols, ciMid); |
1372 |
|
1373 |
ciEnd.setMin(targetColumnIx + 1); |
1374 |
ciEnd.setMax(lastcolumn); |
1375 |
this.columnHelper.addCleanColIntoCols(cols, ciEnd); |
1376 |
} |
1236 |
} |
1377 |
} |
1237 |
|
1378 |
|
|
|
1379 |
private void unsetCollapsed(boolean collapsed, CTCol ci) { |
1380 |
if (collapsed) { |
1381 |
ci.setCollapsed(collapsed); |
1382 |
} else { |
1383 |
ci.unsetCollapsed(); |
1384 |
} |
1385 |
} |
1386 |
|
1238 |
/** |
1387 |
/** |
|
|
1388 |
* Sets all adjacent columns of the same outline level to the specified |
1389 |
* hidden status. |
1390 |
* |
1391 |
* @param pIdx |
1392 |
* the col info index of the start of the outline group |
1393 |
* @return the column index of the last column in the outline group |
1394 |
*/ |
1395 |
private int setGroupHidden(int pIdx, int level, boolean hidden) { |
1396 |
CTCols cols = worksheet.getColsArray(0); |
1397 |
int idx = pIdx; |
1398 |
CTCol columnInfo = cols.getColArray(idx); |
1399 |
while (idx < cols.sizeOfColArray()) { |
1400 |
columnInfo.setHidden(hidden); |
1401 |
if (idx + 1 < cols.sizeOfColArray()) { |
1402 |
CTCol nextColumnInfo = cols.getColArray(idx + 1); |
1403 |
|
1404 |
if (!isAdjacentBefore(columnInfo, nextColumnInfo)) { |
1405 |
break; |
1406 |
} |
1407 |
|
1408 |
if (nextColumnInfo.getOutlineLevel() < level) { |
1409 |
break; |
1410 |
} |
1411 |
columnInfo = nextColumnInfo; |
1412 |
} |
1413 |
idx++; |
1414 |
} |
1415 |
return (int) columnInfo.getMax(); |
1416 |
} |
1417 |
|
1418 |
private boolean isAdjacentBefore(CTCol col, CTCol other_col) { |
1419 |
return (col.getMax() == (other_col.getMin() - 1)); |
1420 |
} |
1421 |
|
1422 |
private int findStartOfColumnOutlineGroup(int pIdx) { |
1423 |
// Find the start of the group. |
1424 |
CTCols cols = worksheet.getColsArray(0); |
1425 |
CTCol columnInfo = cols.getColArray(pIdx); |
1426 |
int level = columnInfo.getOutlineLevel(); |
1427 |
int idx = pIdx; |
1428 |
while (idx != 0) { |
1429 |
CTCol prevColumnInfo = cols.getColArray(idx - 1); |
1430 |
if (!isAdjacentBefore(prevColumnInfo, columnInfo)) { |
1431 |
break; |
1432 |
} |
1433 |
if (prevColumnInfo.getOutlineLevel() < level) { |
1434 |
break; |
1435 |
} |
1436 |
idx--; |
1437 |
columnInfo = prevColumnInfo; |
1438 |
} |
1439 |
return idx; |
1440 |
} |
1441 |
|
1442 |
private int findEndOfColumnOutlineGroup(int colInfoIndex) { |
1443 |
CTCols cols = worksheet.getColsArray(0); |
1444 |
// Find the end of the group. |
1445 |
CTCol columnInfo = cols.getColArray(colInfoIndex); |
1446 |
int level = columnInfo.getOutlineLevel(); |
1447 |
int idx = colInfoIndex; |
1448 |
while (idx < cols.sizeOfColArray() - 1) { |
1449 |
CTCol nextColumnInfo = cols.getColArray(idx + 1); |
1450 |
if (!isAdjacentBefore(columnInfo, nextColumnInfo)) { |
1451 |
break; |
1452 |
} |
1453 |
if (nextColumnInfo.getOutlineLevel() < level) { |
1454 |
break; |
1455 |
} |
1456 |
idx++; |
1457 |
columnInfo = nextColumnInfo; |
1458 |
} |
1459 |
return idx; |
1460 |
} |
1461 |
|
1462 |
private void expandColumn(int columnIndex) { |
1463 |
CTCols cols = worksheet.getColsArray(0); |
1464 |
CTCol col = columnHelper.getColumn(columnIndex, false); |
1465 |
int colInfoIx = columnHelper.getIndexOfColumn(cols, col); |
1466 |
|
1467 |
int idx = findColInfoIdx((int) col.getMax(), colInfoIx); |
1468 |
if (idx == -1) { |
1469 |
return; |
1470 |
} |
1471 |
|
1472 |
// If it is already expanded do nothing. |
1473 |
if (!isColumnGroupCollapsed(idx)) { |
1474 |
return; |
1475 |
} |
1476 |
|
1477 |
// Find the start/end of the group. |
1478 |
int startIdx = findStartOfColumnOutlineGroup(idx); |
1479 |
int endIdx = findEndOfColumnOutlineGroup(idx); |
1480 |
|
1481 |
// expand: |
1482 |
// colapsed bit must be unset |
1483 |
// hidden bit gets unset _if_ surrounding groups are expanded you can |
1484 |
// determine |
1485 |
// this by looking at the hidden bit of the enclosing group. You will |
1486 |
// have |
1487 |
// to look at the start and the end of the current group to determine |
1488 |
// which |
1489 |
// is the enclosing group |
1490 |
// hidden bit only is altered for this outline level. ie. don't |
1491 |
// uncollapse contained groups |
1492 |
CTCol columnInfo = cols.getColArray(endIdx); |
1493 |
if (!isColumnGroupHiddenByParent(idx)) { |
1494 |
int outlineLevel = columnInfo.getOutlineLevel(); |
1495 |
boolean nestedGroup = false; |
1496 |
for (int i = startIdx; i <= endIdx; i++) { |
1497 |
CTCol ci = cols.getColArray(i); |
1498 |
if (outlineLevel == ci.getOutlineLevel()) { |
1499 |
ci.unsetHidden(); |
1500 |
if (nestedGroup) { |
1501 |
nestedGroup = false; |
1502 |
ci.setCollapsed(true); |
1503 |
} |
1504 |
} else { |
1505 |
nestedGroup = true; |
1506 |
} |
1507 |
} |
1508 |
} |
1509 |
// Write collapse flag (stored in a single col info record after this |
1510 |
// outline group) |
1511 |
setColumn((int) columnInfo.getMax() + 1, null, null, null, |
1512 |
Boolean.FALSE, Boolean.FALSE); |
1513 |
} |
1514 |
|
1515 |
private boolean isColumnGroupHiddenByParent(int idx) { |
1516 |
CTCols cols = worksheet.getColsArray(0); |
1517 |
// Look out outline details of end |
1518 |
int endLevel = 0; |
1519 |
boolean endHidden = false; |
1520 |
int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx); |
1521 |
if (endOfOutlineGroupIdx < cols.sizeOfColArray()) { |
1522 |
CTCol nextInfo = cols.getColArray(endOfOutlineGroupIdx + 1); |
1523 |
if (isAdjacentBefore(cols.getColArray(endOfOutlineGroupIdx), |
1524 |
nextInfo)) { |
1525 |
endLevel = nextInfo.getOutlineLevel(); |
1526 |
endHidden = nextInfo.getHidden(); |
1527 |
} |
1528 |
} |
1529 |
// Look out outline details of start |
1530 |
int startLevel = 0; |
1531 |
boolean startHidden = false; |
1532 |
int startOfOutlineGroupIdx = findStartOfColumnOutlineGroup(idx); |
1533 |
if (startOfOutlineGroupIdx > 0) { |
1534 |
CTCol prevInfo = cols.getColArray(startOfOutlineGroupIdx - 1); |
1535 |
|
1536 |
if (isAdjacentBefore(prevInfo, cols |
1537 |
.getColArray(startOfOutlineGroupIdx))) { |
1538 |
startLevel = prevInfo.getOutlineLevel(); |
1539 |
startHidden = prevInfo.getHidden(); |
1540 |
} |
1541 |
|
1542 |
} |
1543 |
if (endLevel > startLevel) { |
1544 |
return endHidden; |
1545 |
} |
1546 |
return startHidden; |
1547 |
} |
1548 |
|
1549 |
private int findColInfoIdx(int columnValue, int fromColInfoIdx) { |
1550 |
CTCols cols = worksheet.getColsArray(0); |
1551 |
|
1552 |
if (columnValue < 0) { |
1553 |
throw new IllegalArgumentException( |
1554 |
"column parameter out of range: " + columnValue); |
1555 |
} |
1556 |
if (fromColInfoIdx < 0) { |
1557 |
throw new IllegalArgumentException( |
1558 |
"fromIdx parameter out of range: " + fromColInfoIdx); |
1559 |
} |
1560 |
|
1561 |
for (int k = fromColInfoIdx; k < cols.sizeOfColArray(); k++) { |
1562 |
CTCol ci = cols.getColArray(k); |
1563 |
|
1564 |
if (containsColumn(ci, columnValue)) { |
1565 |
return k; |
1566 |
} |
1567 |
|
1568 |
if (ci.getMin() > fromColInfoIdx) { |
1569 |
break; |
1570 |
} |
1571 |
|
1572 |
} |
1573 |
return -1; |
1574 |
} |
1575 |
|
1576 |
private boolean containsColumn(CTCol col, int columnIndex) { |
1577 |
return col.getMin() <= columnIndex && columnIndex <= col.getMax(); |
1578 |
} |
1579 |
|
1580 |
/** |
1581 |
* 'Collapsed' state is stored in a single column col info record |
1582 |
* immediately after the outline group |
1583 |
* |
1584 |
* @param idx |
1585 |
* @return a boolean represented if the column is collapsed |
1586 |
*/ |
1587 |
private boolean isColumnGroupCollapsed(int idx) { |
1588 |
CTCols cols = worksheet.getColsArray(0); |
1589 |
int endOfOutlineGroupIdx = findEndOfColumnOutlineGroup(idx); |
1590 |
int nextColInfoIx = endOfOutlineGroupIdx + 1; |
1591 |
if (nextColInfoIx >= cols.sizeOfColArray()) { |
1592 |
return false; |
1593 |
} |
1594 |
CTCol nextColInfo = cols.getColArray(nextColInfoIx); |
1595 |
|
1596 |
CTCol col = cols.getColArray(endOfOutlineGroupIdx); |
1597 |
if (!isAdjacentBefore(col, nextColInfo)) { |
1598 |
return false; |
1599 |
} |
1600 |
|
1601 |
return nextColInfo.getCollapsed(); |
1602 |
} |
1603 |
|
1604 |
/** |
1239 |
* Get the visibility state for a given column. |
1605 |
* Get the visibility state for a given column. |
1240 |
* |
1606 |
* |
1241 |
* @param columnIndex - the column to get (0-based) |
1607 |
* @param columnIndex - the column to get (0-based) |
Lines 1327-1337
Link Here
|
1327 |
opts.setHorizontalCentered(value); |
1693 |
opts.setHorizontalCentered(value); |
1328 |
} |
1694 |
} |
1329 |
|
1695 |
|
|
|
1696 |
|
1330 |
/** |
1697 |
/** |
1331 |
* Whether the output is vertically centered on the page. |
1698 |
* group the row It is possible for collapsed to be false and yet still have |
1332 |
* |
1699 |
* the rows in question hidden. This can be achieved by having a lower |
1333 |
* @param value true to vertically center, false otherwise. |
1700 |
* outline level collapsed, thus hiding all the child rows. Note that in |
|
|
1701 |
* this case, if the lowest level were expanded, the middle level would |
1702 |
* remain collapsed. |
1703 |
* |
1704 |
* @param rowIndex - |
1705 |
* the row involved |
1706 |
* @param collapse - |
1707 |
* boolean value for collapse |
1334 |
*/ |
1708 |
*/ |
|
|
1709 |
public void setRowGroupCollapsed(int rowIndex, boolean collapse) { |
1710 |
if (collapse) { |
1711 |
collapseRow(rowIndex); |
1712 |
} else { |
1713 |
expandRow(rowIndex); |
1714 |
} |
1715 |
} |
1716 |
|
1717 |
private void collapseRow(int rowIndex) { |
1718 |
XSSFRow row = getRow(rowIndex - 1); |
1719 |
if (row != null) { |
1720 |
int startRow = findStartOfRowOutlineGroup(rowIndex - 1); |
1721 |
|
1722 |
// Hide all the columns until the end of the group |
1723 |
int lastRow = writeHidden(row, startRow, true); |
1724 |
if (getRow(lastRow + 1) != null) { |
1725 |
getRow(lastRow + 1).getCTRow().setCollapsed(true); |
1726 |
} else { |
1727 |
XSSFRow newRow = createRow(lastRow + 1); |
1728 |
newRow.getCTRow().setCollapsed(true); |
1729 |
} |
1730 |
} |
1731 |
} |
1732 |
|
1733 |
private int findStartOfRowOutlineGroup(int rowIndex) { |
1734 |
// Find the start of the group. |
1735 |
int level = getRow(rowIndex).getCTRow().getOutlineLevel(); |
1736 |
int currentRow = rowIndex; |
1737 |
while (getRow(currentRow) != null) { |
1738 |
if (getRow(currentRow).getCTRow().getOutlineLevel() < level) |
1739 |
return currentRow + 1; |
1740 |
currentRow--; |
1741 |
} |
1742 |
return currentRow + 1; |
1743 |
} |
1744 |
|
1745 |
private int writeHidden(XSSFRow xRow, int rowIndex, boolean hidden) { |
1746 |
int level = xRow.getCTRow().getOutlineLevel(); |
1747 |
for (Iterator<Row> it = rowIterator(); it.hasNext();) { |
1748 |
xRow = (XSSFRow) it.next(); |
1749 |
if (xRow.getCTRow().getOutlineLevel() >= level) { |
1750 |
xRow.getCTRow().setHidden(hidden); |
1751 |
rowIndex++; |
1752 |
} |
1753 |
|
1754 |
} |
1755 |
return rowIndex; |
1756 |
} |
1757 |
|
1758 |
private void expandRow(int rowNumber) { |
1759 |
int idx = rowNumber; |
1760 |
if (idx == -1) |
1761 |
return; |
1762 |
XSSFRow row = getRow(rowNumber - 1); |
1763 |
// If it is already expanded do nothing. |
1764 |
if (!row.getCTRow().isSetHidden()) |
1765 |
return; |
1766 |
|
1767 |
// Find the start of the group. |
1768 |
int startIdx = findStartOfRowOutlineGroup(idx - 1); |
1769 |
|
1770 |
// Find the end of the group. |
1771 |
int endIdx = findEndOfRowOutlineGroup(idx - 1); |
1772 |
|
1773 |
// expand: |
1774 |
// collapsed must be unset |
1775 |
// hidden bit gets unset _if_ surrounding groups are expanded you can |
1776 |
// determine |
1777 |
// this by looking at the hidden bit of the enclosing group. You will |
1778 |
// have |
1779 |
// to look at the start and the end of the current group to determine |
1780 |
// which |
1781 |
// is the enclosing group |
1782 |
// hidden bit only is altered for this outline level. ie. don't |
1783 |
// un-collapse contained groups |
1784 |
if (!isRowGroupHiddenByParent(idx - 1)) { |
1785 |
for (int i = startIdx; i < endIdx; i++) { |
1786 |
if (row.getCTRow().getOutlineLevel() == getRow(i).getCTRow() |
1787 |
.getOutlineLevel()) { |
1788 |
getRow(i).getCTRow().unsetHidden(); |
1789 |
} else if (!isRowGroupCollapsed(i)) { |
1790 |
getRow(i).getCTRow().unsetHidden(); |
1791 |
} |
1792 |
} |
1793 |
} |
1794 |
// Write collapse field |
1795 |
getRow(endIdx + 1).getCTRow().unsetCollapsed(); |
1796 |
} |
1797 |
|
1798 |
public int findEndOfRowOutlineGroup(int row) { |
1799 |
int level = getRow(row).getCTRow().getOutlineLevel(); |
1800 |
int currentRow; |
1801 |
for (currentRow = row; currentRow < getLastRowNum(); currentRow++) { |
1802 |
if (getRow(currentRow) == null |
1803 |
|| getRow(currentRow).getCTRow().getOutlineLevel() < level) { |
1804 |
break; |
1805 |
} |
1806 |
} |
1807 |
return currentRow; |
1808 |
} |
1809 |
|
1810 |
private boolean isRowGroupHiddenByParent(int row) { |
1811 |
// Look out outline details of end |
1812 |
int endLevel; |
1813 |
boolean endHidden; |
1814 |
int endOfOutlineGroupIdx = findEndOfRowOutlineGroup(row); |
1815 |
if (getRow(endOfOutlineGroupIdx + 1) == null) { |
1816 |
endLevel = 0; |
1817 |
endHidden = false; |
1818 |
} else { |
1819 |
endLevel = (int) (getRow(endOfOutlineGroupIdx + 1).getCTRow() |
1820 |
.getOutlineLevel()); |
1821 |
endHidden = getRow(endOfOutlineGroupIdx + 1).getCTRow().getHidden(); |
1822 |
} |
1823 |
|
1824 |
// Look out outline details of start |
1825 |
int startLevel; |
1826 |
boolean startHidden; |
1827 |
int startOfOutlineGroupIdx = findStartOfRowOutlineGroup(row); |
1828 |
if (startOfOutlineGroupIdx - 1 < 0 |
1829 |
|| getRow(startOfOutlineGroupIdx - 1) == null) { |
1830 |
startLevel = 0; |
1831 |
startHidden = false; |
1832 |
} else { |
1833 |
startLevel = getRow(startOfOutlineGroupIdx - 1).getCTRow() |
1834 |
.getOutlineLevel(); |
1835 |
startHidden = getRow(startOfOutlineGroupIdx - 1).getCTRow() |
1836 |
.getHidden(); |
1837 |
} |
1838 |
if (endLevel > startLevel) { |
1839 |
return endHidden; |
1840 |
} else { |
1841 |
return startHidden; |
1842 |
} |
1843 |
} |
1844 |
|
1845 |
private boolean isRowGroupCollapsed(int row) { |
1846 |
int collapseRow = findEndOfRowOutlineGroup(row) + 1; |
1847 |
if (getRow(collapseRow) == null) |
1848 |
return false; |
1849 |
else |
1850 |
return getRow(collapseRow).getCTRow().getCollapsed(); |
1851 |
} |
1852 |
|
1853 |
|
1335 |
public void setVerticallyCenter(boolean value) { |
1854 |
public void setVerticallyCenter(boolean value) { |
1336 |
CTPrintOptions opts = worksheet.isSetPrintOptions() ? |
1855 |
CTPrintOptions opts = worksheet.isSetPrintOptions() ? |
1337 |
worksheet.getPrintOptions() : worksheet.addNewPrintOptions(); |
1856 |
worksheet.getPrintOptions() : worksheet.addNewPrintOptions(); |
Lines 1339-1350
Link Here
|
1339 |
} |
1858 |
} |
1340 |
|
1859 |
|
1341 |
/** |
1860 |
/** |
1342 |
* Sets the zoom magnication for the sheet. The zoom is expressed as a |
1861 |
* Sets the zoom magnication for the sheet. The zoom is expressed as a |
1343 |
* fraction. For example to express a zoom of 75% use 3 for the numerator |
1862 |
* fraction. For example to express a zoom of 75% use 3 for the numerator |
1344 |
* and 4 for the denominator. |
1863 |
* and 4 for the denominator. |
1345 |
* |
1864 |
* |
1346 |
* @param numerator The numerator for the zoom magnification. |
1865 |
* @param numerator |
1347 |
* @param denominator The denominator for the zoom magnification. |
1866 |
* The numerator for the zoom magnification. |
|
|
1867 |
* @param denominator |
1868 |
* The denominator for the zoom magnification. |
1348 |
* @see #setZoom(int) |
1869 |
* @see #setZoom(int) |
1349 |
*/ |
1870 |
*/ |
1350 |
public void setZoom(int numerator, int denominator) { |
1871 |
public void setZoom(int numerator, int denominator) { |
Lines 1416-1422
Link Here
|
1416 |
if (!copyRowHeight) { |
1937 |
if (!copyRowHeight) { |
1417 |
row.setHeight((short)-1); |
1938 |
row.setHeight((short)-1); |
1418 |
} |
1939 |
} |
1419 |
|
|
|
1420 |
if (resetOriginalRowHeight && getDefaultRowHeight() >= 0) { |
1940 |
if (resetOriginalRowHeight && getDefaultRowHeight() >= 0) { |
1421 |
row.setHeight(getDefaultRowHeight()); |
1941 |
row.setHeight(getDefaultRowHeight()); |
1422 |
} |
1942 |
} |
Lines 1425-1430
Link Here
|
1425 |
} |
1945 |
} |
1426 |
else if (row.getRowNum() >= startRow && row.getRowNum() <= endRow) { |
1946 |
else if (row.getRowNum() >= startRow && row.getRowNum() <= endRow) { |
1427 |
row.setRowNum(row.getRowNum() + n); |
1947 |
row.setRowNum(row.getRowNum() + n); |
|
|
1948 |
|
1949 |
modifyCellReference((XSSFRow)row); |
1950 |
|
1428 |
if (row.getFirstCellNum() > -1) { |
1951 |
if (row.getFirstCellNum() > -1) { |
1429 |
modifyCellReference((XSSFRow) row); |
1952 |
modifyCellReference((XSSFRow) row); |
1430 |
} |
1953 |
} |
Lines 1437-1451
Link Here
|
1437 |
} |
1960 |
} |
1438 |
|
1961 |
|
1439 |
|
1962 |
|
1440 |
private void modifyCellReference(XSSFRow row) { |
1963 |
private void modifyCellReference(XSSFRow row){ |
1441 |
for (int i = row.getFirstCellNum(); i <= row.getLastCellNum(); i++) { |
1964 |
int firstCellNum=row.getFirstCellNum(); |
1442 |
XSSFCell c = row.getCell(i); |
1965 |
//a row could have no cell |
1443 |
if (c != null) { |
1966 |
if(firstCellNum != -1){ |
1444 |
c.modifyCellReference(row); |
1967 |
for(int i=firstCellNum;i<=row.getLastCellNum();i++){ |
1445 |
} |
1968 |
XSSFCell c=(XSSFCell)row.getCell(i); |
1446 |
} |
1969 |
if(c!=null){ |
|
|
1970 |
c.modifyCellReference(row); |
1971 |
} |
1972 |
} |
1973 |
} |
1447 |
} |
1974 |
} |
1448 |
|
1975 |
|
|
|
1976 |
|
1449 |
/** |
1977 |
/** |
1450 |
* Location of the top left visible cell Location of the top left visible cell in the bottom right |
1978 |
* 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). |
1979 |
* pane (when in Left-to-Right mode). |
Lines 1456-1462
Link Here
|
1456 |
public void showInPane(short toprow, short leftcol) { |
1984 |
public void showInPane(short toprow, short leftcol) { |
1457 |
CellReference cellReference = new CellReference(toprow, leftcol); |
1985 |
CellReference cellReference = new CellReference(toprow, leftcol); |
1458 |
String cellRef = cellReference.formatAsString(); |
1986 |
String cellRef = cellReference.formatAsString(); |
1459 |
getSheetTypeSheetView().setTopLeftCell(cellRef); |
1987 |
// getSheetTypeSheetView().setTopLeftCell(cellRef); |
|
|
1988 |
getPane().setTopLeftCell(cellRef); |
1460 |
} |
1989 |
} |
1461 |
|
1990 |
|
1462 |
public void ungroupColumn(short fromColumn, short toColumn) { |
1991 |
public void ungroupColumn(short fromColumn, short toColumn) { |