common ss interfaces for drawing, clientacnhor and picture, also some refactoring of common hssf-xssf code

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@713279 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2008-11-12 07:15:37 +00:00
parent 5a5ab51f2b
commit af7f84c27e
17 changed files with 280 additions and 689 deletions

View File

@ -1163,63 +1163,45 @@ Examples:
It should be noted that any existing drawings may be erased
once you add a image to a sheet.
</p>
<p><strong>HSSF:</strong></p>
<source>
// Create the drawing patriarch. This is the top level container for
// all shapes. This will clear out any existing shapes for that sheet.
HSSFPatriarch patriarch = sheet5.createDrawingPatriarch();
HSSFClientAnchor anchor;
anchor = new HSSFClientAnchor(0,0,0,255,(short)2,2,(short)4,7);
anchor.setAnchorType( 2 );
patriarch.createPicture(anchor, loadPicture( "src/resources/logos/logoKarmokar4.png", wb ));
</source>
<p>Creating an image and setting its anchor to the actual width and height:</p>
<source>
HSSFPatriarch patriarch = sheet5.createDrawingPatriarch();
HSSFPicture picture = patriarch.createPicture(new HSSFClientAnchor(), loadPicture( "src/resources/logos/logoKarmokar4.png", wb ));
picture.resize();
</source>
<p>or</p>
<source>
HSSFPatriarch patriarch = sheet5.createDrawingPatriarch();
HSSFPicture picture = patriarch.createPicture(new HSSFClientAnchor(), loadPicture( "src/resources/logos/logoKarmokar4.png", wb ));
HSSFClientAnchor preferredSize = picture.getPreferredSize();
picture.setAnchor(preferredSize);
</source>
<p><strong>XSSF:</strong></p>
<source>
//create a new workbook
XSSFWorkbook wb = new XSSFWorkbook();
Workbook wb = new XSSFWorkbook(); //or new HSSFWorkbook();
//add a picture in this workbook.
InputStream is = new FileInputStream("lilies.jpg");
int pictureIdx = wb.addPicture(is, XSSFWorkbook.PICTURE_TYPE_JPEG);
//add picture data to this workbook.
InputStream is = new FileInputStream("image1.jpeg");
byte[] bytes = IOUtils.toByteArray(is);
int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
is.close();
//create sheet
XSSFSheet sheet = wb.createSheet();
CreationHelper helper = wb.getCreationHelper();
//create drawing
XSSFDrawing drawing = sheet.createDrawingPatriarch();
//create sheet
Sheet sheet = wb.createSheet();
// Create the drawing patriarch. This is the top level container for all shapes.
Drawing drawing = sheet.createDrawingPatriarch();
//add a picture shape
XSSFPicture pict = drawing.createPicture(new XSSFClientAnchor(), pictureIdx);
ClientAnchor anchor = helper.createClientAnchor();
//set top-left corner of the picture,
//subsequent call of Picture#resize() will operate relative to it
anchor.setCol1(3);
anchor.setRow1(2);
Picture pict = drawing.createPicture(anchor, pictureIdx);
//auto-size picture
//auto-size picture relative to its top-left corner
pict.resize();
//save workbook
FileOutputStream fileOut = new FileOutputStream("xssf-picture.xlsx");
String file = "picture.xls";
if(wb instanceof XSSFWorkbook) file += "x";
FileOutputStream fileOut = new FileOutputStream(file);
wb.write(fileOut);
fileOut.close();
</source>
</source>
<warning>
HSSFPicture.resize() and XSSFPicture.resize() work only for JPEG and PNG. Other formats are not yet supported.
Picture.resize() works only for JPEG and PNG. Other formats are not yet supported.
</warning>
<p>Reading images from a workbook:</p>
<source>

View File

@ -17,7 +17,7 @@
package org.apache.poi.hssf.usermodel;
import org.apache.poi.ss.usermodel.ClientAnchor;
/**
@ -27,7 +27,7 @@ package org.apache.poi.hssf.usermodel;
* @author Glen Stampoultzis (glens at apache.org)
*/
public class HSSFClientAnchor
extends HSSFAnchor
extends HSSFAnchor implements ClientAnchor
{
short col1;
int row1;
@ -124,6 +124,9 @@ public class HSSFClientAnchor
checkRange(col1, 0, 255, "col1");
this.col1 = col1;
}
public void setCol1( int col1 ){
setCol1((short)col1);
}
public short getCol2()
{
@ -136,6 +139,10 @@ public class HSSFClientAnchor
this.col2 = col2;
}
public void setCol2( int col2 ){
setCol2((short)col2);
}
public int getRow1()
{
return row1;

View File

@ -54,4 +54,14 @@ public class HSSFCreationHelper implements CreationHelper {
return new HSSFFormulaEvaluator(workbook);
}
/**
* Creates a HSSFClientAnchor. Use this object to position drawing object in a sheet
*
* @return a HSSFClientAnchor instance
* @see org.apache.poi.ss.usermodel.Drawing
*/
public HSSFClientAnchor createClientAnchor(){
return new HSSFClientAnchor();
}
}

View File

@ -17,6 +17,8 @@
package org.apache.poi.hssf.usermodel;
import org.apache.poi.ss.usermodel.DataFormatter;
import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.text.Format;
@ -73,611 +75,6 @@ import java.util.regex.Pattern;
* @author James May (james dot may at fmr dot com)
*
*/
public final class HSSFDataFormatter {
public final class HSSFDataFormatter extends DataFormatter {
/** Pattern to find a number format: "0" or "#" */
private static final Pattern numPattern = Pattern.compile("[0#]+");
/** Pattern to find days of week as text "ddd...." */
private static final Pattern daysAsText = Pattern.compile("([d]{3,})", Pattern.CASE_INSENSITIVE);
/** Pattern to find "AM/PM" marker */
private static final Pattern amPmPattern = Pattern.compile("((A|P)[M/P]*)", Pattern.CASE_INSENSITIVE);
/** A regex to find patterns like [$$-1009] and [$<24>-452]. */
private static final Pattern specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])");
/** <em>General</em> format for whole numbers. */
private static final Format generalWholeNumFormat = new DecimalFormat("#");
/** <em>General</em> format for decimal numbers. */
private static final Format generalDecimalNumFormat = new DecimalFormat("#.##########");
/** A default format to use when a number pattern cannot be parsed. */
private Format defaultNumFormat;
/**
* A map to cache formats.
* Map<String,Format> formats
*/
private final Map formats;
/**
* Constructor
*/
public HSSFDataFormatter() {
formats = new HashMap();
// init built-in formats
Format zipFormat = ZipPlusFourFormat.instance;
addFormat("00000\\-0000", zipFormat);
addFormat("00000-0000", zipFormat);
Format phoneFormat = PhoneFormat.instance;
// allow for format string variations
addFormat("[<=9999999]###\\-####;\\(###\\)\\ ###\\-####", phoneFormat);
addFormat("[<=9999999]###-####;(###) ###-####", phoneFormat);
addFormat("###\\-####;\\(###\\)\\ ###\\-####", phoneFormat);
addFormat("###-####;(###) ###-####", phoneFormat);
Format ssnFormat = SSNFormat.instance;
addFormat("000\\-00\\-0000", ssnFormat);
addFormat("000-00-0000", ssnFormat);
}
/**
* Return a Format for the given cell if one exists, otherwise try to
* create one. This method will return <code>null</code> if the any of the
* following is true:
* <ul>
* <li>the cell's style is null</li>
* <li>the style's data format string is null or empty</li>
* <li>the format string cannot be recognized as either a number or date</li>
* </ul>
*
* @param cell The cell to retrieve a Format for
* @return A Format for the format String
*/
private Format getFormat(HSSFCell cell) {
if ( cell.getCellStyle() == null) {
return null;
}
int formatIndex = cell.getCellStyle().getDataFormat();
String formatStr = cell.getCellStyle().getDataFormatString();
if(formatStr == null || formatStr.trim().length() == 0) {
return null;
}
return getFormat(cell.getNumericCellValue(), formatIndex, formatStr);
}
private Format getFormat(double cellValue, int formatIndex, String formatStr) {
Format format = (Format)formats.get(formatStr);
if (format != null) {
return format;
}
if (formatStr.equals("General")) {
if (HSSFDataFormatter.isWholeNumber(cellValue)) {
return generalWholeNumFormat;
}
return generalDecimalNumFormat;
}
format = createFormat(cellValue, formatIndex, formatStr);
formats.put(formatStr, format);
return format;
}
/**
* Create and return a Format based on the format string from a cell's
* style. If the pattern cannot be parsed, return a default pattern.
*
* @param cell The Excel cell
* @return A Format representing the excel format. May return null.
*/
public Format createFormat(HSSFCell cell) {
int formatIndex = cell.getCellStyle().getDataFormat();
String formatStr = cell.getCellStyle().getDataFormatString();
return createFormat(cell.getNumericCellValue(), formatIndex, formatStr);
}
private Format createFormat(double cellValue, int formatIndex, String sFormat) {
// remove color formatting if present
String formatStr = sFormat.replaceAll("\\[[a-zA-Z]*\\]", "");
// try to extract special characters like currency
Matcher m = specialPatternGroup.matcher(formatStr);
while(m.find()) {
String match = m.group();
String symbol = match.substring(match.indexOf('$') + 1, match.indexOf('-'));
if (symbol.indexOf('$') > -1) {
StringBuffer sb = new StringBuffer();
sb.append(symbol.substring(0, symbol.indexOf('$')));
sb.append('\\');
sb.append(symbol.substring(symbol.indexOf('$'), symbol.length()));
symbol = sb.toString();
}
formatStr = m.replaceAll(symbol);
m = specialPatternGroup.matcher(formatStr);
}
if(formatStr == null || formatStr.trim().length() == 0) {
return getDefaultFormat(cellValue);
}
if(HSSFDateUtil.isADateFormat(formatIndex,formatStr) &&
HSSFDateUtil.isValidExcelDate(cellValue)) {
return createDateFormat(formatStr, cellValue);
}
if (numPattern.matcher(formatStr).find()) {
return createNumberFormat(formatStr, cellValue);
}
// TODO - when does this occur?
return null;
}
private Format createDateFormat(String pFormatStr, double cellValue) {
String formatStr = pFormatStr;
formatStr = formatStr.replaceAll("\\\\-","-");
formatStr = formatStr.replaceAll("\\\\,",",");
formatStr = formatStr.replaceAll("\\\\ "," ");
formatStr = formatStr.replaceAll(";@", "");
boolean hasAmPm = false;
Matcher amPmMatcher = amPmPattern.matcher(formatStr);
while (amPmMatcher.find()) {
formatStr = amPmMatcher.replaceAll("@");
hasAmPm = true;
amPmMatcher = amPmPattern.matcher(formatStr);
}
formatStr = formatStr.replaceAll("@", "a");
Matcher dateMatcher = daysAsText.matcher(formatStr);
if (dateMatcher.find()) {
String match = dateMatcher.group(0);
formatStr = dateMatcher.replaceAll(match.toUpperCase().replaceAll("D", "E"));
}
// Convert excel date format to SimpleDateFormat.
// Excel uses lower case 'm' for both minutes and months.
// From Excel help:
/*
The "m" or "mm" code must appear immediately after the "h" or"hh"
code or immediately before the "ss" code; otherwise, Microsoft
Excel displays the month instead of minutes."
*/
StringBuffer sb = new StringBuffer();
char[] chars = formatStr.toCharArray();
boolean mIsMonth = true;
List ms = new ArrayList();
for(int j=0; j<chars.length; j++) {
char c = chars[j];
if (c == 'h' || c == 'H') {
mIsMonth = false;
if (hasAmPm) {
sb.append('h');
} else {
sb.append('H');
}
}
else if (c == 'm') {
if(mIsMonth) {
sb.append('M');
ms.add(
new Integer(sb.length() -1)
);
} else {
sb.append('m');
}
}
else if (c == 's' || c == 'S') {
sb.append('s');
// if 'M' precedes 's' it should be minutes ('m')
for (int i = 0; i < ms.size(); i++) {
int index = ((Integer)ms.get(i)).intValue();
if (sb.charAt(index) == 'M') {
sb.replace(index, index+1, "m");
}
}
mIsMonth = true;
ms.clear();
}
else if (Character.isLetter(c)) {
mIsMonth = true;
ms.clear();
if (c == 'y' || c == 'Y') {
sb.append('y');
}
else if (c == 'd' || c == 'D') {
sb.append('d');
}
else {
sb.append(c);
}
}
else {
sb.append(c);
}
}
formatStr = sb.toString();
try {
return new SimpleDateFormat(formatStr);
} catch(IllegalArgumentException iae) {
// the pattern could not be parsed correctly,
// so fall back to the default number format
return getDefaultFormat(cellValue);
}
}
private Format createNumberFormat(String formatStr, double cellValue) {
StringBuffer sb = new StringBuffer(formatStr);
for (int i = 0; i < sb.length(); i++) {
char c = sb.charAt(i);
//handle (#,##0_);
if (c == '(') {
int idx = sb.indexOf(")", i);
if (idx > -1 && sb.charAt(idx -1) == '_') {
sb.deleteCharAt(idx);
sb.deleteCharAt(idx - 1);
sb.deleteCharAt(i);
i--;
}
} else if (c == ')' && i > 0 && sb.charAt(i - 1) == '_') {
sb.deleteCharAt(i);
sb.deleteCharAt(i - 1);
i--;
// remove quotes and back slashes
} else if (c == '\\' || c == '"') {
sb.deleteCharAt(i);
i--;
// for scientific/engineering notation
} else if (c == '+' && i > 0 && sb.charAt(i - 1) == 'E') {
sb.deleteCharAt(i);
i--;
}
}
try {
return new DecimalFormat(sb.toString());
} catch(IllegalArgumentException iae) {
// the pattern could not be parsed correctly,
// so fall back to the default number format
return getDefaultFormat(cellValue);
}
}
/**
* Return true if the double value represents a whole number
* @param d the double value to check
* @return <code>true</code> if d is a whole number
*/
private static boolean isWholeNumber(double d) {
return d == Math.floor(d);
}
/**
* Returns a default format for a cell.
* @param cell The cell
* @return a default format
*/
public Format getDefaultFormat(HSSFCell cell) {
return getDefaultFormat(cell.getNumericCellValue());
}
private Format getDefaultFormat(double cellValue) {
// for numeric cells try user supplied default
if (defaultNumFormat != null) {
return defaultNumFormat;
// otherwise use general format
}
if (isWholeNumber(cellValue)){
return generalWholeNumFormat;
}
return generalDecimalNumFormat;
}
/**
* Returns the formatted value of an Excel date as a <tt>String</tt> based
* on the cell's <code>DataFormat</code>. i.e. "Thursday, January 02, 2003"
* , "01/02/2003" , "02-Jan" , etc.
*
* @param cell The cell
* @return a formatted date string
*/
private String getFormattedDateString(HSSFCell cell) {
Format dateFormat = getFormat(cell);
Date d = cell.getDateCellValue();
if (dateFormat != null) {
return dateFormat.format(d);
}
return d.toString();
}
/**
* Returns the formatted value of an Excel number as a <tt>String</tt>
* based on the cell's <code>DataFormat</code>. Supported formats include
* currency, percents, decimals, phone number, SSN, etc.:
* "61.54%", "$100.00", "(800) 555-1234".
*
* @param cell The cell
* @return a formatted number string
*/
private String getFormattedNumberString(HSSFCell cell) {
Format numberFormat = getFormat(cell);
double d = cell.getNumericCellValue();
if (numberFormat == null) {
return String.valueOf(d);
}
return numberFormat.format(new Double(d));
}
/**
* Formats the given raw cell value, based on the supplied
* format index and string, according to excel style rules.
* @see #formatCellValue(HSSFCell)
*/
public String formatRawCellContents(double value, int formatIndex, String formatString) {
// Is it a date?
if(HSSFDateUtil.isADateFormat(formatIndex,formatString) &&
HSSFDateUtil.isValidExcelDate(value)) {
Format dateFormat = getFormat(value, formatIndex, formatString);
Date d = HSSFDateUtil.getJavaDate(value);
if (dateFormat == null) {
return d.toString();
}
return dateFormat.format(d);
}
// else Number
Format numberFormat = getFormat(value, formatIndex, formatString);
if (numberFormat == null) {
return String.valueOf(value);
}
return numberFormat.format(new Double(value));
}
/**
* <p>
* Returns the formatted value of a cell as a <tt>String</tt> regardless
* of the cell type. If the Excel format pattern cannot be parsed then the
* cell value will be formatted using a default format.
* </p>
* <p>When passed a null or blank cell, this method will return an empty
* String (""). Formulas in formula type cells will not be evaluated.
* </p>
*
* @param cell The cell
* @return the formatted cell value as a String
*/
public String formatCellValue(HSSFCell cell) {
return formatCellValue(cell, null);
}
/**
* <p>
* Returns the formatted value of a cell as a <tt>String</tt> regardless
* of the cell type. If the Excel format pattern cannot be parsed then the
* cell value will be formatted using a default format.
* </p>
* <p>When passed a null or blank cell, this method will return an empty
* String (""). Formula cells will be evaluated using the given
* {@link HSSFFormulaEvaluator} if the evaluator is non-null. If the
* evaluator is null, then the formula String will be returned. The caller
* is responsible for setting the currentRow on the evaluator
*</p>
*
* @param cell The cell (can be null)
* @param evaluator The HSSFFormulaEvaluator (can be null)
* @return a string value of the cell
*/
public String formatCellValue(HSSFCell cell,
HSSFFormulaEvaluator evaluator) throws IllegalArgumentException {
if (cell == null) {
return "";
}
int cellType = cell.getCellType();
if (evaluator != null && cellType == HSSFCell.CELL_TYPE_FORMULA) {
try {
cellType = evaluator.evaluateFormulaCell(cell);
} catch (RuntimeException e) {
throw new RuntimeException("Did you forget to set the current" +
" row on the HSSFFormulaEvaluator?", e);
}
}
switch (cellType)
{
case HSSFCell.CELL_TYPE_FORMULA :
// should only occur if evaluator is null
return cell.getCellFormula();
case HSSFCell.CELL_TYPE_NUMERIC :
if (HSSFDateUtil.isCellDateFormatted(cell)) {
return getFormattedDateString(cell);
}
return getFormattedNumberString(cell);
case HSSFCell.CELL_TYPE_STRING :
return cell.getRichStringCellValue().getString();
case HSSFCell.CELL_TYPE_BOOLEAN :
return String.valueOf(cell.getBooleanCellValue());
case HSSFCell.CELL_TYPE_BLANK :
return "";
}
throw new RuntimeException("Unexpected celltype (" + cellType + ")");
}
/**
* <p>
* Sets a default number format to be used when the Excel format cannot be
* parsed successfully. <b>Note:</b> This is a fall back for when an error
* occurs while parsing an Excel number format pattern. This will not
* affect cells with the <em>General</em> format.
* </p>
* <p>
* The value that will be passed to the Format's format method (specified
* by <code>java.text.Format#format</code>) will be a double value from a
* numeric cell. Therefore the code in the format method should expect a
* <code>Number</code> value.
* </p>
*
* @param format A Format instance to be used as a default
* @see java.text.Format#format
*/
public void setDefaultNumberFormat(Format format) {
Iterator itr = formats.entrySet().iterator();
while(itr.hasNext()) {
Map.Entry entry = (Map.Entry)itr.next();
if (entry.getValue() == generalDecimalNumFormat
|| entry.getValue() == generalWholeNumFormat) {
entry.setValue(format);
}
}
defaultNumFormat = format;
}
/**
* Adds a new format to the available formats.
* <p>
* The value that will be passed to the Format's format method (specified
* by <code>java.text.Format#format</code>) will be a double value from a
* numeric cell. Therefore the code in the format method should expect a
* <code>Number</code> value.
* </p>
* @param excelFormatStr The data format string
* @param format A Format instance
*/
public void addFormat(String excelFormatStr, Format format) {
formats.put(excelFormatStr, format);
}
// Some custom formats
/**
* @return a <tt>DecimalFormat</tt> with parseIntegerOnly set <code>true</code>
*/
/* package */ static DecimalFormat createIntegerOnlyFormat(String fmt) {
DecimalFormat result = new DecimalFormat(fmt);
result.setParseIntegerOnly(true);
return result;
}
/**
* Format class for Excel's SSN format. This class mimics Excel's built-in
* SSN formatting.
*
* @author James May
*/
private static final class SSNFormat extends Format {
public static final Format instance = new SSNFormat();
private static final DecimalFormat df = createIntegerOnlyFormat("000000000");
private SSNFormat() {
// enforce singleton
}
/** Format a number as an SSN */
public static String format(Number num) {
String result = df.format(num);
StringBuffer sb = new StringBuffer();
sb.append(result.substring(0, 3)).append('-');
sb.append(result.substring(3, 5)).append('-');
sb.append(result.substring(5, 9));
return sb.toString();
}
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
return toAppendTo.append(format((Number)obj));
}
public Object parseObject(String source, ParsePosition pos) {
return df.parseObject(source, pos);
}
}
/**
* Format class for Excel Zip + 4 format. This class mimics Excel's
* built-in formatting for Zip + 4.
* @author James May
*/
private static final class ZipPlusFourFormat extends Format {
public static final Format instance = new ZipPlusFourFormat();
private static final DecimalFormat df = createIntegerOnlyFormat("000000000");
private ZipPlusFourFormat() {
// enforce singleton
}
/** Format a number as Zip + 4 */
public static String format(Number num) {
String result = df.format(num);
StringBuffer sb = new StringBuffer();
sb.append(result.substring(0, 5)).append('-');
sb.append(result.substring(5, 9));
return sb.toString();
}
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
return toAppendTo.append(format((Number)obj));
}
public Object parseObject(String source, ParsePosition pos) {
return df.parseObject(source, pos);
}
}
/**
* Format class for Excel phone number format. This class mimics Excel's
* built-in phone number formatting.
* @author James May
*/
private static final class PhoneFormat extends Format {
public static final Format instance = new PhoneFormat();
private static final DecimalFormat df = createIntegerOnlyFormat("##########");
private PhoneFormat() {
// enforce singleton
}
/** Format a number as a phone number */
public static String format(Number num) {
String result = df.format(num);
StringBuffer sb = new StringBuffer();
String seg1, seg2, seg3;
int len = result.length();
if (len <= 4) {
return result;
}
seg3 = result.substring(len - 4, len);
seg2 = result.substring(Math.max(0, len - 7), len - 4);
seg1 = result.substring(Math.max(0, len - 10), Math.max(0, len - 7));
if(seg1 != null && seg1.trim().length() > 0) {
sb.append('(').append(seg1).append(") ");
}
if(seg2 != null && seg2.trim().length() > 0) {
sb.append(seg2).append('-');
}
sb.append(seg3);
return sb.toString();
}
public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
return toAppendTo.append(format((Number)obj));
}
public Object parseObject(String source, ParsePosition pos) {
return df.parseObject(source, pos);
}
}
}

View File

@ -26,6 +26,8 @@ import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherProperty;
import org.apache.poi.hssf.record.EscherAggregate;
import org.apache.poi.util.StringUtil;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.ClientAnchor;
/**
* The patriarch is the toplevel container for shapes in a sheet. It does
@ -34,7 +36,7 @@ import org.apache.poi.util.StringUtil;
* @author Glen Stampoultzis (glens at apache.org)
*/
public class HSSFPatriarch
implements HSSFShapeContainer
implements HSSFShapeContainer, Drawing
{
List shapes = new ArrayList();
HSSFSheet sheet;
@ -108,7 +110,10 @@ public class HSSFPatriarch
shapes.add(shape);
return shape;
}
public HSSFPicture createPicture(ClientAnchor anchor, int pictureIndex)
{
return createPicture((HSSFClientAnchor)anchor, pictureIndex);
}
/**
* Creates a polygon
@ -187,7 +192,7 @@ public class HSSFPatriarch
this.x2 = x2;
this.y2 = y2;
}
/**
* Does this HSSFPatriarch contain a chart?
* (Technically a reference to a chart, since they
@ -197,7 +202,7 @@ public class HSSFPatriarch
*/
public boolean containsChart() {
// TODO - support charts properly in usermodel
// We're looking for a EscherOptRecord
EscherOptRecord optRecord = (EscherOptRecord)
boundAggregate.findFirstWithId(EscherOptRecord.RECORD_ID);
@ -205,7 +210,7 @@ public class HSSFPatriarch
// No opt record, can't have chart
return false;
}
for(Iterator it = optRecord.getEscherProperties().iterator(); it.hasNext();) {
EscherProperty prop = (EscherProperty)it.next();
if(prop.getPropertyNumber() == 896 && prop.isComplex()) {

View File

@ -19,6 +19,7 @@ package org.apache.poi.hssf.usermodel;
import org.apache.poi.ddf.EscherBSERecord;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.ss.usermodel.Picture;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
@ -38,7 +39,7 @@ import java.util.Iterator;
* @author Yegor Kozlov (yegor at apache.org)
*/
public class HSSFPicture
extends HSSFSimpleShape
extends HSSFSimpleShape implements Picture
{
public static final int PICTURE_TYPE_EMF = HSSFWorkbook.PICTURE_TYPE_EMF; // Windows Enhanced Metafile
public static final int PICTURE_TYPE_WMF = HSSFWorkbook.PICTURE_TYPE_WMF; // Windows Metafile

View File

@ -20,7 +20,6 @@ package org.apache.poi.hssf.util;
import java.lang.reflect.Field;
import java.util.Hashtable;
import org.apache.poi.ss.usermodel.Color;
/**
* Intends to provide support for the very evil index to triplet issue and
@ -35,7 +34,7 @@ import org.apache.poi.ss.usermodel.Color;
* @author Andrew C. Oliver (acoliver at apache dot org)
* @author Brian Sanders (bsanders at risklabs dot com) - full default color palette
*/
public class HSSFColor implements Color {
public class HSSFColor {
// TODO make subclass instances immutable
/** Creates a new instance of HSSFColor */

View File

@ -63,7 +63,7 @@ import java.text.*;
* @author James May (james dot may at fmr dot com)
*
*/
public final class DataFormatter {
public class DataFormatter {
/** Pattern to find a number format: "0" or "#" */
private static final Pattern numPattern = Pattern.compile("[0#]+");

View File

@ -0,0 +1,138 @@
/* ====================================================================
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;
/**
* A client anchor is attached to an excel worksheet. It anchors against a
* top-left and bottom-right cell.
*
* @author Yegor Kozlov
*/
public interface ClientAnchor {
/**
* Returns the column (0 based) of the first cell.
*
* @return 0-based column of the first cell.
*/
public short getCol1();
/**
* Sets the column (0 based) of the first cell.
*
* @param col1 0-based column of the first cell.
*/
public void setCol1(int col1);
/**
* Returns the column (0 based) of the second cell.
*
* @return 0-based column of the second cell.
*/
public short getCol2();
/**
* Returns the column (0 based) of the second cell.
*
* @param col2 0-based column of the second cell.
*/
public void setCol2(int col2);
/**
* Returns the row (0 based) of the first cell.
*
* @return 0-based row of the first cell.
*/
public int getRow1();
/**
* Returns the row (0 based) of the first cell.
*
* @param row1 0-based row of the first cell.
*/
public void setRow1(int row1);
/**
* Returns the row (0 based) of the second cell.
*
* @return 0-based row of the second cell.
*/
public int getRow2();
/**
* Returns the row (0 based) of the first cell.
*
* @param row2 0-based row of the first cell.
*/
public void setRow2(int row2);
/**
* Returns the x coordinate within the first cell
*
* @return the x coordinate within the first cell
*/
public int getDx1();
/**
* Sets the x coordinate within the first cell
*
* @param dx1 the x coordinate within the first cell
*/
public void setDx1(int dx1);
/**
* Returns the y coordinate within the first cell
*
* @return the y coordinate within the first cell
*/
public int getDy1();
/**
* Sets the y coordinate within the first cell
*
* @param dy1 the y coordinate within the first cell
*/
public void setDy1(int dy1);
/**
* Sets the y coordinate within the second cell
*
* @return the y coordinate within the second cell
*/
public int getDy2();
/**
* Sets the y coordinate within the second cell
*
* @param dy2 the y coordinate within the second cell
*/
public void setDy2(int dy2);
/**
* Returns the x coordinate within the second cell
*
* @return the x coordinate within the second cell
*/
public int getDx2();
/**
* Sets the x coordinate within the second cell
*
* @param dx2 the x coordinate within the second cell
*/
public void setDx2(int dx2);
}

View File

@ -51,4 +51,6 @@ public interface CreationHelper {
* @return a FormulaEvaluator instance
*/
FormulaEvaluator createFormulaEvaluator();
ClientAnchor createClientAnchor();
}

View File

@ -1,23 +1,24 @@
/* ====================================================================
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;
public interface Color {
}
/* ====================================================================
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;
/**
* @author Yegor Kozlov
*/
public interface Drawing {
Picture createPicture(ClientAnchor anchor, int pictureIndex);
}

View File

@ -0,0 +1,30 @@
/* ====================================================================
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;
/**
* Repersents a picture in a SpreadsheetML document
*
* @author Yegor Kozlov
*/
public interface Picture {
/**
* Reset the image to the original size.
*/
void resize();
}

View File

@ -599,4 +599,6 @@ public interface Sheet extends Iterable<Row> {
*/
Comment getCellComment(int row, int column);
Drawing createDrawingPatriarch();
}

View File

@ -17,6 +17,7 @@
package org.apache.poi.xssf.usermodel;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import org.apache.poi.ss.usermodel.ClientAnchor;
/**
* A client anchor is attached to an excel worksheet. It anchors against
@ -24,7 +25,7 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
*
* @author Yegor Kozlov
*/
public class XSSFClientAnchor extends XSSFAnchor {
public class XSSFClientAnchor extends XSSFAnchor implements ClientAnchor {
/**
* Starting anchor point
@ -88,16 +89,16 @@ public class XSSFClientAnchor extends XSSFAnchor {
this.cell2 = cell2;
}
public int getCol1() {
return cell1.getCol();
public short getCol1() {
return (short)cell1.getCol();
}
public void setCol1(int col1) {
cell1.setCol(col1);
}
public int getCol2() {
return cell2.getCol();
public short getCol2() {
return (short)cell2.getCol();
}
public void setCol2(int col2) {

View File

@ -53,4 +53,13 @@ public class XSSFCreationHelper implements CreationHelper {
return new XSSFFormulaEvaluator(workbook);
}
/**
* Creates a XSSFClientAnchor. Use this object to position drawing object in a sheet
*
* @return a XSSFClientAnchor instance
* @see org.apache.poi.ss.usermodel.Drawing
*/
public XSSFClientAnchor createClientAnchor(){
return new XSSFClientAnchor();
}
}

View File

@ -17,6 +17,8 @@
package org.apache.poi.xssf.usermodel;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.openxml4j.opc.*;
@ -34,7 +36,7 @@ import java.util.HashMap;
*
* @author Yegor Kozlov
*/
public class XSSFDrawing extends POIXMLDocumentPart {
public class XSSFDrawing extends POIXMLDocumentPart implements Drawing {
/**
* Root element of the SpreadsheetML Drawing part
*/
@ -146,6 +148,10 @@ public class XSSFDrawing extends POIXMLDocumentPart {
return shape;
}
public XSSFPicture createPicture(ClientAnchor anchor, int pictureIndex){
return createPicture((XSSFClientAnchor)anchor, pictureIndex);
}
/**
* Add the indexed picture to this drawing relations
*

View File

@ -19,6 +19,7 @@ package org.apache.poi.xssf.usermodel;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.POIXMLDocumentPart;
@ -39,7 +40,7 @@ import java.util.Iterator;
*
* @author Yegor Kozlov
*/
public class XSSFPicture extends XSSFShape {
public class XSSFPicture extends XSSFShape implements Picture {
private static final POILogger logger = POILogFactory.getLogger(XSSFPicture.class);
/**
@ -132,7 +133,7 @@ public class XSSFPicture extends XSSFShape {
int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1());
int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1());
anchor.setCol2((short)col2);
anchor.setCol2(col2);
anchor.setDx1(0);
anchor.setDx2(pref.getDx2());