diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml index 79eb0e914..4548b63bc 100644 --- a/src/documentation/content/xdocs/changes.xml +++ b/src/documentation/content/xdocs/changes.xml @@ -36,6 +36,7 @@ + 43058 - Support setting row grouping on files from CR IX, which lack GutsRecords 31795 - Support cloning of sheets with certain drawing objects on them 43902 - Don't consider merged regions when auto-sizing columns 42464 - Avoid "Expected ExpPtg to be converted from Shared to Non-Shared Formula" on large, formula heavy worksheets diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 37383c816..5a0461620 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -33,6 +33,7 @@ + 43058 - Support setting row grouping on files from CR IX, which lack GutsRecords 31795 - Support cloning of sheets with certain drawing objects on them 43902 - Don't consider merged regions when auto-sizing columns 42464 - Avoid "Expected ExpPtg to be converted from Shared to Non-Shared Formula" on large, formula heavy worksheets diff --git a/src/java/org/apache/poi/hssf/model/Sheet.java b/src/java/org/apache/poi/hssf/model/Sheet.java index ff18f4636..c3f93b0a0 100644 --- a/src/java/org/apache/poi/hssf/model/Sheet.java +++ b/src/java/org/apache/poi/hssf/model/Sheet.java @@ -3144,7 +3144,13 @@ public class Sheet implements Model maxLevel = Math.max(rowRecord.getOutlineLevel(), maxLevel); } + // Grab the guts record, adding if needed GutsRecord guts = (GutsRecord) findFirstRecordBySid( GutsRecord.sid ); + if(guts == null) { + guts = new GutsRecord(); + records.add(guts); + } + // Set the levels onto it guts.setRowLevelMax( (short) ( maxLevel + 1 ) ); guts.setLeftRowGutter( (short) ( 29 + (12 * (maxLevel)) ) ); } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java index 423b023af..6cea11fa0 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFRow.java @@ -223,6 +223,16 @@ public class HSSFRow { return rowNum; } + + /** + * Returns the rows outline level. Increased as you + * put it into more groups (outlines), reduced as + * you take it out of them. + * TODO - Should this really be public? + */ + protected int getOutlineLevel() { + return row.getOutlineLevel(); + } /** * used internally to add a cell. diff --git a/src/testcases/org/apache/poi/hssf/data/NoGutsRecords.xls b/src/testcases/org/apache/poi/hssf/data/NoGutsRecords.xls new file mode 100644 index 000000000..c4340f6b8 Binary files /dev/null and b/src/testcases/org/apache/poi/hssf/data/NoGutsRecords.xls differ diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java index 9a6f9dca0..714cb8d2c 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFSheet.java @@ -309,6 +309,104 @@ public class TestHSSFSheet assertEquals(1, sheetLS.getPrintSetup().getCopies()); } + public void testGroupRows() throws Exception { + HSSFWorkbook workbook = new HSSFWorkbook(); + HSSFSheet s = workbook.createSheet(); + HSSFRow r1 = s.createRow(0); + HSSFRow r2 = s.createRow(1); + HSSFRow r3 = s.createRow(2); + HSSFRow r4 = s.createRow(3); + HSSFRow r5 = s.createRow(4); + + assertEquals(0, r1.getOutlineLevel()); + assertEquals(0, r2.getOutlineLevel()); + assertEquals(0, r3.getOutlineLevel()); + assertEquals(0, r4.getOutlineLevel()); + assertEquals(0, r5.getOutlineLevel()); + + s.groupRow(2,3); + + assertEquals(0, r1.getOutlineLevel()); + assertEquals(0, r2.getOutlineLevel()); + assertEquals(1, r3.getOutlineLevel()); + assertEquals(1, r4.getOutlineLevel()); + assertEquals(0, r5.getOutlineLevel()); + + // Save and re-open + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + workbook.write(baos); + workbook = new HSSFWorkbook( + new ByteArrayInputStream(baos.toByteArray()) + ); + + s = workbook.getSheetAt(0); + r1 = s.getRow(0); + r2 = s.getRow(1); + r3 = s.getRow(2); + r4 = s.getRow(3); + r5 = s.getRow(4); + + assertEquals(0, r1.getOutlineLevel()); + assertEquals(0, r2.getOutlineLevel()); + assertEquals(1, r3.getOutlineLevel()); + assertEquals(1, r4.getOutlineLevel()); + assertEquals(0, r5.getOutlineLevel()); + } + + public void testGroupRowsExisting() throws Exception { + String filename = System.getProperty("HSSF.testdata.path"); + filename = filename + "/NoGutsRecords.xls"; + HSSFWorkbook workbook = + new HSSFWorkbook(new FileInputStream(filename)); + + HSSFSheet s = workbook.getSheetAt(0); + HSSFRow r1 = s.getRow(0); + HSSFRow r2 = s.getRow(1); + HSSFRow r3 = s.getRow(2); + HSSFRow r4 = s.getRow(3); + HSSFRow r5 = s.getRow(4); + HSSFRow r6 = s.getRow(5); + + assertEquals(0, r1.getOutlineLevel()); + assertEquals(0, r2.getOutlineLevel()); + assertEquals(0, r3.getOutlineLevel()); + assertEquals(0, r4.getOutlineLevel()); + assertEquals(0, r5.getOutlineLevel()); + assertEquals(0, r6.getOutlineLevel()); + + // This used to complain about lacking guts records + s.groupRow(2, 4); + + assertEquals(0, r1.getOutlineLevel()); + assertEquals(0, r2.getOutlineLevel()); + assertEquals(1, r3.getOutlineLevel()); + assertEquals(1, r4.getOutlineLevel()); + assertEquals(1, r5.getOutlineLevel()); + assertEquals(0, r6.getOutlineLevel()); + + // Save and re-open + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + workbook.write(baos); + workbook = new HSSFWorkbook( + new ByteArrayInputStream(baos.toByteArray()) + ); + + s = workbook.getSheetAt(0); + r1 = s.getRow(0); + r2 = s.getRow(1); + r3 = s.getRow(2); + r4 = s.getRow(3); + r5 = s.getRow(4); + r6 = s.getRow(5); + + assertEquals(0, r1.getOutlineLevel()); + assertEquals(0, r2.getOutlineLevel()); + assertEquals(1, r3.getOutlineLevel()); + assertEquals(1, r4.getOutlineLevel()); + assertEquals(1, r5.getOutlineLevel()); + assertEquals(0, r6.getOutlineLevel()); + } + /** * Test that the ProtectRecord is included when creating or cloning a sheet */