mirror of https://github.com/apache/poi.git
improved work with cell comments in XSSF, also added support for cell comments to SS interfaces
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@884918 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
43e6a9c885
commit
21d7a81d3c
|
@ -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.
|
||||
</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:
|
||||
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>
|
||||
<source>
|
||||
HSSFWorkbook wb = new HSSFWorkbook();
|
||||
HSSFSheet sheet = wb.createSheet("Cell comments in POI HSSF");
|
||||
CreationHelper createHelper = wb.getCreationHelper();
|
||||
Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
|
||||
|
||||
// Create the drawing patriarch. This is the top level container for all shapes including cell comments.
|
||||
HSSFPatriarch patr = sheet.createDrawingPatriarch();
|
||||
CreationHelper factory = wb.getCreationHelper();
|
||||
|
||||
// Create a cell in row 3
|
||||
Cell cell1 = sheet.createRow(3).createCell((short)1);
|
||||
cell1.setCellValue(new HSSFRichTextString("Hello, World"));
|
||||
Sheet sheet = wb.createSheet();
|
||||
|
||||
// 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));
|
||||
Cell cell = sheet.createRow(3).createCell(5);
|
||||
cell.setCellValue("F4");
|
||||
|
||||
// set text in the comment
|
||||
comment1.setString(createHelper.createRichTextString("We can set comments in POI"));
|
||||
Drawing drawing = sheet.createDrawingPatriarch();
|
||||
|
||||
// set comment author.
|
||||
// you can see it in the status bar when moving mouse over the commented cell
|
||||
comment1.setAuthor("Apache Software Foundation");
|
||||
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);
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
// 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);
|
||||
|
||||
// Write out
|
||||
FileOutputStream out = new FileOutputStream("poi_comment.xls");
|
||||
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());
|
||||
public CTComment newComment() {
|
||||
CTComment ct = comments.getCommentList().addNewComment();
|
||||
ct.setRef("A1");
|
||||
ct.setAuthorId(0);
|
||||
return ct;
|
||||
}
|
||||
|
||||
private CTCommentList getCommentsList() {
|
||||
if (comments.getCommentList() == null) {
|
||||
comments.addNewCommentList();
|
||||
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.getCommentList();
|
||||
}
|
||||
|
||||
private CTAuthors getCommentsAuthors() {
|
||||
if (comments.getAuthors() == null) {
|
||||
comments.addNewAuthors();
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Name of the original comment author. Default value is blank.
|
||||
*/
|
||||
public String getAuthor() {
|
||||
return comments.getAuthor((int)comment.getAuthorId());
|
||||
}
|
||||
|
||||
public int getColumn() {
|
||||
return (new CellReference(comment.getRef())).getCol();
|
||||
}
|
||||
|
||||
public int getRow() {
|
||||
return (new CellReference(comment.getRef())).getRow();
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
// TODO Auto-generated method stub
|
||||
return true;
|
||||
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)
|
||||
_comment.setAuthorId(
|
||||
_comments.findAuthor(author)
|
||||
);
|
||||
}
|
||||
|
||||
public void setColumn(short col) {
|
||||
initializeRef();
|
||||
String newRef =
|
||||
(new CellReference(getRow(), col)).formatAsString();
|
||||
comment.setRef(newRef);
|
||||
/**
|
||||
* @return the 0-based column of the cell that the comment is associated with.
|
||||
*/
|
||||
public int getColumn() {
|
||||
return new CellReference(_comment.getRef()).getCol();
|
||||
}
|
||||
|
||||
private void initializeRef() {
|
||||
if (comment.getRef() == null) {
|
||||
comment.setRef("A1");
|
||||
/**
|
||||
* @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 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(1, sheetComments.getNumberOfAuthors());
|
||||
assertEquals(0, sheetComments.findAuthor(""));
|
||||
assertEquals("", sheetComments.getAuthor(0));
|
||||
|
||||
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.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));
|
||||
assertSame(comment0, sheetComments.getCTComment("A1"));
|
||||
assertSame(comment1, sheetComments.getCTComment("A2"));
|
||||
assertNull(sheetComments.getCTComment("A3"));
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
CTComment ctComment = CTComment.Factory.newInstance();
|
||||
XSSFComment comment2 = new XSSFComment(sheetComments, ctComment);
|
||||
assertNotNull(comment2);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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 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);
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
doc.save(out, POIXMLDocumentPart.DEFAULT_XML_OPTIONS);
|
||||
|
||||
CommentsTable sheetComments = new CommentsTable();
|
||||
sheetComments.readFrom(new ByteArrayInputStream(out.toByteArray()));
|
||||
XSSFComment comment = new XSSFComment(sheetComments, ctComment);
|
||||
assertEquals(TEST_AUTHOR, comment.getAuthor());
|
||||
}
|
||||
|
||||
public void testSetColumn() {
|
||||
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());
|
||||
}
|
||||
|
||||
public void testSetRow() {
|
||||
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());
|
||||
}
|
||||
|
||||
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() {
|
||||
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());
|
||||
@Override
|
||||
protected XSSFITestDataProvider getTestDataProvider(){
|
||||
return XSSFITestDataProvider.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that we can add comments to a new
|
||||
* file, save, load, and still see them
|
||||
* @throws Exception
|
||||
* test that we can read cell comments from an existing workbook.
|
||||
*/
|
||||
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());
|
||||
public void testReadComments() {
|
||||
readComments("SimpleWithComments.xlsx");
|
||||
}
|
||||
|
||||
/**
|
||||
* test that we can modify existing cell comments
|
||||
*/
|
||||
public void testModifyComments() throws IOException {
|
||||
modifyComments("SimpleWithComments.xlsx");
|
||||
}
|
||||
|
||||
public void testDeleteComments() throws Exception {
|
||||
deleteComments("SimpleWithComments.xlsx");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
|
||||
CTComment ctComment = sheetComments.newComment();
|
||||
CTShape vmlShape = CTShape.Factory.newInstance();
|
||||
|
||||
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 testGetSetCol() {
|
||||
CommentsTable sheetComments = new CommentsTable();
|
||||
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 testGetSetRow() {
|
||||
CommentsTable sheetComments = new CommentsTable();
|
||||
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 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 testAuthor() {
|
||||
CommentsTable sheetComments = new CommentsTable();
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
public final class TestHSSFComment extends BaseTestCellComment {
|
||||
|
||||
/**
|
||||
* 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();
|
||||
@Override
|
||||
protected HSSFITestDataProvider getTestDataProvider(){
|
||||
return HSSFITestDataProvider.getInstance();
|
||||
}
|
||||
|
||||
//verify our settings
|
||||
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(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();
|
||||
|
||||
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();
|
||||
|
||||
assertNotNull(comment);
|
||||
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());
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -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>
|
Loading…
Reference in New Issue