git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1715839 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_14_BETA1
@@ -21,6 +21,7 @@ import java.io.PrintWriter; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.TreeMap; | |||
import org.apache.poi.ddf.EscherRecord; | |||
@@ -61,6 +62,7 @@ import org.apache.poi.ss.usermodel.CellStyle; | |||
import org.apache.poi.ss.usermodel.DataValidation; | |||
import org.apache.poi.ss.usermodel.DataValidationHelper; | |||
import org.apache.poi.ss.usermodel.Row; | |||
import org.apache.poi.ss.util.CellAddress; | |||
import org.apache.poi.ss.util.CellRangeAddress; | |||
import org.apache.poi.ss.util.CellRangeAddressList; | |||
import org.apache.poi.ss.util.CellReference; | |||
@@ -2044,11 +2046,23 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { | |||
* Returns cell comment for the specified row and column | |||
* | |||
* @return cell comment or <code>null</code> if not found | |||
* @deprecated as of 2015-11-23 (circa POI 3.14beta1). Use {@link #getCellComment(CellReference)} instead. | |||
*/ | |||
@Override | |||
public HSSFComment getCellComment(int row, int column) { | |||
return findCellComment(row, column); | |||
} | |||
/** | |||
* Returns cell comment for the specified row and column | |||
* | |||
* @return cell comment or <code>null</code> if not found | |||
*/ | |||
@Override | |||
public HSSFComment getCellComment(CellAddress ref) { | |||
return findCellComment(ref.getRow(), ref.getColumn()); | |||
} | |||
/** | |||
* Get a Hyperlink in this sheet anchored at row, column | |||
* | |||
@@ -2238,6 +2252,43 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet { | |||
return null; | |||
} | |||
/** | |||
* Returns all cell comments on this sheet. | |||
* @return A map of each Comment in the sheet, keyed on the cell address where | |||
* the comment is located. | |||
*/ | |||
@Override | |||
public Map<CellAddress, HSSFComment> getCellComments() { | |||
HSSFPatriarch patriarch = getDrawingPatriarch(); | |||
if (null == patriarch) { | |||
patriarch = createDrawingPatriarch(); | |||
} | |||
Map<CellAddress, HSSFComment> locations = new TreeMap<CellAddress, HSSFComment>(); | |||
findCellCommentLocations(patriarch, locations); | |||
return locations; | |||
} | |||
/** | |||
* Finds all cell comments in this sheet and adds them to the specified locations map | |||
* | |||
* @param container a container that may contain HSSFComments | |||
* @param locations the map to store the HSSFComments in | |||
*/ | |||
private void findCellCommentLocations(HSSFShapeContainer container, Map<CellAddress, HSSFComment> locations) { | |||
for (Object object : container.getChildren()) { | |||
HSSFShape shape = (HSSFShape) object; | |||
if (shape instanceof HSSFShapeGroup) { | |||
findCellCommentLocations((HSSFShapeGroup) shape, locations); | |||
continue; | |||
} | |||
if (shape instanceof HSSFComment) { | |||
HSSFComment comment = (HSSFComment) shape; | |||
if (comment.hasPosition()) { | |||
locations.put(new CellAddress(comment.getRow(), comment.getColumn()), comment); | |||
} | |||
} | |||
} | |||
} | |||
public CellRangeAddress getRepeatingRows() { | |||
return getRepeatingRowsOrColums(true); |
@@ -19,9 +19,12 @@ package org.apache.poi.ss.usermodel; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.apache.poi.hssf.util.PaneInformation; | |||
import org.apache.poi.ss.util.CellAddress; | |||
import org.apache.poi.ss.util.CellRangeAddress; | |||
import org.apache.poi.ss.util.CellReference; | |||
/** | |||
* High level representation of a Excel worksheet. | |||
@@ -890,8 +893,23 @@ public interface Sheet extends Iterable<Row> { | |||
* Returns cell comment for the specified row and column | |||
* | |||
* @return cell comment or <code>null</code> if not found | |||
* @deprecated as of 2015-11-23 (circa POI 3.14beta1). Use {@link #getCellComment(CellReference)} instead. | |||
*/ | |||
Comment getCellComment(int row, int column); | |||
/** | |||
* Returns cell comment for the specified location | |||
* | |||
* @return cell comment or <code>null</code> if not found | |||
*/ | |||
Comment getCellComment(CellAddress ref); | |||
/** | |||
* Returns all cell comments on this sheet. | |||
* @return A map of each Comment in the sheet, keyed on the cell address where | |||
* the comment is located. | |||
*/ | |||
Map<CellAddress, ? extends Comment> getCellComments(); | |||
/** | |||
* Creates the top-level drawing patriarch. |
@@ -19,6 +19,8 @@ package org.apache.poi.ss.util; | |||
import java.util.Locale; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
/** | |||
* <p>This class is a container for POI usermodel row=0 column=0 cell references. | |||
* It is barely a container for these two coordinates. The implementation | |||
@@ -85,6 +87,15 @@ public class CellAddress implements Comparable<CellAddress> { | |||
this(reference.getRow(), reference.getCol()); | |||
} | |||
/** | |||
* Create a new CellAddress object. | |||
* | |||
* @param cell the Cell to get the location of | |||
*/ | |||
public CellAddress(Cell cell) { | |||
this(cell.getRowIndex(), cell.getColumnIndex()); | |||
} | |||
/** | |||
* Get the cell address row | |||
* |
@@ -29,7 +29,6 @@ import java.util.TreeMap; | |||
import org.apache.poi.POIXMLDocumentPart; | |||
import org.apache.poi.openxml4j.opc.PackagePart; | |||
import org.apache.poi.openxml4j.opc.PackageRelationship; | |||
import org.apache.poi.ss.usermodel.Comment; | |||
import org.apache.poi.ss.util.CellAddress; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.xssf.usermodel.XSSFComment; | |||
@@ -188,9 +187,9 @@ public class CommentsTable extends POIXMLDocumentPart { | |||
* @return A map of each Comment in this sheet, keyed on the cell address where | |||
* the comment is located. | |||
*/ | |||
public Map<CellAddress, Comment> getCellComments(){ | |||
public Map<CellAddress, XSSFComment> getCellComments() { | |||
prepareCTCommentCache(); | |||
final TreeMap<CellAddress, Comment> map = new TreeMap<CellAddress, Comment>(); | |||
final TreeMap<CellAddress, XSSFComment> map = new TreeMap<CellAddress, XSSFComment>(); | |||
for (final Entry<CellAddress, CTComment> e: commentRefs.entrySet()) { | |||
map.put(e.getKey(), new XSSFComment(this, e.getValue(), null)); |
@@ -30,7 +30,6 @@ import org.apache.poi.ss.usermodel.AutoFilter; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.CellRange; | |||
import org.apache.poi.ss.usermodel.CellStyle; | |||
import org.apache.poi.ss.usermodel.Comment; | |||
import org.apache.poi.ss.usermodel.DataValidation; | |||
import org.apache.poi.ss.usermodel.DataValidationHelper; | |||
import org.apache.poi.ss.usermodel.Drawing; | |||
@@ -41,8 +40,11 @@ import org.apache.poi.ss.usermodel.Row; | |||
import org.apache.poi.ss.usermodel.Sheet; | |||
import org.apache.poi.ss.usermodel.SheetConditionalFormatting; | |||
import org.apache.poi.ss.usermodel.Workbook; | |||
import org.apache.poi.ss.util.CellAddress; | |||
import org.apache.poi.ss.util.CellRangeAddress; | |||
import org.apache.poi.ss.util.CellReference; | |||
import org.apache.poi.ss.util.SheetUtil; | |||
import org.apache.poi.xssf.usermodel.XSSFComment; | |||
import org.apache.poi.xssf.usermodel.XSSFDataValidation; | |||
import org.apache.poi.xssf.usermodel.XSSFHyperlink; | |||
import org.apache.poi.xssf.usermodel.XSSFSheet; | |||
@@ -1322,10 +1324,33 @@ public class SXSSFSheet implements Sheet, Cloneable | |||
* Returns cell comment for the specified row and column | |||
* | |||
* @return cell comment or <code>null</code> if not found | |||
* @deprecated as of 2015-11-23 (circa POI 3.14beta1). Use {@link #getCellComment(CellReference)} instead. | |||
*/ | |||
public Comment getCellComment(int row, int column) | |||
@Override | |||
public XSSFComment getCellComment(int row, int column) | |||
{ | |||
return _sh.getCellComment(row, column); | |||
return getCellComment(new CellAddress(row, column)); | |||
} | |||
/** | |||
* Returns cell comment for the specified row and column | |||
* | |||
* @return cell comment or <code>null</code> if not found | |||
*/ | |||
@Override | |||
public XSSFComment getCellComment(CellAddress ref) | |||
{ | |||
return _sh.getCellComment(ref); | |||
} | |||
/** | |||
* Returns all cell comments on this sheet. | |||
* @return A map of each Comment in the sheet, keyed on the cell address where | |||
* the comment is located. | |||
*/ | |||
@Override | |||
public Map<CellAddress, XSSFComment> getCellComments() { | |||
return _sh.getCellComments(); | |||
} | |||
/** |
@@ -39,6 +39,7 @@ import org.apache.poi.ss.usermodel.FormulaError; | |||
import org.apache.poi.ss.usermodel.Hyperlink; | |||
import org.apache.poi.ss.usermodel.RichTextString; | |||
import org.apache.poi.ss.usermodel.Row; | |||
import org.apache.poi.ss.util.CellAddress; | |||
import org.apache.poi.ss.util.CellRangeAddress; | |||
import org.apache.poi.ss.util.CellReference; | |||
import org.apache.poi.util.Beta; | |||
@@ -585,7 +586,7 @@ public final class XSSFCell implements Cell { | |||
public String getReference() { | |||
String ref = _cell.getR(); | |||
if(ref == null) { | |||
return new CellReference(this).formatAsString(); | |||
return new CellAddress(this).formatAsString(); | |||
} | |||
return ref; | |||
} | |||
@@ -1029,7 +1030,7 @@ public final class XSSFCell implements Cell { | |||
public void removeCellComment() { | |||
XSSFComment comment = getCellComment(); | |||
if(comment != null){ | |||
String ref = getReference(); | |||
CellAddress ref = new CellAddress(getReference()); | |||
XSSFSheet sh = getSheet(); | |||
sh.getCommentsTable(false).removeComment(ref); | |||
sh.getVMLDrawing(false).removeCommentShape(getRowIndex(), getColumnIndex()); |
@@ -23,6 +23,7 @@ import java.math.BigInteger; | |||
import org.apache.poi.ss.usermodel.ClientAnchor; | |||
import org.apache.poi.ss.usermodel.Comment; | |||
import org.apache.poi.ss.usermodel.RichTextString; | |||
import org.apache.poi.ss.util.CellAddress; | |||
import org.apache.poi.ss.util.CellReference; | |||
import org.apache.poi.xssf.model.CommentsTable; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; | |||
@@ -130,9 +131,9 @@ public class XSSFComment implements Comment { | |||
* @param col the 0-based column of the cell that contains the comment | |||
*/ | |||
public void setColumn(int col) { | |||
String oldRef = _comment.getRef(); | |||
CellAddress oldRef = new CellAddress(_comment.getRef()); | |||
CellReference ref = new CellReference(getRow(), col); | |||
CellAddress ref = new CellAddress(getRow(), col); | |||
_comment.setRef(ref.formatAsString()); | |||
_comments.referenceUpdated(oldRef, _comment); | |||
@@ -154,12 +155,11 @@ public class XSSFComment implements Comment { | |||
* @param row the 0-based row of the cell that contains the comment | |||
*/ | |||
public void setRow(int row) { | |||
String oldRef = _comment.getRef(); | |||
CellAddress oldRef = new CellAddress(_comment.getRef()); | |||
String newRef = | |||
(new CellReference(row, getColumn())).formatAsString(); | |||
_comment.setRef(newRef); | |||
_comments.referenceUpdated(oldRef, _comment); | |||
CellAddress ref = new CellAddress(row, getColumn()); | |||
_comment.setRef(ref.formatAsString()); | |||
_comments.referenceUpdated(oldRef, _comment); | |||
if(_vmlShape != null) { | |||
_vmlShape.getClientDataArray(0).setRowArray(0, |
@@ -33,6 +33,7 @@ import org.apache.poi.openxml4j.opc.PackageRelationship; | |||
import org.apache.poi.openxml4j.opc.TargetMode; | |||
import org.apache.poi.ss.usermodel.ClientAnchor; | |||
import org.apache.poi.ss.usermodel.Drawing; | |||
import org.apache.poi.ss.util.CellAddress; | |||
import org.apache.poi.ss.util.CellReference; | |||
import org.apache.poi.util.Internal; | |||
import org.apache.poi.util.Units; | |||
@@ -316,7 +317,7 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { | |||
ca.getRow2() + ", " + dy2Pixels; | |||
vmlShape.getClientDataArray(0).setAnchorArray(0, position); | |||
} | |||
String ref = new CellReference(ca.getRow1(), ca.getCol1()).formatAsString(); | |||
CellAddress ref = new CellAddress(ca.getRow1(), ca.getCol1()); | |||
if(comments.findCellComment(ref) != null) { | |||
throw new IllegalArgumentException("Multiple cell comments in one cell are not allowed, cell: " + ref); |
@@ -63,6 +63,7 @@ import org.apache.poi.ss.usermodel.IndexedColors; | |||
import org.apache.poi.ss.usermodel.Row; | |||
import org.apache.poi.ss.usermodel.Sheet; | |||
import org.apache.poi.ss.util.AreaReference; | |||
import org.apache.poi.ss.util.CellAddress; | |||
import org.apache.poi.ss.util.CellRangeAddress; | |||
import org.apache.poi.ss.util.CellRangeAddressList; | |||
import org.apache.poi.ss.util.CellReference; | |||
@@ -681,13 +682,34 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
getPane().setActivePane(STPane.Enum.forInt(activePane)); | |||
} | |||
/** | |||
* Return cell comment at row, column, if one exists. Otherwise returns null. | |||
* @row the row where the comment is located | |||
* @column the column where the comment is located | |||
* @return the cell comment, if one exists. Otherwise return null. | |||
* @deprecated as of 2015-11-23 (circa POI 3.14beta1). Use {@link #getCellComment(CellReference)} instead. | |||
*/ | |||
@Override | |||
public XSSFComment getCellComment(int row, int column) { | |||
return getCellComment(new CellAddress(row, column)); | |||
} | |||
/** | |||
* Return cell comment at row, column, if one exists. Otherwise returns null. | |||
* | |||
* @param address the location of the cell comment | |||
* @return the cell comment, if one exists. Otherwise return null. | |||
*/ | |||
@Override | |||
public XSSFComment getCellComment(CellAddress address) { | |||
if (sheetComments == null) { | |||
return null; | |||
} | |||
String ref = new CellReference(row, column).formatAsString(); | |||
final int row = address.getRow(); | |||
final int column = address.getColumn(); | |||
CellAddress ref = new CellAddress(row, column); | |||
CTComment ctComment = sheetComments.getCTComment(ref); | |||
if(ctComment == null) return null; | |||
@@ -696,6 +718,16 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
vml == null ? null : vml.findCommentShape(row, column)); | |||
} | |||
/** | |||
* Returns all cell comments on this sheet. | |||
* @return A map of each Comment in the sheet, keyed on the cell address where | |||
* the comment is located. | |||
*/ | |||
@Override | |||
public Map<CellAddress, XSSFComment> getCellComments() { | |||
return sheetComments.getCellComments(); | |||
} | |||
/** | |||
* Get a Hyperlink in this sheet anchored at row, column | |||
* | |||
@@ -2805,12 +2837,12 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
CTCommentList lst = sheetComments.getCTComments().getCommentList(); | |||
for (CTComment comment : lst.getCommentArray()) { | |||
String strRef = comment.getRef(); | |||
CellReference ref = new CellReference(strRef); | |||
CellAddress ref = new CellAddress(strRef); | |||
// is this comment part of the current row? | |||
if(ref.getRow() == rownum) { | |||
sheetComments.removeComment(strRef); | |||
vml.removeCommentShape(ref.getRow(), ref.getCol()); | |||
sheetComments.removeComment(ref); | |||
vml.removeCommentShape(ref.getRow(), ref.getColumn()); | |||
} | |||
} | |||
} |
@@ -23,10 +23,13 @@ import static org.junit.Assert.*; | |||
import java.io.IOException; | |||
import java.util.Iterator; | |||
import java.util.Map; | |||
import java.util.Map.Entry; | |||
import org.apache.poi.hssf.util.PaneInformation; | |||
import org.apache.poi.ss.ITestDataProvider; | |||
import org.apache.poi.ss.SpreadsheetVersion; | |||
import org.apache.poi.ss.util.CellAddress; | |||
import org.apache.poi.ss.util.CellRangeAddress; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
@@ -1018,13 +1021,54 @@ public abstract class BaseTestSheet { | |||
comment.setAuthor("test C10 author"); | |||
cell.setCellComment(comment); | |||
assertNotNull(sheet.getCellComment(9, 2)); | |||
assertEquals("test C10 author", sheet.getCellComment(9, 2).getAuthor()); | |||
CellAddress ref = new CellAddress(9, 2); | |||
assertNotNull(sheet.getCellComment(ref)); | |||
assertEquals("test C10 author", sheet.getCellComment(ref).getAuthor()); | |||
assertNotNull(_testDataProvider.writeOutAndReadBack(workbook)); | |||
workbook.close(); | |||
} | |||
@Test | |||
public void getCellComments() throws IOException { | |||
Workbook workbook = _testDataProvider.createWorkbook(); | |||
Sheet sheet = workbook.createSheet("TEST"); | |||
Drawing dg = sheet.createDrawingPatriarch(); | |||
int nRows = 5; | |||
int nCols = 6; | |||
for (int r=0; r<nRows; r++) { | |||
sheet.createRow(r); | |||
// Create columns in reverse order | |||
for (int c=nCols-1; c>=0; c--) { | |||
Comment comment = dg.createCellComment(workbook.getCreationHelper().createClientAnchor()); | |||
Cell cell = sheet.getRow(r).createCell(c); | |||
comment.setAuthor("Author " + r); | |||
RichTextString text = workbook.getCreationHelper().createRichTextString("Test comment at row=" + r + ", column=" + c); | |||
comment.setString(text); | |||
cell.setCellComment(comment); | |||
} | |||
} | |||
Workbook wb = _testDataProvider.writeOutAndReadBack(workbook); | |||
Sheet sh = wb.getSheet("TEST"); | |||
Map<CellAddress, ? extends Comment> cellComments = sh.getCellComments(); | |||
assertEquals(nRows*nCols, cellComments.size()); | |||
for (Entry<CellAddress, ? extends Comment> e : cellComments.entrySet()) { | |||
CellAddress ref = e.getKey(); | |||
Comment aComment = e.getValue(); | |||
assertEquals("Author " + ref.getRow(), aComment.getAuthor()); | |||
String text = "Test comment at row=" + ref.getRow() + ", column=" + ref.getColumn(); | |||
assertEquals(text, aComment.getString().getString()); | |||
} | |||
workbook.close(); | |||
wb.close(); | |||
} | |||
@Test |