From fadd255a55a4613466b21e97c06bb85947a4b7f1 Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Wed, 12 Nov 2008 07:15:37 +0000 Subject: [PATCH] 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 --- .../content/xdocs/spreadsheet/quick-guide.xml | 64 +- .../poi/hssf/usermodel/HSSFClientAnchor.java | 11 +- .../hssf/usermodel/HSSFCreationHelper.java | 10 + .../poi/hssf/usermodel/HSSFDataFormatter.java | 609 +----------------- .../poi/hssf/usermodel/HSSFPatriarch.java | 15 +- .../poi/hssf/usermodel/HSSFPicture.java | 3 +- .../org/apache/poi/hssf/util/HSSFColor.java | 3 +- .../poi/ss/usermodel/DataFormatter.java | 2 +- .../apache/poi/ss/usermodel/ClientAnchor.java | 138 ++++ .../poi/ss/usermodel/CreationHelper.java | 2 + .../ss/usermodel/{Color.java => Drawing.java} | 47 +- .../org/apache/poi/ss/usermodel/Picture.java | 30 + .../org/apache/poi/ss/usermodel/Sheet.java | 2 + .../poi/xssf/usermodel/XSSFClientAnchor.java | 11 +- .../xssf/usermodel/XSSFCreationHelper.java | 9 + .../poi/xssf/usermodel/XSSFDrawing.java | 8 +- .../poi/xssf/usermodel/XSSFPicture.java | 5 +- 17 files changed, 280 insertions(+), 689 deletions(-) create mode 100755 src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/ClientAnchor.java rename src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/{Color.java => Drawing.java} (86%) mode change 100644 => 100755 create mode 100755 src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Picture.java diff --git a/src/documentation/content/xdocs/spreadsheet/quick-guide.xml b/src/documentation/content/xdocs/spreadsheet/quick-guide.xml index 461a5f207f..9b347c7592 100644 --- a/src/documentation/content/xdocs/spreadsheet/quick-guide.xml +++ b/src/documentation/content/xdocs/spreadsheet/quick-guide.xml @@ -1163,63 +1163,45 @@ Examples: It should be noted that any existing drawings may be erased once you add a image to a sheet.

-

HSSF:

- // 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 )); - -

Creating an image and setting its anchor to the actual width and height:

- - HSSFPatriarch patriarch = sheet5.createDrawingPatriarch(); - - HSSFPicture picture = patriarch.createPicture(new HSSFClientAnchor(), loadPicture( "src/resources/logos/logoKarmokar4.png", wb )); - picture.resize(); - -

or

- - HSSFPatriarch patriarch = sheet5.createDrawingPatriarch(); - - HSSFPicture picture = patriarch.createPicture(new HSSFClientAnchor(), loadPicture( "src/resources/logos/logoKarmokar4.png", wb )); - HSSFClientAnchor preferredSize = picture.getPreferredSize(); - picture.setAnchor(preferredSize); - -

XSSF:

- //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(); - + - 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. -

Reading images from a workbook:

diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java b/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java index 4d9098d75a..605b5ac3d0 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFClientAnchor.java @@ -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; diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFCreationHelper.java b/src/java/org/apache/poi/hssf/usermodel/HSSFCreationHelper.java index 0eabcfa706..569ad6ff0e 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFCreationHelper.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFCreationHelper.java @@ -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(); + } + } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormatter.java b/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormatter.java index 67291a22f1..4eead2a5b6 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormatter.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFDataFormatter.java @@ -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 [$�-452]. */ - private static final Pattern specialPatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+\\])"); - - /** General format for whole numbers. */ - private static final Format generalWholeNumFormat = new DecimalFormat("#"); - - /** General 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 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 null if the any of the - * following is true: - * - * - * @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 -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 true 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 String based - * on the cell's DataFormat. 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 String - * based on the cell's DataFormat. 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)); - } - - /** - *

- * Returns the formatted value of a cell as a String regardless - * of the cell type. If the Excel format pattern cannot be parsed then the - * cell value will be formatted using a default format. - *

- *

When passed a null or blank cell, this method will return an empty - * String (""). Formulas in formula type cells will not be evaluated. - *

- * - * @param cell The cell - * @return the formatted cell value as a String - */ - public String formatCellValue(HSSFCell cell) { - return formatCellValue(cell, null); - } - - /** - *

- * Returns the formatted value of a cell as a String regardless - * of the cell type. If the Excel format pattern cannot be parsed then the - * cell value will be formatted using a default format. - *

- *

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 - *

- * - * @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 + ")"); - } - - - /** - *

- * Sets a default number format to be used when the Excel format cannot be - * parsed successfully. Note: This is a fall back for when an error - * occurs while parsing an Excel number format pattern. This will not - * affect cells with the General format. - *

- *

- * The value that will be passed to the Format's format method (specified - * by java.text.Format#format) will be a double value from a - * numeric cell. Therefore the code in the format method should expect a - * Number value. - *

- * - * @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. - *

- * The value that will be passed to the Format's format method (specified - * by java.text.Format#format) will be a double value from a - * numeric cell. Therefore the code in the format method should expect a - * Number value. - *

- * @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 DecimalFormat with parseIntegerOnly set true - */ - /* 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); - } - } } diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java index 98af6e07da..8b9a2d1766 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPatriarch.java @@ -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()) { diff --git a/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java index 8d2dd79641..4b7ac45f14 100644 --- a/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java +++ b/src/java/org/apache/poi/hssf/usermodel/HSSFPicture.java @@ -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 diff --git a/src/java/org/apache/poi/hssf/util/HSSFColor.java b/src/java/org/apache/poi/hssf/util/HSSFColor.java index d13baecf80..d19cc95147 100644 --- a/src/java/org/apache/poi/hssf/util/HSSFColor.java +++ b/src/java/org/apache/poi/hssf/util/HSSFColor.java @@ -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 */ diff --git a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java index 2d621eea1b..378f3303ca 100755 --- a/src/java/org/apache/poi/ss/usermodel/DataFormatter.java +++ b/src/java/org/apache/poi/ss/usermodel/DataFormatter.java @@ -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#]+"); diff --git a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/ClientAnchor.java b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/ClientAnchor.java new file mode 100755 index 0000000000..736f5e6ff5 --- /dev/null +++ b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/ClientAnchor.java @@ -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); +} diff --git a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/CreationHelper.java b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/CreationHelper.java index 89dc88e4af..758990daf1 100644 --- a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/CreationHelper.java +++ b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/CreationHelper.java @@ -51,4 +51,6 @@ public interface CreationHelper { * @return a FormulaEvaluator instance */ FormulaEvaluator createFormulaEvaluator(); + + ClientAnchor createClientAnchor(); } \ No newline at end of file diff --git a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Color.java b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Drawing.java old mode 100644 new mode 100755 similarity index 86% rename from src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Color.java rename to src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Drawing.java index 2bbcaf16e3..c7b8dc0e84 --- a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Color.java +++ b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Drawing.java @@ -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 { - - -} \ No newline at end of file +/* ==================================================================== + 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); +} diff --git a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Picture.java b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Picture.java new file mode 100755 index 0000000000..3e2fab6ac4 --- /dev/null +++ b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Picture.java @@ -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(); +} diff --git a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Sheet.java b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Sheet.java index 911f232111..12c6a6a0c1 100644 --- a/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Sheet.java +++ b/src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Sheet.java @@ -599,4 +599,6 @@ public interface Sheet extends Iterable { */ Comment getCellComment(int row, int column); + Drawing createDrawingPatriarch(); + } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java index 9e6bd26277..468ff8f6c3 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java @@ -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) { diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java index fa39817bd4..88b9d9a87a 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCreationHelper.java @@ -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(); + } } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java index b444eb5ff0..f6e0a6c325 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java @@ -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 * diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java index f776aafe37..f786ca3ef4 100755 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java @@ -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());