diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 209d8ae8d8..0891579ed8 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 47924 - fixed logic for matching cells and comments in HSSFCell.getCellComment() 47942 - added implementation of protection features to XLSX and DOCX files 48070 - preserve leading and trailing white spaces in XSSFRichTextString 48044 - added implementation for CountBlank function diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java index 999fa287dc..701b7ce746 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCell.java @@ -1054,7 +1054,8 @@ public class HSSFCell implements Cell { protected static HSSFComment findCellComment(Sheet sheet, int row, int column) { // TODO - optimise this code by searching backwards, find NoteRecord first, quit if not found. Find one TXO by id HSSFComment comment = null; - ArrayList noteTxo = new ArrayList(); + Map noteTxo = + new HashMap(); int i = 0; for (Iterator it = sheet.getRecords().iterator(); it.hasNext();) { RecordBase rec = it.next(); @@ -1062,7 +1063,7 @@ public class HSSFCell implements Cell { NoteRecord note = (NoteRecord) rec; if (note.getRow() == row && note.getColumn() == column) { if(i < noteTxo.size()) { - TextObjectRecord txo = noteTxo.get(i); + TextObjectRecord txo = noteTxo.get(note.getShapeId()); comment = new HSSFComment(note, txo); comment.setRow(note.getRow()); comment.setColumn((short) note.getColumn()); @@ -1081,12 +1082,12 @@ public class HSSFCell implements Cell { if (sub instanceof CommonObjectDataSubRecord) { CommonObjectDataSubRecord cmo = (CommonObjectDataSubRecord) sub; if (cmo.getObjectType() == CommonObjectDataSubRecord.OBJECT_TYPE_COMMENT) { - //find the next TextObjectRecord which holds the comment's text - //the order of TXO matches the order of NoteRecords: i-th TXO record corresponds to the i-th NoteRecord + //map ObjectId and corresponding TextObjectRecord, + //it will be used to match NoteRecord and TextObjectRecord while (it.hasNext()) { rec = it.next(); if (rec instanceof TextObjectRecord) { - noteTxo.add((TextObjectRecord) rec); + noteTxo.put(cmo.getObjectId(), (TextObjectRecord) rec); break; } } diff --git a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFComment.java b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFComment.java index 7014cb5149..bb4707b321 100644 --- a/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFComment.java +++ b/src/testcases/org/apache/poi/hssf/usermodel/TestHSSFComment.java @@ -23,6 +23,10 @@ import java.io.IOException; import junit.framework.TestCase; import org.apache.poi.hssf.HSSFTestDataSamples; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Comment; +import org.apache.poi.ss.util.CellReference; /** * Tests TestHSSFCellComment. @@ -215,4 +219,39 @@ public final class TestHSSFComment extends TestCase { // wb.write(fout); // fout.close(); } + + /** + * HSSFCell#findCellComment should NOT rely on the order of records + * when matching cells and their cell comments. The correct algorithm is to map + */ + public static void test47924() { + HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("47924.xls"); + HSSFSheet sheet = wb.getSheetAt(0); + HSSFCell cell; + HSSFComment comment; + + cell = sheet.getRow(0).getCell(0); + comment = cell.getCellComment(); + assertEquals("a1", comment.getString().getString()); + + cell = sheet.getRow(1).getCell(0); + comment = cell.getCellComment(); + assertEquals("a2", comment.getString().getString()); + + cell = sheet.getRow(2).getCell(0); + comment = cell.getCellComment(); + assertEquals("a3", comment.getString().getString()); + + cell = sheet.getRow(2).getCell(2); + comment = cell.getCellComment(); + assertEquals("c3", comment.getString().getString()); + + cell = sheet.getRow(4).getCell(1); + comment = cell.getCellComment(); + assertEquals("b5", comment.getString().getString()); + + cell = sheet.getRow(5).getCell(2); + comment = cell.getCellComment(); + assertEquals("c6", comment.getString().getString()); + } } diff --git a/test-data/spreadsheet/47924.xls b/test-data/spreadsheet/47924.xls new file mode 100644 index 0000000000..287f17b6e8 Binary files /dev/null and b/test-data/spreadsheet/47924.xls differ