All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.jett.tag.CommentTag Maven / Gradle / Ivy

package net.sf.jett.tag;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFCell;

import net.sf.jett.exception.TagParseException;
import net.sf.jett.model.Block;
import net.sf.jett.model.WorkbookContext;
import net.sf.jett.transform.BlockTransformer;
import net.sf.jett.util.AttributeUtil;
import net.sf.jett.util.SheetUtil;

/**
 * 

A CommentTag represents a Cell that needs to have an Excel * Comment attached to it. It controls Comment properties such author, the * Rich Text string comment, and whether the Comment is initially visible.

* *

This tag uses the POI method createDrawingPatriarch to * create an Excel comment on the Cell on which the tag is * located. The POI documentation warns of corrupting other "drawings" such as * charts and "complex" drawings when calling getDrawingPatriarch * (HSSF code). When testing both .xls and .xlsx template spreadsheets, it * appears that drawings and charts do get corrupted in .xls spreadsheets, but * they do NOT get corrupted in .xlsx spreadsheets.

* *
Attributes: *
    *
  • Inherits all attributes from {@link BaseTag}.
  • *
  • value (required): RichTextString
  • *
  • author (required): String
  • *
  • comment (required): RichTextString
  • *
  • visible (optional): boolean
  • *
* * @author Randy Gettman * @since 0.2.0 */ public class CommentTag extends BaseTag { /** * Attribute that specifies the value of the Cell itself after * transformation. */ public static final String ATTR_VALUE = "value"; /** * Attribute that specifies the author of the Comment to be created. */ public static final String ATTR_AUTHOR = "author"; /** * Attribute that specifies the comment text. */ public static final String ATTR_COMMENT = "comment"; /** * Attribute that specifies whether the comment is initially visible. Even * if not initially visible, the user can mouseover a cell with a comment to * view the comment text as a pop-up. */ public static final String ATTR_VISIBLE = "visible"; private static final List REQ_ATTRS = new ArrayList<>(Arrays.asList(ATTR_VALUE, ATTR_AUTHOR, ATTR_COMMENT)); private static final List OPT_ATTRS = new ArrayList<>(Arrays.asList(ATTR_VISIBLE)); private RichTextString myValue; private RichTextString myAuthor; private RichTextString myComment; private boolean amIVisible; /** * Returns this Tag's name. * @return This Tag's name. */ @Override public String getName() { return "comment"; } /** * Returns a List of required attribute names. * @return A List of required attribute names. */ @Override protected List getRequiredAttributes() { List reqAttrs = new ArrayList<>(super.getRequiredAttributes()); reqAttrs.addAll(REQ_ATTRS); return reqAttrs; } /** * Returns a List of optional attribute names. * @return A List of optional attribute names. */ @Override protected List getOptionalAttributes() { List optAttrs = new ArrayList<>(super.getOptionalAttributes()); optAttrs.addAll(OPT_ATTRS); return optAttrs; } /** * Validates the attributes for this Tag. This tag must be * bodiless. */ @SuppressWarnings("unchecked") @Override public void validateAttributes() throws TagParseException { super.validateAttributes(); if (!isBodiless()) throw new TagParseException("Comment tags must not have a body. Comment tag with body found" + getLocation()); TagContext context = getContext(); Map beans = context.getBeans(); Map attributes = getAttributes(); myValue = attributes.get(ATTR_VALUE); myAuthor = attributes.get(ATTR_AUTHOR); myComment = attributes.get(ATTR_COMMENT); amIVisible = AttributeUtil.evaluateBoolean(this, attributes.get(ATTR_VISIBLE), beans, false); } /** *

Place the "value" attribute in the cell, and the rest of the * attributes control the creation of a cell comment.

* @return Whether the first Cell in the Block * associated with this Tag was processed. */ @Override public boolean process() { TagContext context = getContext(); Sheet sheet = context.getSheet(); Block block = context.getBlock(); Map beans = context.getBeans(); int left = block.getLeftColNum(); int top = block.getTopRowNum(); // It should exist in this Cell; this Tag was found in it. Row row = sheet.getRow(top); Cell cell = row.getCell(left); WorkbookContext workbookContext = getWorkbookContext(); SheetUtil.setCellValue(workbookContext, cell, myValue); Drawing drawing = context.getOrCreateDrawing(); CreationHelper helper = sheet.getWorkbook().getCreationHelper(); ClientAnchor anchor = helper.createClientAnchor(); Object commentString = AttributeUtil.evaluateRichTextStringNotNull(this, myComment, helper, beans, ATTR_COMMENT, ""); String author = AttributeUtil.evaluateStringNotNull(this, myAuthor, beans, ATTR_AUTHOR, ""); int commentLength; if (commentString instanceof RichTextString) { commentLength = ((RichTextString) commentString).length(); } else { commentLength = commentString.toString().length(); } // Calculate number of rows/cols to fit the comment text. Try adding a // column, then adding a row, repeatedly, until we are sure that a box of // that size will hold the comment text. int rows = 0; int cols = 0; double width = 0; double height = 0; double fontHeightPoints = (cell instanceof HSSFCell) ? ((HSSFCell) cell).getCellStyle().getFont(sheet.getWorkbook()).getFontHeightInPoints() : ((XSSFCell) cell).getCellStyle().getFont().getFontHeightInPoints(); while (width * height < commentLength) { cols++; width += sheet.getColumnWidth(left + cols) / 256; if (width * height >= commentLength) break; Row r = sheet.getRow(top + rows); if (r == null) r = sheet.createRow(top + rows); height += r.getHeightInPoints() / fontHeightPoints; rows++; } // HSSFComments seem to need an extra row's worth of height. if (cell instanceof HSSFCell) rows++; anchor.setCol1(left); anchor.setCol2(left + cols); anchor.setRow1(top); anchor.setRow2(top + rows); Comment comment = drawing.createCellComment(anchor); comment.setAuthor(author); if (commentString instanceof RichTextString) { comment.setString((RichTextString) commentString); } else { comment.setString(helper.createRichTextString(commentString.toString())); } comment.setVisible(amIVisible); cell.setCellComment(comment); BlockTransformer transformer = new BlockTransformer(); transformer.transform(context, workbookContext); return true; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy