git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@884918 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_6
@@ -43,7 +43,7 @@ | |||
<li><link href="#TextExtraction">Text Extraction</link></li> | |||
<li><link href="#Alignment">Aligning cells</link></li> | |||
<li><link href="#Borders">Working with borders</link></li> | |||
<li><link href="#FrillsAndFills">Fills and color</link></li> | |||
<li><link href="#FillsAndFrills">Fills and color</link></li> | |||
<li><link href="#MergedCells">Merging cells</link></li> | |||
<li><link href="#WorkingWithFonts">Working with fonts</link></li> | |||
<li><link href="#CustomColors">Custom colors</link></li> | |||
@@ -1328,123 +1328,36 @@ Examples: | |||
</source> | |||
</section> | |||
<anchor id="CellComments"/> | |||
<section><title>Cell Comments - HSSF and XSSF (slight differences though)</title> | |||
<section><title>Cell Comments - HSSF and XSSF</title> | |||
<p> | |||
In HSSF Excel, cell comments were added to the file format as a bit of a | |||
cludge. As such, comments are a kind of a text shape, so inserting a | |||
comment is very similar to placing a text box in a worksheet. | |||
A comment is a rich text note that is attached to & | |||
associated with a cell, separate from other cell content. | |||
Comment content is stored separate from the cell, and is displayed in a drawing object (like a text box) | |||
that is separate from, but associated with, a cell | |||
</p> | |||
<p> | |||
In XSSF Excel, cell comments are more cleanly done. Each Sheet has a list | |||
of its comments, and they can be added much like other cell properties. | |||
</p> | |||
<p> | |||
Once you have created your comment, how you use it is very similar between | |||
HSSF and XSSF. It is only the creation of a new comment where things | |||
differ. | |||
</p> | |||
<p> | |||
For HSSF, the process is: | |||
</p> | |||
<source> | |||
HSSFWorkbook wb = new HSSFWorkbook(); | |||
HSSFSheet sheet = wb.createSheet("Cell comments in POI HSSF"); | |||
CreationHelper createHelper = wb.getCreationHelper(); | |||
// Create the drawing patriarch. This is the top level container for all shapes including cell comments. | |||
HSSFPatriarch patr = sheet.createDrawingPatriarch(); | |||
// Create a cell in row 3 | |||
Cell cell1 = sheet.createRow(3).createCell((short)1); | |||
cell1.setCellValue(new HSSFRichTextString("Hello, World")); | |||
// Anchor defines size and position of the comment in worksheet | |||
Comment comment1 = patr.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short)4, 2, (short) 6, 5)); | |||
// set text in the comment | |||
comment1.setString(createHelper.createRichTextString("We can set comments in POI")); | |||
// set comment author. | |||
// you can see it in the status bar when moving mouse over the commented cell | |||
comment1.setAuthor("Apache Software Foundation"); | |||
// The first way to assign comment to a cell is via Cell.setCellComment method | |||
cell1.setCellComment(comment1); | |||
// Create another cell in row 6 | |||
Cell cell2 = sheet.createRow(6).createCell((short)1); | |||
cell2.setCellValue(36.6); | |||
// And a comment for it | |||
HSSFComment comment2 = patr.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short)4, 8, (short) 6, 11)); | |||
// Modify background color of the comment | |||
comment2.setFillColor(204, 236, 255); | |||
HSSFRichTextString string = new HSSFRichTextString("Normal body temperature"); | |||
// Apply custom font to the text in the comment | |||
HSSFFont font = wb.createFont(); | |||
font.setFontName("Arial"); | |||
font.setFontHeightInPoints((short)10); | |||
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); | |||
font.setColor(HSSFColor.RED.index); | |||
string.applyFont(font); | |||
comment2.setString(string); | |||
// By default comments are hidden. This one is always visible. | |||
comment2.setVisible(true); | |||
comment2.setAuthor("Bill Gates"); | |||
/** | |||
* The second way to assign comment to a cell is to implicitly specify its row and column. | |||
* Note, it is possible to set row and column of a non-existing cell. | |||
* It works, the comment is visible. | |||
*/ | |||
comment2.setRow(6); | |||
comment2.setColumn((short)1); | |||
FileOutputStream out = new FileOutputStream("poi_comment.xls"); | |||
wb.write(out); | |||
out.close(); | |||
</source> | |||
<p> | |||
For XSSF, the simpler process is: | |||
</p> | |||
<source> | |||
XSSFWorkbook wb = new XSSFWorkbook(); | |||
XSSFSheet sheet = wb.createSheet("Cell comments in POI XSSF"); | |||
CreationHelper createHelper = wb.getCreationHelper(); | |||
// Create a cell in row 3 | |||
Cell cell1 = sheet.createRow(3).createCell((short)1); | |||
cell1.setCellValue(new XSSFRichTextString("Hello, World")); | |||
// Create a comment, and set the text and author | |||
// (You can see the author in the status bar when moving mouse | |||
// over the commented cell) | |||
Comment comment1 = sheet.createComment(); | |||
comment1.setString(createHelper.createRichTextString("We can set comments in POI")); | |||
comment1.setAuthor("Apache Software Foundation"); | |||
// The first way to assign comment to a cell is via Cell.setCellComment method | |||
cell1.setCellComment(comment1); | |||
<source> | |||
Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook(); | |||
CreationHelper factory = wb.getCreationHelper(); | |||
// The other way is to set the row and column | |||
// This could point to a cell that isn't defined, and the comment will | |||
// will still show up all the same | |||
Comment comment2 = sheet.createComment(); | |||
comment2.setString(createHelper.createRichTextString("Comment for missing cell")); | |||
comment2.setAuthor("Apache POI"); | |||
comment2.setRow(11); | |||
comment2.setColumn(1); | |||
Sheet sheet = wb.createSheet(); | |||
Cell cell = sheet.createRow(3).createCell(5); | |||
cell.setCellValue("F4"); | |||
Drawing drawing = sheet.createDrawingPatriarch(); | |||
// Write out | |||
FileOutputStream out = new FileOutputStream("poi_comment.xls"); | |||
ClientAnchor anchor = factory.createClientAnchor(); | |||
Comment comment = drawing.createCellComment(anchor); | |||
RichTextString str = factory.createRichTextString("Hello, World!"); | |||
comment.setString(str); | |||
comment.setAuthor("Apache POI"); | |||
//assign the comment to the cell | |||
cell.setCellComment(comment); | |||
String fname = "comment-xssf.xls"; | |||
if(wb instanceof XSSFWorkbook) fname += "x"; | |||
FileOutputStream out = new FileOutputStream(fname); | |||
wb.write(out); | |||
out.close(); | |||
</source> |
@@ -34,7 +34,10 @@ | |||
<changes> | |||
<release version="3.6-beta1" date="2009-??-??"> | |||
<action dev="POI-DEVELOPERS" type="add">Add support for creating SummaryInformation and DocumentSummaryInformation properties on POIDocuments that don't have them, via POIDocument.createInformationProperties()</action> | |||
<action dev="POI-DEVELOPERS" type="fix">47188 - avoid corruption of workbook when adding cell comments </action> | |||
<action dev="POI-DEVELOPERS" type="fix">48106 - improved work with cell comments in XSSF</action> | |||
<action dev="POI-DEVELOPERS" type="add">Add support for creating SummaryInformation and DocumentSummaryInformation properties | |||
on POIDocuments that don't have them, via POIDocument.createInformationProperties()</action> | |||
<action dev="POI-DEVELOPERS" type="fix">48180 - be more forgiving of short chart records, which skip some unused fields</action> | |||
<action dev="POI-DEVELOPERS" type="fix">48274 - fix erronious wrapping of byte colours in HSSFPalette.findSimilarColor</action> | |||
<action dev="POI-DEVELOPERS" type="fix">48269 - fix fetching of error codes from XSSF formula cells</action> |
@@ -0,0 +1,80 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.xssf.usermodel.examples; | |||
import org.apache.poi.ss.usermodel.*; | |||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |||
import java.io.IOException; | |||
import java.io.FileOutputStream; | |||
/** | |||
* Demonstrates how to work with excel cell comments. | |||
* | |||
* <p> | |||
* Excel comment is a kind of a text shape, | |||
* so inserting a comment is very similar to placing a text box in a worksheet | |||
* </p> | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public class CellComments { | |||
public static void main(String[] args) throws IOException { | |||
Workbook wb = new XSSFWorkbook(); | |||
CreationHelper factory = wb.getCreationHelper(); | |||
Sheet sheet = wb.createSheet(); | |||
Cell cell1 = sheet.createRow(3).createCell(5); | |||
cell1.setCellValue("F4"); | |||
Drawing drawing = sheet.createDrawingPatriarch(); | |||
ClientAnchor anchor = factory.createClientAnchor(); | |||
Comment comment1 = drawing.createCellComment(anchor); | |||
RichTextString str1 = factory.createRichTextString("Hello, World!"); | |||
comment1.setString(str1); | |||
comment1.setAuthor("Apache POI"); | |||
cell1.setCellComment(comment1); | |||
Cell cell2 = sheet.createRow(2).createCell(2); | |||
cell2.setCellValue("C3"); | |||
Comment comment2 = drawing.createCellComment(anchor); | |||
RichTextString str2 = factory.createRichTextString("XSSF can set cell comments"); | |||
//apply custom font to the text in the comment | |||
Font font = wb.createFont(); | |||
font.setFontName("Arial"); | |||
font.setFontHeightInPoints((short)14); | |||
font.setBoldweight(Font.BOLDWEIGHT_BOLD); | |||
font.setColor(IndexedColors.RED.getIndex()); | |||
str2.applyFont(font); | |||
comment2.setString(str2); | |||
comment2.setAuthor("Apache POI"); | |||
comment2.setColumn(2); | |||
comment2.setRow(2); | |||
String fname = "comments.xlsx"; | |||
FileOutputStream out = new FileOutputStream(fname); | |||
wb.write(out); | |||
out.close(); | |||
} | |||
} |
@@ -127,12 +127,19 @@ public class HSSFComment extends HSSFTextbox implements Comment { | |||
* | |||
* @param col the 0-based column of the cell that contains the comment | |||
*/ | |||
public void setColumn(short col) { | |||
public void setColumn(int col) { | |||
if(_note != null) { | |||
_note.setColumn(col); | |||
} | |||
_col = col; | |||
} | |||
/** | |||
* @deprecated (Nov 2009) use {@link HSSFComment#setColumn(int)} } | |||
*/ | |||
@Deprecated | |||
public void setColumn(short col) { | |||
setColumn((int)col); | |||
} | |||
/** | |||
* Name of the original comment author |
@@ -157,6 +157,11 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing { | |||
return shape; | |||
} | |||
@Override | |||
public HSSFComment createCellComment(ClientAnchor anchor){ | |||
return createComment((HSSFAnchor)anchor); | |||
} | |||
/** | |||
* Returns a list of all shapes contained by the patriarch. | |||
*/ |
@@ -351,6 +351,11 @@ public interface Cell { | |||
*/ | |||
Comment getCellComment(); | |||
/** | |||
* Removes the comment for this cell, if there is one. | |||
*/ | |||
void removeCellComment(); | |||
/** | |||
* Returns hyperlink associated with this cell | |||
* |
@@ -59,7 +59,7 @@ public interface Comment { | |||
* | |||
* @param col the 0-based column of the cell that contains the comment | |||
*/ | |||
void setColumn(short col); | |||
void setColumn(int col); | |||
/** | |||
* Name of the original comment author |
@@ -21,4 +21,6 @@ package org.apache.poi.ss.usermodel; | |||
*/ | |||
public interface Drawing { | |||
Picture createPicture(ClientAnchor anchor, int pictureIndex); | |||
Comment createCellComment(ClientAnchor anchor); | |||
} |
@@ -24,7 +24,6 @@ import org.apache.poi.ss.util.CellReference; | |||
import org.apache.poi.xssf.usermodel.XSSFComment; | |||
import org.apache.poi.POIXMLDocumentPart; | |||
import org.apache.xmlbeans.XmlException; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAuthors; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments; | |||
@@ -33,11 +32,13 @@ import org.apache.poi.openxml4j.opc.PackagePart; | |||
import org.apache.poi.openxml4j.opc.PackageRelationship; | |||
public class CommentsTable extends POIXMLDocumentPart { | |||
protected CTComments comments; | |||
private CTComments comments; | |||
public CommentsTable() { | |||
super(); | |||
comments = CTComments.Factory.newInstance(); | |||
comments.addNewCommentList(); | |||
comments.addNewAuthors().addAuthor(""); | |||
} | |||
public CommentsTable(PackagePart part, PackageRelationship rel) throws IOException { | |||
@@ -70,62 +71,60 @@ public class CommentsTable extends POIXMLDocumentPart { | |||
public int getNumberOfComments() { | |||
return comments.getCommentList().sizeOfCommentArray(); | |||
} | |||
public int getNumberOfAuthors() { | |||
return getCommentsAuthors().sizeOfAuthorArray(); | |||
return comments.getAuthors().sizeOfAuthorArray(); | |||
} | |||
public String getAuthor(long authorId) { | |||
return getCommentsAuthors().getAuthorArray((int)authorId); | |||
return comments.getAuthors().getAuthorArray((int)authorId); | |||
} | |||
public int findAuthor(String author) { | |||
for (int i = 0 ; i < getCommentsAuthors().sizeOfAuthorArray() ; i++) { | |||
if (getCommentsAuthors().getAuthorArray(i).equals(author)) { | |||
for (int i = 0 ; i < comments.getAuthors().sizeOfAuthorArray() ; i++) { | |||
if (comments.getAuthors().getAuthorArray(i).equals(author)) { | |||
return i; | |||
} | |||
} | |||
return addNewAuthor(author); | |||
} | |||
public XSSFComment findCellComment(int row, int column) { | |||
return findCellComment( | |||
(new CellReference(row, column)).formatAsString() ); | |||
public XSSFComment findCellComment(String cellRef) { | |||
CTComment ct = getCTComment(cellRef); | |||
return ct == null ? null : new XSSFComment(this, ct, null); | |||
} | |||
public XSSFComment findCellComment(String cellRef) { | |||
for (CTComment comment : getCommentsList().getCommentArray()) { | |||
public CTComment getCTComment(String cellRef) { | |||
for (CTComment comment : comments.getCommentList().getCommentArray()) { | |||
if (cellRef.equals(comment.getRef())) { | |||
return new XSSFComment(this, comment); | |||
return comment; | |||
} | |||
} | |||
return null; | |||
} | |||
/** | |||
* Generates a new XSSFComment, associated with the | |||
* current comments list. | |||
*/ | |||
public XSSFComment addComment() { | |||
return new XSSFComment(this, getCommentsList().addNewComment()); | |||
} | |||
private CTCommentList getCommentsList() { | |||
if (comments.getCommentList() == null) { | |||
comments.addNewCommentList(); | |||
} | |||
return comments.getCommentList(); | |||
public CTComment newComment() { | |||
CTComment ct = comments.getCommentList().addNewComment(); | |||
ct.setRef("A1"); | |||
ct.setAuthorId(0); | |||
return ct; | |||
} | |||
private CTAuthors getCommentsAuthors() { | |||
if (comments.getAuthors() == null) { | |||
comments.addNewAuthors(); | |||
public boolean removeComment(String cellRef) { | |||
CTCommentList lst = comments.getCommentList(); | |||
if(lst != null) for(int i=0; i < lst.sizeOfCommentArray(); i++) { | |||
CTComment comment = lst.getCommentArray(i); | |||
if (cellRef.equals(comment.getRef())) { | |||
lst.removeComment(i); | |||
return true; | |||
} | |||
} | |||
return comments.getAuthors(); | |||
return false; | |||
} | |||
private int addNewAuthor(String author) { | |||
int index = getCommentsAuthors().sizeOfAuthorArray(); | |||
getCommentsAuthors().insertAuthor(index, author); | |||
int index = comments.getAuthors().sizeOfAuthorArray(); | |||
comments.getAuthors().insertAuthor(index, author); | |||
return index; | |||
} | |||
@@ -807,11 +807,29 @@ public final class XSSFCell implements Cell { | |||
* Assign a comment to this cell. If the supplied comment is null, | |||
* the comment for this cell will be removed. | |||
* | |||
* @param comment comment associated with this cell | |||
* @param comment the XSSFComment associated with this cell | |||
*/ | |||
public void setCellComment(Comment comment) { | |||
String cellRef = new CellReference(_row.getRowNum(), getColumnIndex()).formatAsString(); | |||
getSheet().setCellComment(cellRef, (XSSFComment)comment); | |||
if(comment == null) { | |||
removeCellComment(); | |||
return; | |||
} | |||
comment.setRow(getRowIndex()); | |||
comment.setColumn(getColumnIndex()); | |||
} | |||
/** | |||
* Removes the comment for this cell, if there is one. | |||
*/ | |||
public void removeCellComment() { | |||
XSSFComment comment = getCellComment(); | |||
if(comment != null){ | |||
String ref = _cell.getR(); | |||
XSSFSheet sh = getSheet(); | |||
sh.getCommentsTable(false).removeComment(ref); | |||
sh.getVMLDrawing(false).removeCommentShape(getRowIndex(), getColumnIndex()); | |||
} | |||
} | |||
/** |
@@ -217,4 +217,8 @@ public final class XSSFClientAnchor extends XSSFAnchor implements ClientAnchor { | |||
return anchorType; | |||
} | |||
public boolean isSet(){ | |||
return !(cell1.getCol() == 0 && cell2.getCol() == 0 && | |||
cell1.getRow() == 0 && cell2.getRow() == 0); | |||
} | |||
} |
@@ -20,84 +20,149 @@ import org.apache.poi.ss.usermodel.Comment; | |||
import org.apache.poi.ss.usermodel.RichTextString; | |||
import org.apache.poi.ss.util.CellReference; | |||
import org.apache.poi.xssf.model.CommentsTable; | |||
import org.apache.poi.xssf.usermodel.helpers.RichTextStringHelper; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst; | |||
import schemasMicrosoftComVml.CTShape; | |||
import java.math.BigInteger; | |||
public class XSSFComment implements Comment { | |||
private CTComment comment; | |||
private CommentsTable comments; | |||
private final CTComment _comment; | |||
private final CommentsTable _comments; | |||
private final CTShape _vmlShape; | |||
/** | |||
* cached reference to the string with the comment text | |||
*/ | |||
private XSSFRichTextString _str; | |||
/** | |||
/** | |||
* Creates a new XSSFComment, associated with a given | |||
* low level comment object. | |||
* If, as an end user, you want a new XSSFComment | |||
* object, the please ask your sheet for one. | |||
*/ | |||
public XSSFComment(CommentsTable comments, CTComment comment) { | |||
this.comment = comment; | |||
this.comments = comments; | |||
public XSSFComment(CommentsTable comments, CTComment comment, CTShape vmlShape) { | |||
_comment = comment; | |||
_comments = comments; | |||
_vmlShape = vmlShape; | |||
} | |||
public String getAuthor() { | |||
return comments.getAuthor((int)comment.getAuthorId()); | |||
/** | |||
* | |||
* @return Name of the original comment author. Default value is blank. | |||
*/ | |||
public String getAuthor() { | |||
return _comments.getAuthor((int) _comment.getAuthorId()); | |||
} | |||
/** | |||
* Name of the original comment author. Default value is blank. | |||
* | |||
* @param author the name of the original author of the comment | |||
*/ | |||
public void setAuthor(String author) { | |||
_comment.setAuthorId( | |||
_comments.findAuthor(author) | |||
); | |||
} | |||
/** | |||
* @return the 0-based column of the cell that the comment is associated with. | |||
*/ | |||
public int getColumn() { | |||
return (new CellReference(comment.getRef())).getCol(); | |||
return new CellReference(_comment.getRef()).getCol(); | |||
} | |||
/** | |||
* @return the 0-based row index of the cell that the comment is associated with. | |||
*/ | |||
public int getRow() { | |||
return (new CellReference(comment.getRef())).getRow(); | |||
return new CellReference(_comment.getRef()).getRow(); | |||
} | |||
public boolean isVisible() { | |||
// TODO Auto-generated method stub | |||
return true; | |||
/** | |||
* @return whether the comment is visible | |||
*/ | |||
public boolean isVisible() { | |||
boolean visible = false; | |||
if(_vmlShape != null){ | |||
String style = _vmlShape.getStyle(); | |||
visible = style != null && style.indexOf("visibility:visible") != -1; | |||
} | |||
return visible; | |||
} | |||
public void setAuthor(String author) { | |||
comment.setAuthorId( | |||
comments.findAuthor(author) | |||
); | |||
} | |||
/** | |||
* @param visible whether the comment is visible | |||
*/ | |||
public void setVisible(boolean visible) { | |||
if(_vmlShape != null){ | |||
String style; | |||
if(visible) style = "position:absolute;visibility:visible"; | |||
else style = "position:absolute;visibility:hidden"; | |||
_vmlShape.setStyle(style); | |||
} | |||
} | |||
public void setColumn(short col) { | |||
initializeRef(); | |||
String newRef = | |||
(new CellReference(getRow(), col)).formatAsString(); | |||
comment.setRef(newRef); | |||
} | |||
private void initializeRef() { | |||
if (comment.getRef() == null) { | |||
comment.setRef("A1"); | |||
} | |||
/** | |||
* Set the column of the cell that contains the comment | |||
* | |||
* @param col the 0-based column of the cell that contains the comment | |||
*/ | |||
public void setColumn(int col) { | |||
CellReference ref = new CellReference(getRow(), col); | |||
_comment.setRef(ref.formatAsString()); | |||
if(_vmlShape != null) _vmlShape.getClientDataArray(0).setColumnArray(0, new BigInteger(String.valueOf(col))); | |||
} | |||
/** | |||
* Set the row of the cell that contains the comment | |||
* | |||
* @param row the 0-based row of the cell that contains the comment | |||
*/ | |||
public void setRow(int row) { | |||
initializeRef(); | |||
String newRef = | |||
(new CellReference(row, getColumn())).formatAsString(); | |||
comment.setRef(newRef); | |||
} | |||
_comment.setRef(newRef); | |||
if(_vmlShape != null) _vmlShape.getClientDataArray(0).setRowArray(0, new BigInteger(String.valueOf(row))); | |||
} | |||
public RichTextString getString() { | |||
return RichTextStringHelper.convertFromRst(comment.getText()); | |||
/** | |||
* @return the rich text string of the comment | |||
*/ | |||
public XSSFRichTextString getString() { | |||
if(_str == null) { | |||
CTRst rst = _comment.getText(); | |||
if(rst != null) _str = new XSSFRichTextString(_comment.getText()); | |||
} | |||
return _str; | |||
} | |||
/** | |||
* Sets the rich text string used by this comment. | |||
* | |||
* @param string the XSSFRichTextString used by this object. | |||
*/ | |||
public void setString(RichTextString string) { | |||
CTRst text = comment.addNewText(); | |||
RichTextStringHelper.convertToRst(string, text); | |||
if(!(string instanceof XSSFRichTextString)){ | |||
throw new IllegalArgumentException("Only XSSFRichTextString argument is supported"); | |||
} | |||
_str = (XSSFRichTextString)string; | |||
_comment.setText(_str.getCTRst()); | |||
} | |||
public void setString(String string) { | |||
RichTextString richTextString = new XSSFRichTextString(string); | |||
setString(richTextString); | |||
setString(new XSSFRichTextString(string)); | |||
} | |||
public void setVisible(boolean visible) { | |||
// TODO Auto-generated method stub | |||
} | |||
/** | |||
* @return the xml bean holding this comment's properties | |||
*/ | |||
protected CTComment getCTComment(){ | |||
return _comment; | |||
} | |||
protected CTShape getCTShape(){ | |||
return _vmlShape; | |||
} | |||
} |
@@ -25,6 +25,7 @@ import java.util.Map; | |||
import javax.xml.namespace.QName; | |||
import org.apache.poi.POIXMLDocumentPart; | |||
import org.apache.poi.xssf.model.CommentsTable; | |||
import org.apache.poi.openxml4j.opc.PackagePart; | |||
import org.apache.poi.openxml4j.opc.PackagePartName; | |||
import org.apache.poi.openxml4j.opc.PackageRelationship; | |||
@@ -233,6 +234,35 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { | |||
return shape; | |||
} | |||
/** | |||
* Creates a cell comment. | |||
* | |||
* @param anchor the client anchor describes how this comment is attached | |||
* to the sheet. | |||
* @return the newly created comment. | |||
*/ | |||
@Override | |||
public XSSFComment createCellComment(ClientAnchor anchor) | |||
{ | |||
XSSFClientAnchor ca = (XSSFClientAnchor)anchor; | |||
XSSFSheet sheet = (XSSFSheet)getParent(); | |||
//create comments and vmlDrawing parts if they don't exist | |||
CommentsTable comments = sheet.getCommentsTable(true); | |||
XSSFVMLDrawing vml = sheet.getVMLDrawing(true); | |||
schemasMicrosoftComVml.CTShape vmlShape = vml.newCommentShape(); | |||
if(ca.isSet()){ | |||
String position = | |||
ca.getCol1() + ", 0, " + ca.getRow1() + ", 0, " + | |||
ca.getCol2() + ", 0, " + ca.getRow2() + ", 0"; | |||
vmlShape.getClientDataArray(0).setAnchorArray(0, position); | |||
} | |||
XSSFComment shape = new XSSFComment(comments, comments.newComment(), vmlShape); | |||
shape.setColumn(ca.getCol1()); | |||
shape.setRow(ca.getRow1()); | |||
return shape; | |||
} | |||
/** | |||
* Create and initialize a CTTwoCellAnchor that anchors a shape against top-left and bottom-right cells. | |||
* |
@@ -118,7 +118,7 @@ public final class XSSFRelation extends POIXMLRelation { | |||
"application/vnd.openxmlformats-officedocument.vmlDrawing", | |||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing", | |||
"/xl/drawings/vmlDrawing#.vml", | |||
null | |||
XSSFVMLDrawing.class | |||
); | |||
public static final XSSFRelation CUSTOM_XML_MAPPINGS = new XSSFRelation( |
@@ -54,38 +54,7 @@ import org.apache.poi.xssf.usermodel.helpers.XSSFRowShifter; | |||
import org.apache.xmlbeans.XmlException; | |||
import org.apache.xmlbeans.XmlOptions; | |||
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBreak; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOutlinePr; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageBreak; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetUpPr; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPane; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPrintOptions; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSelection; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetPr; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetView; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPaneState; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; | |||
/** | |||
* High level representation of a SpreadsheetML worksheet. | |||
@@ -351,6 +320,48 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
return drawing; | |||
} | |||
/** | |||
* Get VML drawing for this sheet (aka 'legacy' drawig) | |||
* | |||
* @param autoCreate if true, then a new VML drawing part is created | |||
* | |||
* @return the VML drawing of <code>null</code> if the drawing was not found and autoCreate=false | |||
*/ | |||
protected XSSFVMLDrawing getVMLDrawing(boolean autoCreate) { | |||
XSSFVMLDrawing drawing = null; | |||
CTLegacyDrawing ctDrawing = worksheet.getLegacyDrawing(); | |||
if(ctDrawing == null) { | |||
if(autoCreate) { | |||
//drawingNumber = #drawings.size() + 1 | |||
int drawingNumber = getPackagePart().getPackage().getPartsByContentType(XSSFRelation.VML_DRAWINGS.getContentType()).size() + 1; | |||
drawing = (XSSFVMLDrawing)createRelationship(XSSFRelation.VML_DRAWINGS, XSSFFactory.getInstance(), drawingNumber); | |||
String relId = drawing.getPackageRelationship().getId(); | |||
//add CTLegacyDrawing element which indicates that this sheet contains drawing components built on the drawingML platform. | |||
//The relationship Id references the part containing the drawing definitions. | |||
ctDrawing = worksheet.addNewLegacyDrawing(); | |||
ctDrawing.setId(relId); | |||
} | |||
} else { | |||
//search the referenced drawing in the list of the sheet's relations | |||
for(POIXMLDocumentPart p : getRelations()){ | |||
if(p instanceof XSSFVMLDrawing) { | |||
XSSFVMLDrawing dr = (XSSFVMLDrawing)p; | |||
String drId = dr.getPackageRelationship().getId(); | |||
if(drId.equals(ctDrawing.getId())){ | |||
drawing = dr; | |||
break; | |||
} | |||
break; | |||
} | |||
} | |||
if(drawing == null){ | |||
logger.log(POILogger.ERROR, "Can't find VML drawing with id=" + ctDrawing.getId() + " in the list of the sheet's relationships"); | |||
} | |||
} | |||
return drawing; | |||
} | |||
/** | |||
* Creates a split (freezepane). Any existing freezepane or split pane is overwritten. | |||
* @param colSplit Horizonatal position of split. | |||
@@ -392,12 +403,14 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
/** | |||
* Creates a new comment for this sheet. You still | |||
* need to assign it to a cell though | |||
* | |||
* @deprecated since Nov 2009 this method is not compatible with the common SS interfaces, | |||
* use {@link org.apache.poi.xssf.usermodel.XSSFDrawing#createCellComment | |||
* (org.apache.poi.ss.usermodel.ClientAnchor)} instead | |||
*/ | |||
@Deprecated | |||
public XSSFComment createComment() { | |||
if (sheetComments == null) { | |||
sheetComments = (CommentsTable)createRelationship(XSSFRelation.SHEET_COMMENTS, XSSFFactory.getInstance(), (int)sheet.getSheetId()); | |||
} | |||
return sheetComments.addComment(); | |||
return createDrawingPatriarch().createCellComment(new XSSFClientAnchor()); | |||
} | |||
/** | |||
@@ -438,7 +451,14 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
if (sheetComments == null) { | |||
return null; | |||
} | |||
return sheetComments.findCellComment(row, column); | |||
String ref = new CellReference(row, column).formatAsString(); | |||
CTComment ctComment = sheetComments.getCTComment(ref); | |||
if(ctComment == null) return null; | |||
XSSFVMLDrawing vml = getVMLDrawing(false); | |||
return new XSSFComment(sheetComments, ctComment, | |||
vml == null ? null : vml.findCommentShape(row, column)); | |||
} | |||
public XSSFHyperlink getHyperlink(int row, int column) { | |||
@@ -2161,8 +2181,10 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
* | |||
* @param cellRef cell region | |||
* @param comment the comment to assign | |||
* @deprecated since Nov 2009 use {@link XSSFCell#setCellComment(org.apache.poi.ss.usermodel.Comment)} instead | |||
*/ | |||
public void setCellComment(String cellRef, XSSFComment comment) { | |||
@Deprecated | |||
public static void setCellComment(String cellRef, XSSFComment comment) { | |||
CellReference cellReference = new CellReference(cellRef); | |||
comment.setRow(cellReference.getRow()); | |||
@@ -2234,8 +2256,13 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet { | |||
/** | |||
* Returns the sheet's comments object if there is one, | |||
* or null if not | |||
* | |||
* @param create create a new comments table if it does not exist | |||
*/ | |||
protected CommentsTable getCommentsTable() { | |||
protected CommentsTable getCommentsTable(boolean create) { | |||
if(sheetComments == null && create){ | |||
sheetComments = (CommentsTable)createRelationship(XSSFRelation.SHEET_COMMENTS, XSSFFactory.getInstance(), (int)sheet.getSheetId()); | |||
} | |||
return sheetComments; | |||
} | |||
@@ -0,0 +1,253 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.xssf.usermodel; | |||
import org.apache.poi.POIXMLDocumentPart; | |||
import org.apache.poi.openxml4j.opc.PackagePart; | |||
import org.apache.poi.openxml4j.opc.PackageRelationship; | |||
import org.apache.xmlbeans.XmlException; | |||
import org.apache.xmlbeans.XmlOptions; | |||
import org.apache.xmlbeans.XmlObject; | |||
import org.apache.xmlbeans.XmlCursor; | |||
import org.w3c.dom.Node; | |||
import schemasMicrosoftComOfficeOffice.*; | |||
import javax.xml.namespace.QName; | |||
import java.io.*; | |||
import java.util.*; | |||
import java.util.regex.Pattern; | |||
import java.util.regex.Matcher; | |||
import java.math.BigInteger; | |||
import schemasMicrosoftComVml.*; | |||
import schemasMicrosoftComVml.STTrueFalse; | |||
import schemasMicrosoftComOfficeExcel.CTClientData; | |||
import schemasMicrosoftComOfficeExcel.STObjectType; | |||
/** | |||
* Represents a SpreadsheetML VML drawing. | |||
* | |||
* <p> | |||
* In Excel 2007 VML drawings are used to describe properties of cell comments, | |||
* although the spec says that VML is deprecated: | |||
* </p> | |||
* <p> | |||
* The VML format is a legacy format originally introduced with Office 2000 and is included and fully defined | |||
* in this Standard for backwards compatibility reasons. The DrawingML format is a newer and richer format | |||
* created with the goal of eventually replacing any uses of VML in the Office Open XML formats. VML should be | |||
* considered a deprecated format included in Office Open XML for legacy reasons only and new applications that | |||
* need a file format for drawings are strongly encouraged to use preferentially DrawingML | |||
* </p> | |||
* | |||
* See 6.4 VML - SpreadsheetML Drawing in Office Open XML Part 4 - Markup Language Reference.pdf | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public final class XSSFVMLDrawing extends POIXMLDocumentPart { | |||
private static final QName QNAME_SHAPE_LAYOUT = new QName("urn:schemas-microsoft-com:office:office", "shapelayout"); | |||
private static final QName QNAME_SHAPE_TYPE = new QName("urn:schemas-microsoft-com:vml", "shapetype"); | |||
private static final QName QNAME_SHAPE = new QName("urn:schemas-microsoft-com:vml", "shape"); | |||
/** | |||
* regexp to parse shape ids, in VML they have weird form of id="_x0000_s1026" | |||
*/ | |||
private static final Pattern ptrn_shapeId = Pattern.compile("_x0000_s(\\d+)"); | |||
private List<QName> _qnames = new ArrayList<QName>(); | |||
private List<XmlObject> _items = new ArrayList<XmlObject>(); | |||
private String _shapeTypeId; | |||
private int _shapeId = 1024; | |||
/** | |||
* Create a new SpreadsheetML drawing | |||
* | |||
* @see XSSFSheet#createDrawingPatriarch() | |||
*/ | |||
protected XSSFVMLDrawing() { | |||
super(); | |||
newDrawing(); | |||
} | |||
/** | |||
* Construct a SpreadsheetML drawing from a package part | |||
* | |||
* @param part the package part holding the drawing data, | |||
* the content type must be <code>application/vnd.openxmlformats-officedocument.drawing+xml</code> | |||
* @param rel the package relationship holding this drawing, | |||
* the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing | |||
*/ | |||
protected XSSFVMLDrawing(PackagePart part, PackageRelationship rel) throws IOException, XmlException { | |||
super(part, rel); | |||
read(getPackagePart().getInputStream()); | |||
} | |||
protected void read(InputStream is) throws IOException, XmlException { | |||
XmlObject root = XmlObject.Factory.parse(is); | |||
_qnames = new ArrayList<QName>(); | |||
_items = new ArrayList<XmlObject>(); | |||
for(XmlObject obj : root.selectPath("$this/xml/*")) { | |||
Node nd = obj.getDomNode(); | |||
QName qname = new QName(nd.getNamespaceURI(), nd.getLocalName()); | |||
if (qname.equals(QNAME_SHAPE_LAYOUT)) { | |||
_items.add(CTShapeLayout.Factory.parse(obj.xmlText())); | |||
} else if (qname.equals(QNAME_SHAPE_TYPE)) { | |||
CTShapetype st = CTShapetype.Factory.parse(obj.xmlText()); | |||
_items.add(st); | |||
_shapeTypeId = st.getId(); | |||
} else if (qname.equals(QNAME_SHAPE)) { | |||
CTShape shape = CTShape.Factory.parse(obj.xmlText()); | |||
String id = shape.getId(); | |||
if(id != null) { | |||
Matcher m = ptrn_shapeId.matcher(id); | |||
if(m.find()) _shapeId = Math.max(_shapeId, Integer.parseInt(m.group(1))); | |||
} | |||
_items.add(shape); | |||
} else { | |||
_items.add(XmlObject.Factory.parse(obj.xmlText())); | |||
} | |||
_qnames.add(qname); | |||
} | |||
} | |||
protected List<XmlObject> getItems(){ | |||
return _items; | |||
} | |||
protected void write(OutputStream out) throws IOException { | |||
XmlObject rootObject = XmlObject.Factory.newInstance(); | |||
XmlCursor rootCursor = rootObject.newCursor(); | |||
rootCursor.toNextToken(); | |||
rootCursor.beginElement("xml"); | |||
for(int i=0; i < _items.size(); i++){ | |||
XmlCursor xc = _items.get(i).newCursor(); | |||
rootCursor.beginElement(_qnames.get(i)); | |||
while(xc.toNextToken() == XmlCursor.TokenType.ATTR) { | |||
Node anode = xc.getDomNode(); | |||
rootCursor.insertAttributeWithValue(anode.getLocalName(), anode.getNamespaceURI(), anode.getNodeValue()); | |||
} | |||
xc.toStartDoc(); | |||
xc.copyXmlContents(rootCursor); | |||
rootCursor.toNextToken(); | |||
xc.dispose(); | |||
} | |||
rootCursor.dispose(); | |||
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); | |||
xmlOptions.setSavePrettyPrint(); | |||
HashMap<String, String> map = new HashMap<String, String>(); | |||
map.put("urn:schemas-microsoft-com:vml", "v"); | |||
map.put("urn:schemas-microsoft-com:office:office", "o"); | |||
map.put("urn:schemas-microsoft-com:office:excel", "x"); | |||
xmlOptions.setSaveSuggestedPrefixes(map); | |||
rootObject.save(out, xmlOptions); | |||
} | |||
@Override | |||
protected void commit() throws IOException { | |||
PackagePart part = getPackagePart(); | |||
OutputStream out = part.getOutputStream(); | |||
write(out); | |||
out.close(); | |||
} | |||
/** | |||
* Initialize a new Speadsheet VML drawing | |||
*/ | |||
private void newDrawing(){ | |||
CTShapeLayout layout = CTShapeLayout.Factory.newInstance(); | |||
layout.setExt(STExt.EDIT); | |||
CTIdMap idmap = layout.addNewIdmap(); | |||
idmap.setExt(STExt.EDIT); | |||
idmap.setData("1"); | |||
_items.add(layout); | |||
_qnames.add(QNAME_SHAPE_LAYOUT); | |||
CTShapetype shapetype = CTShapetype.Factory.newInstance(); | |||
_shapeTypeId = "_xssf_cell_comment"; | |||
shapetype.setId(_shapeTypeId); | |||
shapetype.setCoordsize("21600,21600"); | |||
shapetype.setSpt(202); | |||
shapetype.setPath2("m,l,21600r21600,l21600,xe"); | |||
shapetype.addNewStroke().setJoinstyle(STStrokeJoinStyle.MITER); | |||
CTPath path = shapetype.addNewPath(); | |||
path.setGradientshapeok(STTrueFalse.T); | |||
path.setConnecttype(STConnectType.RECT); | |||
_items.add(shapetype); | |||
_qnames.add(QNAME_SHAPE_TYPE); | |||
} | |||
protected CTShape newCommentShape(){ | |||
CTShape shape = CTShape.Factory.newInstance(); | |||
shape.setId("_x0000_s" + (++_shapeId)); | |||
shape.setType("#" + _shapeTypeId); | |||
shape.setStyle("position:absolute; visibility:hidden"); | |||
shape.setFillcolor("#ffffe1"); | |||
shape.setInsetmode(STInsetMode.AUTO); | |||
shape.addNewFill().setColor("#ffffe1"); | |||
CTShadow shadow = shape.addNewShadow(); | |||
shadow.setOn(STTrueFalse.T); | |||
shadow.setColor("black"); | |||
shadow.setObscured(STTrueFalse.T); | |||
shape.addNewPath().setConnecttype(STConnectType.NONE); | |||
shape.addNewTextbox().setStyle("mso-direction-alt:auto"); | |||
CTClientData cldata = shape.addNewClientData(); | |||
cldata.setObjectType(STObjectType.NOTE); | |||
cldata.addNewMoveWithCells(); | |||
cldata.addNewSizeWithCells(); | |||
cldata.addNewAnchor().setStringValue("1, 15, 0, 2, 3, 15, 3, 16"); | |||
cldata.addNewAutoFill().setStringValue("False"); | |||
cldata.addNewRow().setBigIntegerValue(new BigInteger("0")); | |||
cldata.addNewColumn().setBigIntegerValue(new BigInteger("0")); | |||
_items.add(shape); | |||
_qnames.add(QNAME_SHAPE); | |||
return shape; | |||
} | |||
/** | |||
* Find a shape with ClientData of type "NOTE" and the specified row and column | |||
* | |||
* @return the comment shape or <code>null</code> | |||
*/ | |||
protected CTShape findCommentShape(int row, int col){ | |||
for(XmlObject itm : _items){ | |||
if(itm instanceof CTShape){ | |||
CTShape sh = (CTShape)itm; | |||
if(sh.sizeOfClientDataArray() > 0){ | |||
CTClientData cldata = sh.getClientDataArray(0); | |||
if(cldata.getObjectType() == STObjectType.NOTE){ | |||
int crow = cldata.getRowArray(0).intValue(); | |||
int ccol = cldata.getColumnArray(0).intValue(); | |||
if(crow == row && ccol == col) { | |||
return sh; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
return null; | |||
} | |||
protected boolean removeCommentShape(int row, int col){ | |||
CTShape shape = findCommentShape(row, col); | |||
return shape != null && _items.remove(shape); | |||
} | |||
} |
@@ -25,10 +25,7 @@ import junit.framework.AssertionFailedError; | |||
import junit.framework.TestCase; | |||
import org.apache.poi.POIXMLDocumentPart; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.Comment; | |||
import org.apache.poi.ss.usermodel.Row; | |||
import org.apache.poi.ss.usermodel.Sheet; | |||
import org.apache.poi.ss.usermodel.*; | |||
import org.apache.poi.xssf.XSSFTestDataSamples; | |||
import org.apache.poi.xssf.usermodel.XSSFComment; | |||
import org.apache.poi.xssf.usermodel.XSSFRichTextString; | |||
@@ -47,32 +44,24 @@ public class TestCommentsTable extends TestCase { | |||
private static final String TEST_A1_TEXT = "test A1 text"; | |||
private static final String TEST_AUTHOR = "test author"; | |||
public void testfindAuthor() throws Exception { | |||
CommentsDocument doc = CommentsDocument.Factory.newInstance(); | |||
doc.setComments(CTComments.Factory.newInstance()); | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
doc.save(out, POIXMLDocumentPart.DEFAULT_XML_OPTIONS); | |||
public void testFindAuthor() throws Exception { | |||
CommentsTable sheetComments = new CommentsTable(); | |||
sheetComments.readFrom(new ByteArrayInputStream(out.toByteArray())); | |||
assertEquals(0, sheetComments.findAuthor(TEST_AUTHOR)); | |||
assertEquals(1, sheetComments.findAuthor("another author")); | |||
assertEquals(0, sheetComments.findAuthor(TEST_AUTHOR)); | |||
assertEquals(2, sheetComments.findAuthor("YAA")); | |||
assertEquals(1, sheetComments.findAuthor("another author")); | |||
assertEquals(1, sheetComments.getNumberOfAuthors()); | |||
assertEquals(0, sheetComments.findAuthor("")); | |||
assertEquals("", sheetComments.getAuthor(0)); | |||
assertEquals(1, sheetComments.findAuthor(TEST_AUTHOR)); | |||
assertEquals(2, sheetComments.findAuthor("another author")); | |||
assertEquals(1, sheetComments.findAuthor(TEST_AUTHOR)); | |||
assertEquals(3, sheetComments.findAuthor("YAA")); | |||
assertEquals(2, sheetComments.findAuthor("another author")); | |||
} | |||
public void testGetCellComment() throws Exception { | |||
CommentsDocument doc = CommentsDocument.Factory.newInstance(); | |||
doc.setComments(CTComments.Factory.newInstance()); | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
doc.save(out, POIXMLDocumentPart.DEFAULT_XML_OPTIONS); | |||
CommentsTable sheetComments = new CommentsTable(); | |||
sheetComments.readFrom(new ByteArrayInputStream(out.toByteArray())); | |||
CTComments comments = sheetComments.getCTComments(); | |||
CTCommentList commentList = comments.addNewCommentList(); | |||
CTCommentList commentList = comments.getCommentList(); | |||
// Create 2 comments for A1 and A" cells | |||
CTComment comment0 = commentList.insertNewComment(0); | |||
@@ -87,86 +76,14 @@ public class TestCommentsTable extends TestCase { | |||
comment1.setText(ctrst1); | |||
// test finding the right comment for a cell | |||
assertEquals(TEST_A1_TEXT, sheetComments.findCellComment("A1").getString().getString()); | |||
assertEquals(TEST_A1_TEXT, sheetComments.findCellComment(0, 0).getString().getString()); | |||
assertEquals(TEST_A2_TEXT, sheetComments.findCellComment("A2").getString().getString()); | |||
assertEquals(TEST_A2_TEXT, sheetComments.findCellComment(1, 0).getString().getString()); | |||
assertNull(sheetComments.findCellComment("A3")); | |||
assertNull(sheetComments.findCellComment(2, 0)); | |||
} | |||
public void testAddCellComment() throws Exception { | |||
CommentsDocument doc = CommentsDocument.Factory.newInstance(); | |||
doc.setComments(CTComments.Factory.newInstance()); | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
doc.save(out, POIXMLDocumentPart.DEFAULT_XML_OPTIONS); | |||
CommentsTable sheetComments = new CommentsTable(); | |||
sheetComments.readFrom(new ByteArrayInputStream(out.toByteArray())); | |||
CTCommentList commentList = sheetComments.getCTComments().addNewCommentList(); | |||
assertEquals(0, commentList.sizeOfCommentArray()); | |||
XSSFComment comment = sheetComments.addComment(); | |||
comment.setAuthor("test A1 author"); | |||
comment.setRow(0); | |||
comment.setColumn((short)0); | |||
assertEquals(1, commentList.sizeOfCommentArray()); | |||
assertEquals("test A1 author", sheetComments.getAuthor(commentList.getCommentArray(0).getAuthorId())); | |||
assertEquals("test A1 author", comment.getAuthor()); | |||
// Change the author, check it updates | |||
comment.setAuthor("Another Author"); | |||
assertEquals(1, commentList.sizeOfCommentArray()); | |||
assertEquals("Another Author", comment.getAuthor()); | |||
assertSame(comment0, sheetComments.getCTComment("A1")); | |||
assertSame(comment1, sheetComments.getCTComment("A2")); | |||
assertNull(sheetComments.getCTComment("A3")); | |||
} | |||
public void testDontLoostNewLines() { | |||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithVariousData.xlsx"); | |||
List<POIXMLDocumentPart> rels = wb.getSheetAt(0).getRelations(); | |||
CommentsTable ct = null; | |||
for(POIXMLDocumentPart p : rels) { | |||
if(p instanceof CommentsTable){ | |||
ct = (CommentsTable)p; | |||
break; | |||
} | |||
} | |||
if (ct == null) { | |||
throw new AssertionFailedError("didn't find comments table"); | |||
} | |||
assertEquals(2, ct.getNumberOfComments()); | |||
assertEquals(1, ct.getNumberOfAuthors()); | |||
XSSFComment comment = ct.findCellComment("C5"); | |||
assertEquals("Nick Burch", comment.getAuthor()); | |||
assertEquals("Nick Burch:\nThis is a comment", comment.getString().getString()); | |||
wb = XSSFTestDataSamples.writeOutAndReadBack(wb); | |||
rels = wb.getSheetAt(0).getRelations(); | |||
ct = null; | |||
for(POIXMLDocumentPart p : rels) { | |||
if(p instanceof CommentsTable){ | |||
ct = (CommentsTable)p; | |||
break; | |||
} | |||
} | |||
if (ct == null) { | |||
throw new AssertionFailedError("didn't find comments table"); | |||
} | |||
assertEquals(2, ct.getNumberOfComments()); | |||
assertEquals(1, ct.getNumberOfAuthors()); | |||
comment = ct.findCellComment("C5"); | |||
assertEquals("Nick Burch", comment.getAuthor()); | |||
assertEquals("Nick Burch:\nThis is a comment", comment.getString().getString()); | |||
} | |||
public void testExisting() { | |||
XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("WithVariousData.xlsx"); | |||
Workbook workbook = XSSFTestDataSamples.openSampleWorkbook("WithVariousData.xlsx"); | |||
Sheet sheet1 = workbook.getSheetAt(0); | |||
Sheet sheet2 = workbook.getSheetAt(1); | |||
@@ -238,7 +155,7 @@ public class TestCommentsTable extends TestCase { | |||
assertEquals("Also POI", | |||
sheet2.getRow(2).getCell(1).getCellComment().getAuthor()); | |||
assertEquals("Nick Burch:\nThis is a comment", | |||
assertEquals("Hello!", | |||
sheet1.getRow(4).getCell(2).getCellComment().getString().getString()); | |||
} | |||
@@ -276,4 +193,37 @@ public class TestCommentsTable extends TestCase { | |||
// Todo - check text too, once bug fixed | |||
} | |||
public void testRemoveComment() throws Exception { | |||
CommentsTable sheetComments = new CommentsTable(); | |||
CTComment a1 = sheetComments.newComment(); | |||
a1.setRef("A1"); | |||
CTComment a2 = sheetComments.newComment(); | |||
a2.setRef("A2"); | |||
CTComment a3 = sheetComments.newComment(); | |||
a3.setRef("A3"); | |||
assertSame(a1, sheetComments.getCTComment("A1")); | |||
assertSame(a2, sheetComments.getCTComment("A2")); | |||
assertSame(a3, sheetComments.getCTComment("A3")); | |||
assertEquals(3, sheetComments.getNumberOfComments()); | |||
assertTrue(sheetComments.removeComment("A1")); | |||
assertEquals(2, sheetComments.getNumberOfComments()); | |||
assertNull(sheetComments.getCTComment("A1")); | |||
assertSame(a2, sheetComments.getCTComment("A2")); | |||
assertSame(a3, sheetComments.getCTComment("A3")); | |||
assertTrue(sheetComments.removeComment("A2")); | |||
assertEquals(1, sheetComments.getNumberOfComments()); | |||
assertNull(sheetComments.getCTComment("A1")); | |||
assertNull(sheetComments.getCTComment("A2")); | |||
assertSame(a3, sheetComments.getCTComment("A3")); | |||
assertTrue(sheetComments.removeComment("A3")); | |||
assertEquals(0, sheetComments.getNumberOfComments()); | |||
assertNull(sheetComments.getCTComment("A1")); | |||
assertNull(sheetComments.getCTComment("A2")); | |||
assertNull(sheetComments.getCTComment("A3")); | |||
} | |||
} |
@@ -18,171 +18,177 @@ | |||
package org.apache.poi.xssf.usermodel; | |||
import org.apache.poi.hssf.usermodel.HSSFRichTextString; | |||
import org.apache.poi.ss.usermodel.Cell; | |||
import org.apache.poi.ss.usermodel.Comment; | |||
import org.apache.poi.ss.usermodel.RichTextString; | |||
import org.apache.poi.ss.usermodel.Row; | |||
import org.apache.poi.ss.usermodel.*; | |||
import org.apache.poi.ss.util.CellReference; | |||
import org.apache.poi.xssf.model.CommentsTable; | |||
import org.apache.poi.xssf.XSSFTestDataSamples; | |||
import org.apache.poi.xssf.XSSFITestDataProvider; | |||
import org.apache.poi.POIXMLDocumentPart; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTAuthors; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComments; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CommentsDocument; | |||
import org.apache.xmlbeans.XmlObject; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; | |||
import junit.framework.TestCase; | |||
import junit.framework.AssertionFailedError; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.IOException; | |||
import java.util.List; | |||
import schemasMicrosoftComVml.CTShape; | |||
public class TestXSSFComment extends TestCase { | |||
public class TestXSSFComment extends BaseTestCellComment { | |||
private static final String TEST_RICHTEXTSTRING = "test richtextstring"; | |||
private static final String TEST_AUTHOR = "test_author"; | |||
public void testConstructors() { | |||
CommentsTable sheetComments = new CommentsTable(); | |||
XSSFComment comment = sheetComments.addComment(); | |||
assertNotNull(comment); | |||
@Override | |||
protected XSSFITestDataProvider getTestDataProvider(){ | |||
return XSSFITestDataProvider.getInstance(); | |||
} | |||
CTComment ctComment = CTComment.Factory.newInstance(); | |||
XSSFComment comment2 = new XSSFComment(sheetComments, ctComment); | |||
assertNotNull(comment2); | |||
/** | |||
* test that we can read cell comments from an existing workbook. | |||
*/ | |||
public void testReadComments() { | |||
readComments("SimpleWithComments.xlsx"); | |||
} | |||
public void testGetColumn() { | |||
CommentsTable sheetComments = new CommentsTable(); | |||
CTComment ctComment = CTComment.Factory.newInstance(); | |||
ctComment.setRef("A1"); | |||
XSSFComment comment = new XSSFComment(sheetComments, ctComment); | |||
assertNotNull(comment); | |||
assertEquals(0, comment.getColumn()); | |||
ctComment.setRef("C10"); | |||
assertEquals(2, comment.getColumn()); | |||
/** | |||
* test that we can modify existing cell comments | |||
*/ | |||
public void testModifyComments() throws IOException { | |||
modifyComments("SimpleWithComments.xlsx"); | |||
} | |||
public void testGetRow() { | |||
CommentsTable sheetComments = new CommentsTable(); | |||
CTComment ctComment = CTComment.Factory.newInstance(); | |||
ctComment.setRef("A1"); | |||
XSSFComment comment = new XSSFComment(sheetComments, ctComment); | |||
assertNotNull(comment); | |||
assertEquals(0, comment.getRow()); | |||
ctComment.setRef("C10"); | |||
assertEquals(9, comment.getRow()); | |||
public void testDeleteComments() throws Exception { | |||
deleteComments("SimpleWithComments.xlsx"); | |||
} | |||
public void testGetAuthor() throws Exception { | |||
CommentsDocument doc = CommentsDocument.Factory.newInstance(); | |||
CTComments ctComments = CTComments.Factory.newInstance(); | |||
CTComment ctComment = ctComments.addNewCommentList().addNewComment(); | |||
CTAuthors ctAuthors = ctComments.addNewAuthors(); | |||
ctAuthors.insertAuthor(0, TEST_AUTHOR); | |||
ctComment.setAuthorId(0); | |||
doc.setComments(ctComments); | |||
/** | |||
* test properties of a newly constructed comment | |||
*/ | |||
public void testConstructor() { | |||
CommentsTable sheetComments = new CommentsTable(); | |||
assertNotNull(sheetComments.getCTComments().getCommentList()); | |||
assertNotNull(sheetComments.getCTComments().getAuthors()); | |||
assertEquals(1, sheetComments.getCTComments().getAuthors().sizeOfAuthorArray()); | |||
assertEquals(1, sheetComments.getNumberOfAuthors()); | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
doc.save(out, POIXMLDocumentPart.DEFAULT_XML_OPTIONS); | |||
CTComment ctComment = sheetComments.newComment(); | |||
CTShape vmlShape = CTShape.Factory.newInstance(); | |||
CommentsTable sheetComments = new CommentsTable(); | |||
sheetComments.readFrom(new ByteArrayInputStream(out.toByteArray())); | |||
XSSFComment comment = new XSSFComment(sheetComments, ctComment); | |||
assertEquals(TEST_AUTHOR, comment.getAuthor()); | |||
XSSFComment comment = new XSSFComment(sheetComments, ctComment, vmlShape); | |||
assertEquals(null, comment.getString()); | |||
assertEquals(0, comment.getRow()); | |||
assertEquals(0, comment.getColumn()); | |||
assertEquals("", comment.getAuthor()); | |||
assertEquals(false, comment.isVisible()); | |||
} | |||
public void testSetColumn() { | |||
public void testGetSetCol() { | |||
CommentsTable sheetComments = new CommentsTable(); | |||
CTComment ctComment = CTComment.Factory.newInstance(); | |||
XSSFComment comment = new XSSFComment(sheetComments, ctComment); | |||
comment.setColumn((short)3); | |||
assertEquals(3, comment.getColumn()); | |||
assertEquals(3, (new CellReference(ctComment.getRef()).getCol())); | |||
assertEquals("D1", ctComment.getRef()); | |||
comment.setColumn((short)13); | |||
assertEquals(13, comment.getColumn()); | |||
XSSFVMLDrawing vml = new XSSFVMLDrawing(); | |||
CTComment ctComment = sheetComments.newComment(); | |||
CTShape vmlShape = vml.newCommentShape(); | |||
XSSFComment comment = new XSSFComment(sheetComments, ctComment, vmlShape); | |||
comment.setColumn(1); | |||
assertEquals(1, comment.getColumn()); | |||
assertEquals(1, new CellReference(ctComment.getRef()).getCol()); | |||
assertEquals(1, vmlShape.getClientDataArray(0).getColumnArray(0).intValue()); | |||
comment.setColumn(5); | |||
assertEquals(5, comment.getColumn()); | |||
assertEquals(5, new CellReference(ctComment.getRef()).getCol()); | |||
assertEquals(5, vmlShape.getClientDataArray(0).getColumnArray(0).intValue()); | |||
} | |||
public void testSetRow() { | |||
public void testGetSetRow() { | |||
CommentsTable sheetComments = new CommentsTable(); | |||
CTComment ctComment = CTComment.Factory.newInstance(); | |||
XSSFComment comment = new XSSFComment(sheetComments, ctComment); | |||
comment.setRow(20); | |||
assertEquals(20, comment.getRow()); | |||
assertEquals(20, (new CellReference(ctComment.getRef()).getRow())); | |||
assertEquals("A21", ctComment.getRef()); | |||
comment.setRow(19); | |||
assertEquals(19, comment.getRow()); | |||
XSSFVMLDrawing vml = new XSSFVMLDrawing(); | |||
CTComment ctComment = sheetComments.newComment(); | |||
CTShape vmlShape = vml.newCommentShape(); | |||
XSSFComment comment = new XSSFComment(sheetComments, ctComment, vmlShape); | |||
comment.setRow(1); | |||
assertEquals(1, comment.getRow()); | |||
assertEquals(1, new CellReference(ctComment.getRef()).getRow()); | |||
assertEquals(1, vmlShape.getClientDataArray(0).getRowArray(0).intValue()); | |||
comment.setRow(5); | |||
assertEquals(5, comment.getRow()); | |||
assertEquals(5, new CellReference(ctComment.getRef()).getRow()); | |||
assertEquals(5, vmlShape.getClientDataArray(0).getRowArray(0).intValue()); | |||
} | |||
public void testSetAuthor() { | |||
CommentsTable sheetComments = new CommentsTable(); | |||
CTComment ctComment = CTComment.Factory.newInstance(); | |||
XSSFComment comment = new XSSFComment(sheetComments, ctComment); | |||
comment.setAuthor(TEST_AUTHOR); | |||
assertEquals(TEST_AUTHOR, comment.getAuthor()); | |||
public void testSetString() { | |||
XSSFWorkbook wb = new XSSFWorkbook(); | |||
XSSFSheet sh = wb.createSheet(); | |||
XSSFComment comment = sh.createDrawingPatriarch().createCellComment(new XSSFClientAnchor()); | |||
//passing HSSFRichTextString is incorrect | |||
try { | |||
comment.setString(new HSSFRichTextString(TEST_RICHTEXTSTRING)); | |||
fail("expected exception"); | |||
} catch (IllegalArgumentException e){ | |||
; | |||
} | |||
//simple string argument | |||
comment.setString(TEST_RICHTEXTSTRING); | |||
assertEquals(TEST_RICHTEXTSTRING, comment.getString().getString()); | |||
//if the text is already set, it should be overridden, not added twice! | |||
comment.setString(TEST_RICHTEXTSTRING); | |||
CTComment ctComment = comment.getCTComment(); | |||
XmlObject[] obj = ctComment.selectPath( | |||
"declare namespace w='http://schemas.openxmlformats.org/spreadsheetml/2006/main' .//w:text"); | |||
assertEquals(1, obj.length); | |||
assertEquals(TEST_RICHTEXTSTRING, comment.getString().getString()); | |||
//sequential call of comment.getString() should return the same XSSFRichTextString object | |||
assertSame(comment.getString(), comment.getString()); | |||
XSSFRichTextString richText = new XSSFRichTextString(TEST_RICHTEXTSTRING); | |||
XSSFFont font1 = wb.createFont(); | |||
font1.setFontName("Tahoma"); | |||
font1.setFontHeight(8.5); | |||
font1.setItalic(true); | |||
font1.setColor(IndexedColors.BLUE_GREY.getIndex()); | |||
richText.applyFont(0, 5, font1); | |||
//check the low-level stuff | |||
comment.setString(richText); | |||
obj = ctComment.selectPath( | |||
"declare namespace w='http://schemas.openxmlformats.org/spreadsheetml/2006/main' .//w:text"); | |||
assertEquals(1, obj.length); | |||
assertSame(comment.getString(), richText); | |||
//check that the rich text is set in the comment | |||
CTRPrElt rPr = richText.getCTRst().getRArray(0).getRPr(); | |||
assertEquals(true, rPr.getIArray()[0].getVal()); | |||
assertEquals(8.5, rPr.getSzArray()[0].getVal()); | |||
assertEquals(IndexedColors.BLUE_GREY.getIndex(), rPr.getColorArray()[0].getIndexed()); | |||
assertEquals("Tahoma", rPr.getRFontArray()[0].getVal()); | |||
} | |||
public void testSetString() { | |||
public void testAuthor() { | |||
CommentsTable sheetComments = new CommentsTable(); | |||
CTComment ctComment = CTComment.Factory.newInstance(); | |||
XSSFComment comment = new XSSFComment(sheetComments, ctComment); | |||
RichTextString richTextString = new HSSFRichTextString(TEST_RICHTEXTSTRING); | |||
comment.setString(richTextString); | |||
assertEquals(TEST_RICHTEXTSTRING, ctComment.getText().getT()); | |||
CTComment ctComment = sheetComments.newComment(); | |||
assertEquals(1, sheetComments.getNumberOfAuthors()); | |||
XSSFComment comment = new XSSFComment(sheetComments, ctComment, null); | |||
assertEquals("", comment.getAuthor()); | |||
comment.setAuthor("Apache POI"); | |||
assertEquals("Apache POI", comment.getAuthor()); | |||
assertEquals(2, sheetComments.getNumberOfAuthors()); | |||
comment.setAuthor("Apache POI"); | |||
assertEquals(2, sheetComments.getNumberOfAuthors()); | |||
comment.setAuthor(""); | |||
assertEquals("", comment.getAuthor()); | |||
assertEquals(2, sheetComments.getNumberOfAuthors()); | |||
} | |||
/** | |||
* Tests that we can add comments to a new | |||
* file, save, load, and still see them | |||
* @throws Exception | |||
*/ | |||
public void testCreateSave() { | |||
XSSFWorkbook wb = new XSSFWorkbook(); | |||
XSSFSheet s1 = wb.createSheet(); | |||
Row r1 = s1.createRow(0); | |||
Cell r1c1 = r1.createCell(0); | |||
r1c1.setCellValue(2.2); | |||
assertEquals(0, s1.getNumberOfComments()); | |||
Comment c1 = s1.createComment(); | |||
c1.setAuthor("Author 1"); | |||
c1.setString(new XSSFRichTextString("Comment 1")); | |||
r1c1.setCellComment(c1); | |||
assertEquals(1, s1.getNumberOfComments()); | |||
// Save and re-load | |||
wb = XSSFTestDataSamples.writeOutAndReadBack(wb); | |||
s1 = wb.getSheetAt(0); | |||
assertEquals(1, s1.getNumberOfComments()); | |||
assertNotNull(s1.getRow(0).getCell(0).getCellComment()); | |||
assertEquals("Author 1", s1.getRow(0).getCell(0).getCellComment().getAuthor()); | |||
assertEquals("Comment 1", s1.getRow(0).getCell(0).getCellComment().getString().getString()); | |||
// Now add an orphaned one | |||
Comment c2 = s1.createComment(); | |||
c2.setAuthor("Author 2"); | |||
c2.setString(new XSSFRichTextString("Second Comment")); | |||
c2.setRow(0); | |||
c2.setColumn((short)1); | |||
assertEquals(2, s1.getNumberOfComments()); | |||
// Save and re-load | |||
wb = XSSFTestDataSamples.writeOutAndReadBack(wb); | |||
s1 = wb.getSheetAt(0); | |||
assertEquals(2, s1.getNumberOfComments()); | |||
assertNotNull(s1.getCellComment(0, 0)); | |||
assertNotNull(s1.getCellComment(0, 1)); | |||
assertEquals("Author 1", s1.getCellComment(0, 0).getAuthor()); | |||
assertEquals("Author 2", s1.getCellComment(0, 1).getAuthor()); | |||
} | |||
} |
@@ -177,7 +177,7 @@ public class TestXSSFSheet extends BaseTestSheet { | |||
XSSFComment comment = sheet.createComment(); | |||
Cell cell = sheet.createRow(0).createCell((short) 0); | |||
CommentsTable comments = sheet.getCommentsTable(); | |||
CommentsTable comments = sheet.getCommentsTable(false); | |||
CTComments ctComments = comments.getCTComments(); | |||
sheet.setCellComment("A1", comment); | |||
@@ -843,4 +843,42 @@ public class TestXSSFSheet extends BaseTestSheet { | |||
assertFalse(sheet.isColumnHidden(4)); | |||
assertFalse(sheet.isColumnHidden(5)); | |||
} | |||
public void testCommentsTable() { | |||
XSSFWorkbook workbook = new XSSFWorkbook(); | |||
XSSFSheet sheet1 = workbook.createSheet(); | |||
CommentsTable comment1 = sheet1.getCommentsTable(false); | |||
assertNull(comment1); | |||
comment1 = sheet1.getCommentsTable(true); | |||
assertNotNull(comment1); | |||
assertEquals("/xl/comments1.xml", comment1.getPackageRelationship().getTargetURI().toString()); | |||
assertSame(comment1, sheet1.getCommentsTable(true)); | |||
//second sheet | |||
XSSFSheet sheet2 = workbook.createSheet(); | |||
CommentsTable comment2 = sheet2.getCommentsTable(false); | |||
assertNull(comment2); | |||
comment2 = sheet2.getCommentsTable(true); | |||
assertNotNull(comment2); | |||
assertSame(comment2, sheet2.getCommentsTable(true)); | |||
assertEquals("/xl/comments2.xml", comment2.getPackageRelationship().getTargetURI().toString()); | |||
//comment1 and comment2 are different objects | |||
assertNotSame(comment1, comment2); | |||
//now test against a workbook containing cell comments | |||
workbook = XSSFTestDataSamples.openSampleWorkbook("WithMoreVariousData.xlsx"); | |||
sheet1 = workbook.getSheetAt(0); | |||
comment1 = sheet1.getCommentsTable(true); | |||
assertNotNull(comment1); | |||
assertEquals("/xl/comments1.xml", comment1.getPackageRelationship().getTargetURI().toString()); | |||
assertSame(comment1, sheet1.getCommentsTable(true)); | |||
} | |||
} |
@@ -0,0 +1,139 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.xssf.usermodel; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.ByteArrayInputStream; | |||
import java.math.BigInteger; | |||
import java.util.List; | |||
import junit.framework.TestCase; | |||
import org.apache.poi.POIDataSamples; | |||
import org.apache.xmlbeans.XmlObject; | |||
import schemasMicrosoftComVml.*; | |||
import schemasMicrosoftComOfficeOffice.CTShapeLayout; | |||
import schemasMicrosoftComOfficeOffice.STConnectType; | |||
import schemasMicrosoftComOfficeOffice.STInsetMode; | |||
import schemasMicrosoftComOfficeExcel.CTClientData; | |||
import schemasMicrosoftComOfficeExcel.STObjectType; | |||
/** | |||
* @author Yegor Kozlov | |||
*/ | |||
public class TestXSSFVMLDrawing extends TestCase { | |||
public void testNew() throws Exception { | |||
XSSFVMLDrawing vml = new XSSFVMLDrawing(); | |||
List<XmlObject> items = vml.getItems(); | |||
assertEquals(2, items.size()); | |||
assertTrue(items.get(0) instanceof CTShapeLayout); | |||
CTShapeLayout layout = (CTShapeLayout)items.get(0); | |||
assertEquals(STExt.EDIT, layout.getExt()); | |||
assertEquals(STExt.EDIT, layout.getIdmap().getExt()); | |||
assertEquals("1", layout.getIdmap().getData()); | |||
assertTrue(items.get(1) instanceof CTShapetype); | |||
CTShapetype type = (CTShapetype)items.get(1); | |||
assertEquals("21600,21600", type.getCoordsize()); | |||
assertEquals(202.0f, type.getSpt()); | |||
assertEquals("m,l,21600r21600,l21600,xe", type.getPath2()); | |||
assertEquals("_xssf_cell_comment", type.getId()); | |||
assertEquals(STTrueFalse.T, type.getPathArray(0).getGradientshapeok()); | |||
assertEquals(STConnectType.RECT, type.getPathArray(0).getConnecttype()); | |||
CTShape shape = vml.newCommentShape(); | |||
assertEquals(3, items.size()); | |||
assertSame(items.get(2), shape); | |||
assertEquals("#_xssf_cell_comment", shape.getType()); | |||
assertEquals("position:absolute; visibility:hidden", shape.getStyle()); | |||
assertEquals("#ffffe1", shape.getFillcolor()); | |||
assertEquals(STInsetMode.AUTO, shape.getInsetmode()); | |||
assertEquals("#ffffe1", shape.getFillArray(0).getColor()); | |||
CTShadow shadow = shape.getShadowArray(0); | |||
assertEquals(STTrueFalse.T, shadow.getOn()); | |||
assertEquals("black", shadow.getColor()); | |||
assertEquals(STTrueFalse.T, shadow.getObscured()); | |||
assertEquals(STConnectType.NONE, shape.getPathArray(0).getConnecttype()); | |||
assertEquals("mso-direction-alt:auto", shape.getTextboxArray(0).getStyle()); | |||
CTClientData cldata = shape.getClientDataArray(0); | |||
assertEquals(STObjectType.NOTE, cldata.getObjectType()); | |||
assertEquals(1, cldata.sizeOfMoveWithCellsArray()); | |||
assertEquals(1, cldata.sizeOfSizeWithCellsArray()); | |||
assertEquals("1, 15, 0, 2, 3, 15, 3, 16", cldata.getAnchorArray(0)); | |||
assertEquals("False", cldata.getAutoFillArray(0).toString()); | |||
assertEquals(0, cldata.getRowArray(0).intValue()); | |||
assertEquals(0, cldata.getColumnArray(0).intValue()); | |||
//serialize and read again | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
vml.write(out); | |||
XSSFVMLDrawing vml2 = new XSSFVMLDrawing(); | |||
vml2.read(new ByteArrayInputStream(out.toByteArray())); | |||
List<XmlObject> items2 = vml2.getItems(); | |||
assertEquals(3, items2.size()); | |||
assertTrue(items2.get(0) instanceof CTShapeLayout); | |||
assertTrue(items2.get(1) instanceof CTShapetype); | |||
assertTrue(items2.get(2) instanceof CTShape); | |||
} | |||
public void testFindCommentShape() throws Exception { | |||
XSSFVMLDrawing vml = new XSSFVMLDrawing(); | |||
vml.read(POIDataSamples.getSpreadSheetInstance().openResourceAsStream("vmlDrawing1.vml")); | |||
CTShape sh_a1 = vml.findCommentShape(0, 0); | |||
assertNotNull(sh_a1); | |||
assertEquals("_x0000_s1025", sh_a1.getId()); | |||
CTShape sh_b1 = vml.findCommentShape(0, 1); | |||
assertNotNull(sh_b1); | |||
assertEquals("_x0000_s1026", sh_b1.getId()); | |||
CTShape sh_c1 = vml.findCommentShape(0, 2); | |||
assertNull(sh_c1); | |||
CTShape sh_d1 = vml.newCommentShape(); | |||
assertEquals("_x0000_s1027", sh_d1.getId()); | |||
sh_d1.getClientDataArray(0).setRowArray(0, new BigInteger("0")); | |||
sh_d1.getClientDataArray(0).setColumnArray(0, new BigInteger("3")); | |||
assertSame(sh_d1, vml.findCommentShape(0, 3)); | |||
//newly created drawing | |||
XSSFVMLDrawing newVml = new XSSFVMLDrawing(); | |||
assertNull(newVml.findCommentShape(0, 0)); | |||
sh_a1 = newVml.newCommentShape(); | |||
assertEquals("_x0000_s1025", sh_a1.getId()); | |||
sh_a1.getClientDataArray(0).setRowArray(0, new BigInteger("0")); | |||
sh_a1.getClientDataArray(0).setColumnArray(0, new BigInteger("1")); | |||
assertSame(sh_a1, newVml.findCommentShape(0, 1)); | |||
} | |||
public void testRemoveCommentShape() throws Exception { | |||
XSSFVMLDrawing vml = new XSSFVMLDrawing(); | |||
vml.read(POIDataSamples.getSpreadSheetInstance().openResourceAsStream("vmlDrawing1.vml")); | |||
CTShape sh_a1 = vml.findCommentShape(0, 0); | |||
assertNotNull(sh_a1); | |||
assertTrue(vml.removeCommentShape(0, 0)); | |||
assertNull(vml.findCommentShape(0, 0)); | |||
} | |||
} |
@@ -16,208 +16,45 @@ | |||
==================================================================== */ | |||
package org.apache.poi.hssf.usermodel; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.ByteArrayOutputStream; | |||
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; | |||
import org.apache.poi.hssf.HSSFITestDataProvider; | |||
import org.apache.poi.ss.usermodel.BaseTestCellComment; | |||
/** | |||
* Tests TestHSSFCellComment. | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public final class TestHSSFComment extends TestCase { | |||
/** | |||
* Test that we can create cells and add comments to it. | |||
*/ | |||
public static void testWriteComments() throws Exception { | |||
String cellText = "Hello, World"; | |||
String commentText = "We can set comments in POI"; | |||
String commentAuthor = "Apache Software Foundation"; | |||
int cellRow = 3; | |||
int cellColumn = 1; | |||
HSSFWorkbook wb = new HSSFWorkbook(); | |||
HSSFSheet sheet = wb.createSheet(); | |||
HSSFCell cell = sheet.createRow(cellRow).createCell(cellColumn); | |||
cell.setCellValue(new HSSFRichTextString(cellText)); | |||
assertNull(cell.getCellComment()); | |||
HSSFPatriarch patr = sheet.createDrawingPatriarch(); | |||
HSSFClientAnchor anchor = new HSSFClientAnchor(); | |||
anchor.setAnchor( (short)4, 2, 0, 0, (short) 6, 5, 0, 0); | |||
HSSFComment comment = patr.createComment(anchor); | |||
HSSFRichTextString string1 = new HSSFRichTextString(commentText); | |||
comment.setString(string1); | |||
comment.setAuthor(commentAuthor); | |||
cell.setCellComment(comment); | |||
if (false) { | |||
// TODO - the following line should break this test, but it doesn't | |||
cell.removeCellComment(); | |||
} | |||
//verify our settings | |||
assertEquals(HSSFSimpleShape.OBJECT_TYPE_COMMENT, comment.getShapeType()); | |||
assertEquals(commentAuthor, comment.getAuthor()); | |||
assertEquals(commentText, comment.getString().getString()); | |||
assertEquals(cellRow, comment.getRow()); | |||
assertEquals(cellColumn, comment.getColumn()); | |||
//serialize the workbook and read it again | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
wb.write(out); | |||
out.close(); | |||
public final class TestHSSFComment extends BaseTestCellComment { | |||
wb = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray())); | |||
sheet = wb.getSheetAt(0); | |||
cell = sheet.getRow(cellRow).getCell(cellColumn); | |||
comment = cell.getCellComment(); | |||
assertNotNull(comment); | |||
assertEquals(HSSFSimpleShape.OBJECT_TYPE_COMMENT, comment.getShapeType()); | |||
assertEquals(commentAuthor, comment.getAuthor()); | |||
assertEquals(commentText, comment.getString().getString()); | |||
assertEquals(cellRow, comment.getRow()); | |||
assertEquals(cellColumn, comment.getColumn()); | |||
// Change slightly, and re-test | |||
comment.setString(new HSSFRichTextString("New Comment Text")); | |||
out = new ByteArrayOutputStream(); | |||
wb.write(out); | |||
out.close(); | |||
wb = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray())); | |||
sheet = wb.getSheetAt(0); | |||
cell = sheet.getRow(cellRow).getCell(cellColumn); | |||
comment = cell.getCellComment(); | |||
@Override | |||
protected HSSFITestDataProvider getTestDataProvider(){ | |||
return HSSFITestDataProvider.getInstance(); | |||
} | |||
assertNotNull(comment); | |||
public static void testDefaultShapeType() throws Exception { | |||
HSSFComment comment = new HSSFComment((HSSFShape)null, (HSSFAnchor)null); | |||
assertEquals(HSSFSimpleShape.OBJECT_TYPE_COMMENT, comment.getShapeType()); | |||
assertEquals(commentAuthor, comment.getAuthor()); | |||
assertEquals("New Comment Text", comment.getString().getString()); | |||
assertEquals(cellRow, comment.getRow()); | |||
assertEquals(cellColumn, comment.getColumn()); | |||
} | |||
/** | |||
* test that we can read cell comments from an existing workbook. | |||
*/ | |||
public static void testReadComments() { | |||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("SimpleWithComments.xls"); | |||
HSSFSheet sheet = wb.getSheetAt(0); | |||
HSSFCell cell; | |||
HSSFRow row; | |||
HSSFComment comment; | |||
for (int rownum = 0; rownum < 3; rownum++) { | |||
row = sheet.getRow(rownum); | |||
cell = row.getCell(0); | |||
comment = cell.getCellComment(); | |||
assertNull("Cells in the first column are not commented", comment); | |||
assertNull(sheet.getCellComment(rownum, 0)); | |||
} | |||
for (int rownum = 0; rownum < 3; rownum++) { | |||
row = sheet.getRow(rownum); | |||
cell = row.getCell(1); | |||
comment = cell.getCellComment(); | |||
assertNotNull("Cells in the second column have comments", comment); | |||
assertNotNull("Cells in the second column have comments", sheet.getCellComment(rownum, 1)); | |||
assertEquals(HSSFSimpleShape.OBJECT_TYPE_COMMENT, comment.getShapeType()); | |||
assertEquals("Yegor Kozlov", comment.getAuthor()); | |||
assertFalse("cells in the second column have not empyy notes", | |||
"".equals(comment.getString().getString())); | |||
assertEquals(rownum, comment.getRow()); | |||
assertEquals(cell.getColumnIndex(), comment.getColumn()); | |||
} | |||
} | |||
public void testReadComments() { | |||
readComments("SimpleWithComments.xls"); | |||
} | |||
/** | |||
* test that we can modify existing cell comments | |||
*/ | |||
public static void testModifyComments() throws IOException { | |||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("SimpleWithComments.xls"); | |||
HSSFSheet sheet = wb.getSheetAt(0); | |||
HSSFCell cell; | |||
HSSFRow row; | |||
HSSFComment comment; | |||
for (int rownum = 0; rownum < 3; rownum++) { | |||
row = sheet.getRow(rownum); | |||
cell = row.getCell(1); | |||
comment = cell.getCellComment(); | |||
comment.setAuthor("Mofified["+rownum+"] by Yegor"); | |||
comment.setString(new HSSFRichTextString("Modified comment at row " + rownum)); | |||
} | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
wb.write(out); | |||
out.close(); | |||
wb = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray())); | |||
sheet = wb.getSheetAt(0); | |||
for (int rownum = 0; rownum < 3; rownum++) { | |||
row = sheet.getRow(rownum); | |||
cell = row.getCell(1); | |||
comment = cell.getCellComment(); | |||
assertEquals("Mofified["+rownum+"] by Yegor", comment.getAuthor()); | |||
assertEquals("Modified comment at row " + rownum, comment.getString().getString()); | |||
} | |||
} | |||
public void testModifyComments() throws IOException { | |||
modifyComments("SimpleWithComments.xls"); | |||
} | |||
public void testDeleteComments() throws Exception { | |||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("SimpleWithComments.xls"); | |||
HSSFSheet sheet = wb.getSheetAt(0); | |||
// Zap from rows 1 and 3 | |||
assertNotNull(sheet.getRow(0).getCell(1).getCellComment()); | |||
assertNotNull(sheet.getRow(1).getCell(1).getCellComment()); | |||
assertNotNull(sheet.getRow(2).getCell(1).getCellComment()); | |||
sheet.getRow(0).getCell(1).removeCellComment(); | |||
sheet.getRow(2).getCell(1).setCellComment(null); | |||
// Check gone so far | |||
assertNull(sheet.getRow(0).getCell(1).getCellComment()); | |||
assertNotNull(sheet.getRow(1).getCell(1).getCellComment()); | |||
assertNull(sheet.getRow(2).getCell(1).getCellComment()); | |||
// Save and re-load | |||
ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
wb.write(out); | |||
out.close(); | |||
wb = new HSSFWorkbook(new ByteArrayInputStream(out.toByteArray())); | |||
// Check | |||
assertNull(sheet.getRow(0).getCell(1).getCellComment()); | |||
assertNotNull(sheet.getRow(1).getCell(1).getCellComment()); | |||
assertNull(sheet.getRow(2).getCell(1).getCellComment()); | |||
// FileOutputStream fout = new FileOutputStream("/tmp/c.xls"); | |||
// wb.write(fout); | |||
// fout.close(); | |||
deleteComments("SimpleWithComments.xls"); | |||
} | |||
/** |
@@ -0,0 +1,246 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.ss.usermodel; | |||
import junit.framework.TestCase; | |||
import org.apache.poi.ss.ITestDataProvider; | |||
/** | |||
* Common superclass for testing implementatiosn of | |||
* {@link Comment} | |||
*/ | |||
public abstract class BaseTestCellComment extends TestCase { | |||
protected abstract ITestDataProvider getTestDataProvider(); | |||
public final void testFind() { | |||
Workbook book = getTestDataProvider().createWorkbook(); | |||
Sheet sheet = book.createSheet(); | |||
assertNull(sheet.getCellComment(0, 0)); | |||
Row row = sheet.createRow(0); | |||
Cell cell = row.createCell(0); | |||
assertNull(sheet.getCellComment(0, 0)); | |||
assertNull(cell.getCellComment()); | |||
} | |||
public final void testCreate() throws Exception { | |||
String cellText = "Hello, World"; | |||
String commentText = "We can set comments in POI"; | |||
String commentAuthor = "Apache Software Foundation"; | |||
int cellRow = 3; | |||
int cellColumn = 1; | |||
Workbook wb = getTestDataProvider().createWorkbook(); | |||
CreationHelper factory = wb.getCreationHelper(); | |||
Sheet sheet = wb.createSheet(); | |||
assertNull(sheet.getCellComment(cellRow, cellColumn)); | |||
Cell cell = sheet.createRow(cellRow).createCell(cellColumn); | |||
cell.setCellValue(factory.createRichTextString(cellText)); | |||
assertNull(cell.getCellComment()); | |||
assertNull(sheet.getCellComment(cellRow, cellColumn)); | |||
Drawing patr = sheet.createDrawingPatriarch(); | |||
ClientAnchor anchor = factory.createClientAnchor(); | |||
anchor.setCol1(2); | |||
anchor.setCol2(5); | |||
anchor.setRow1(1); | |||
anchor.setRow2(2); | |||
Comment comment = patr.createCellComment(anchor); | |||
assertFalse(comment.isVisible()); | |||
comment.setVisible(true); | |||
assertTrue(comment.isVisible()); | |||
RichTextString string1 = factory.createRichTextString(commentText); | |||
comment.setString(string1); | |||
comment.setAuthor(commentAuthor); | |||
cell.setCellComment(comment); | |||
assertNotNull(cell.getCellComment()); | |||
assertNotNull(sheet.getCellComment(cellRow, cellColumn)); | |||
//verify our settings | |||
assertEquals(commentAuthor, comment.getAuthor()); | |||
assertEquals(commentText, comment.getString().getString()); | |||
assertEquals(cellRow, comment.getRow()); | |||
assertEquals(cellColumn, comment.getColumn()); | |||
wb = getTestDataProvider().writeOutAndReadBack(wb); | |||
sheet = wb.getSheetAt(0); | |||
cell = sheet.getRow(cellRow).getCell(cellColumn); | |||
comment = cell.getCellComment(); | |||
assertNotNull(comment); | |||
assertEquals(commentAuthor, comment.getAuthor()); | |||
assertEquals(commentText, comment.getString().getString()); | |||
assertEquals(cellRow, comment.getRow()); | |||
assertEquals(cellColumn, comment.getColumn()); | |||
assertTrue(comment.isVisible()); | |||
// Change slightly, and re-test | |||
comment.setString(factory.createRichTextString("New Comment Text")); | |||
comment.setVisible(false); | |||
wb = getTestDataProvider().writeOutAndReadBack(wb); | |||
sheet = wb.getSheetAt(0); | |||
cell = sheet.getRow(cellRow).getCell(cellColumn); | |||
comment = cell.getCellComment(); | |||
assertNotNull(comment); | |||
assertEquals(commentAuthor, comment.getAuthor()); | |||
assertEquals("New Comment Text", comment.getString().getString()); | |||
assertEquals(cellRow, comment.getRow()); | |||
assertEquals(cellColumn, comment.getColumn()); | |||
assertFalse(comment.isVisible()); | |||
} | |||
/** | |||
* test that we can read cell comments from an existing workbook. | |||
*/ | |||
public void readComments(String sampleFile) { | |||
Workbook wb = getTestDataProvider().openSampleWorkbook(sampleFile); | |||
Sheet sheet = wb.getSheetAt(0); | |||
Cell cell; | |||
Row row; | |||
Comment comment; | |||
for (int rownum = 0; rownum < 3; rownum++) { | |||
row = sheet.getRow(rownum); | |||
cell = row.getCell(0); | |||
comment = cell.getCellComment(); | |||
assertNull("Cells in the first column are not commented", comment); | |||
assertNull(sheet.getCellComment(rownum, 0)); | |||
} | |||
for (int rownum = 0; rownum < 3; rownum++) { | |||
row = sheet.getRow(rownum); | |||
cell = row.getCell(1); | |||
comment = cell.getCellComment(); | |||
assertNotNull("Cells in the second column have comments", comment); | |||
assertNotNull("Cells in the second column have comments", sheet.getCellComment(rownum, 1)); | |||
assertEquals("Yegor Kozlov", comment.getAuthor()); | |||
assertFalse("cells in the second column have not empyy notes", | |||
"".equals(comment.getString().getString())); | |||
assertEquals(rownum, comment.getRow()); | |||
assertEquals(cell.getColumnIndex(), comment.getColumn()); | |||
} | |||
} | |||
/** | |||
* test that we can modify existing cell comments | |||
*/ | |||
public void modifyComments(String sampleFile) { | |||
Workbook wb = getTestDataProvider().openSampleWorkbook(sampleFile); | |||
CreationHelper factory = wb.getCreationHelper(); | |||
Sheet sheet = wb.getSheetAt(0); | |||
Cell cell; | |||
Row row; | |||
Comment comment; | |||
for (int rownum = 0; rownum < 3; rownum++) { | |||
row = sheet.getRow(rownum); | |||
cell = row.getCell(1); | |||
comment = cell.getCellComment(); | |||
comment.setAuthor("Mofified[" + rownum + "] by Yegor"); | |||
comment.setString(factory.createRichTextString("Modified comment at row " + rownum)); | |||
} | |||
wb = getTestDataProvider().writeOutAndReadBack(wb); | |||
sheet = wb.getSheetAt(0); | |||
for (int rownum = 0; rownum < 3; rownum++) { | |||
row = sheet.getRow(rownum); | |||
cell = row.getCell(1); | |||
comment = cell.getCellComment(); | |||
assertEquals("Mofified[" + rownum + "] by Yegor", comment.getAuthor()); | |||
assertEquals("Modified comment at row " + rownum, comment.getString().getString()); | |||
} | |||
} | |||
public void deleteComments(String sampleFile) throws Exception { | |||
Workbook wb = getTestDataProvider().openSampleWorkbook(sampleFile); | |||
Sheet sheet = wb.getSheetAt(0); | |||
// Zap from rows 1 and 3 | |||
assertNotNull(sheet.getRow(0).getCell(1).getCellComment()); | |||
assertNotNull(sheet.getRow(1).getCell(1).getCellComment()); | |||
assertNotNull(sheet.getRow(2).getCell(1).getCellComment()); | |||
sheet.getRow(0).getCell(1).removeCellComment(); | |||
sheet.getRow(2).getCell(1).setCellComment(null); | |||
// Check gone so far | |||
assertNull(sheet.getRow(0).getCell(1).getCellComment()); | |||
assertNotNull(sheet.getRow(1).getCell(1).getCellComment()); | |||
assertNull(sheet.getRow(2).getCell(1).getCellComment()); | |||
// Save and re-load | |||
wb = getTestDataProvider().writeOutAndReadBack(wb); | |||
sheet = wb.getSheetAt(0); | |||
// Check | |||
assertNull(sheet.getRow(0).getCell(1).getCellComment()); | |||
assertNotNull(sheet.getRow(1).getCell(1).getCellComment()); | |||
assertNull(sheet.getRow(2).getCell(1).getCellComment()); | |||
} | |||
/** | |||
* code from the quick guide | |||
*/ | |||
public void testQuickGuide(){ | |||
Workbook wb = getTestDataProvider().createWorkbook(); | |||
CreationHelper factory = wb.getCreationHelper(); | |||
Sheet sheet = wb.createSheet(); | |||
Cell cell = sheet.createRow(3).createCell(5); | |||
cell.setCellValue("F4"); | |||
Drawing drawing = sheet.createDrawingPatriarch(); | |||
ClientAnchor anchor = factory.createClientAnchor(); | |||
Comment comment = drawing.createCellComment(anchor); | |||
RichTextString str = factory.createRichTextString("Hello, World!"); | |||
comment.setString(str); | |||
comment.setAuthor("Apache POI"); | |||
//assign the comment to the cell | |||
cell.setCellComment(comment); | |||
wb = getTestDataProvider().writeOutAndReadBack(wb); | |||
sheet = wb.getSheetAt(0); | |||
cell = sheet.getRow(3).getCell(5); | |||
comment = cell.getCellComment(); | |||
assertNotNull(comment); | |||
assertEquals("Hello, World!", comment.getString().getString()); | |||
assertEquals("Apache POI", comment.getAuthor()); | |||
assertEquals(3, comment.getRow()); | |||
assertEquals(5, comment.getColumn()); | |||
} | |||
} |
@@ -0,0 +1,42 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<xml xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel"> | |||
<o:shapelayout v:ext="edit"> | |||
<o:idmap v:ext="edit" data="1"/> | |||
</o:shapelayout> | |||
<v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m,l,21600r21600,l21600,xe"> | |||
<v:stroke joinstyle="miter"/> | |||
<v:path gradientshapeok="t" o:connecttype="rect"/> | |||
</v:shapetype> | |||
<v:shape id="_x0000_s1025" type="#_x0000_t202" style="position:absolute; margin-left:59.25pt;margin-top:1.5pt;width:96pt;height:55.5pt;z-index:1; visibility:hidden" fillcolor="#ffffe1" o:insetmode="auto"> | |||
<v:fill color2="#ffffe1"/> | |||
<v:shadow on="t" color="black" obscured="t"/> | |||
<v:path o:connecttype="none"/> | |||
<v:textbox style="mso-direction-alt:auto"> | |||
<div style="text-align:left"/> | |||
</v:textbox> | |||
<x:ClientData ObjectType="Note"> | |||
<x:MoveWithCells/> | |||
<x:SizeWithCells/> | |||
<x:Anchor>1, 15, 0, 2, 3, 15, 3, 16</x:Anchor> | |||
<x:AutoFill>False</x:AutoFill> | |||
<x:Row>0</x:Row> | |||
<x:Column>0</x:Column> | |||
</x:ClientData> | |||
</v:shape> | |||
<v:shape id="_x0000_s1026" type="#_x0000_t202" style="position:absolute; visibility:hidden" fillcolor="#ffffe1" o:insetmode="auto"> | |||
<v:fill color2="#ffffe1"/> | |||
<v:shadow on="t" color="black" obscured="t"/> | |||
<v:path o:connecttype="none"/> | |||
<v:textbox style="mso-direction-alt:auto"> | |||
<div style="text-align:left"/> | |||
</v:textbox> | |||
<x:ClientData ObjectType="Note"> | |||
<x:MoveWithCells/> | |||
<x:SizeWithCells/> | |||
<x:Anchor>1, 15, 0, 2, 3, 15, 3, 16</x:Anchor> | |||
<x:AutoFill>False</x:AutoFill> | |||
<x:Row>0</x:Row> | |||
<x:Column>1</x:Column> | |||
</x:ClientData> | |||
</v:shape> | |||
</xml> |