poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From m..@apache.org
Subject svn commit: r921819 [2/2] - /poi/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java
Date Thu, 11 Mar 2010 12:12:54 GMT

Modified: poi/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java?rev=921819&r1=921818&r2=921819&view=diff
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java (original)
+++ poi/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java Thu Mar 11 12:12:54 2010
@@ -1,922 +1,943 @@
-/* ====================================================================
-   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.hssf.usermodel.examples;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-import org.apache.poi.hssf.usermodel.HSSFSheet;
-import org.apache.poi.hssf.usermodel.HSSFRow;
-import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
-import org.apache.poi.hssf.usermodel.HSSFPatriarch;
-import org.apache.poi.hssf.util.CellReference;
-
-
-/**
- * Demonstrates how to add an image to a worksheet and set that image's size
- * to a specific number of milimetres irrespective of the width of the columns
- * or height of the rows. Overridden methods are provided so that the location
- * of the image - the cells row and column co-ordinates that define the top
- * left hand corners of the image - can be identified either in the familiar
- * Excel manner - A1 for instance - or using POI's methodolody of a column and
- * row index where 0, 0 would indicate cell A1.
- *
- * The best way to make use of these techniques is to delay adding the image to
- * the sheet until all other work has been completed. That way, the sizes of
- * all rows and columns will have been adjusted - assuming that step was
- * necessary. Even though the anchors type is set to prevent the image moving
- * or re-sizing, this setting does not have any effect until the sheet is being
- * viewed using the Excel application.
- *
- * The key to the process is the HSSFClientAnchor class. It accepts eight
- * parameters that define, in order;
- *
- *      * How far - in terms of co-ordinate position - the image should be inset
- *      from the left hand border of a cell.
- *      * How far - in terms of co-ordinate positions - the image should be inset
- *      from the from the top of the cell.
- *      * How far - in terms of co-ordinate positions - the right hand edge of
- *      the image should protrude into a cell (measured from the cell's left hand
- *      edge to the image's right hand edge).
- *      * How far - in terms of co-ordinate positions - the bottm edge of the
- *      image should protrude into a row (measured from the cell's top edge to
- *      the image's bottom edge).
- *      * The index of the column that contains the cell whose top left hand
- *      corner should be aligned with the top left hand corner of the image.
- *      * The index of the row that contains the cell whose top left hand corner
- *      should be aligned with the image's top left hand corner.
- *      * The index of the column that contains the cell whose top left hand
- *      corner should be aligned with the image's bottom right hand corner
- *      * The index number of the row that contains the cell whose top left
- *      hand corner should be aligned with the images bottom right hand corner.
- *
- * It can be used to add an image into cell A1, for example, in the following
- * manner;
- *
- *      HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0,
- *          (short)0, 0, (short)1, 1);
- *
- * The final four parameters determine that the top left hand corner should be
- * aligned with the top left hand corner of cell A1 and it's bottom right
- * hand corner with the top left hand corner of cell B2. Think of the image as
- * being stretched so that it's top left hand corner is aligned with the top
- * left hand corner of cell A1 and it's bottom right hand corner is aligned with
- * the top left hand corner of cell B1. Interestingly, this would also produce
- * the same results;
- *
- *       anchor = new HSSFClientAnchor(0, 0, 1023, 255,
- *          (short)0, 0, (short)0, 0);
- *
- * Note that the final four parameters all contain the same value and seem to
- * indicate that the images top left hand corner is aligned with the top left
- * hand corner of cell A1 and that it's bottom right hand corner is also
- * aligned with the top left hand corner of cell A1. Yet, running this code
- * would see the image fully occupying cell A1. That is the result of the
- * values passed to parameters three and four; these I have referred to as
- * determing the images co-ordinates within the cell. They indicate that the
- * image should occupy - in order - the full width of the column and the full
- * height of the row.
- *
- * The co-ordinate values shown are the maxima; and they are independent of
- * row height/column width and of the font used. Passing 255 will always result
- * in the image occupying the full height of the row and passing 1023 will
- * always result in the image occupying the full width of the column. They help
- * in situations where an image is larger than a column/row and must overlap
- * into the next column/row. Using them does mean, however, that it is often
- * necessary to perform conversions between Excel's characters units, points,
- * pixels and millimetres in order to establish how many rows/columns an image
- * should occupy and just what the varous insets ought to be.
- *
- * Note that the first two parameters of the HSSFClientAchor classes constructor
- * are not made use of in the code that follows. It would be fairly trivial
- * however to extend these example further and provide methods that would centre
- * an image within a cell or allow the user to specify that a plain border a
- * fixed number of millimetres wide should wrap around the image. Those first
- * two parameters would make this sort of functionality perfectly possible.
- *
- * Owing to the various conversions used, the actual size of the image may vary
- * from that required; testing has so far found this to be in the region of
- * plus or minus two millimetres. Most likely by modifying the way the
- * calculations are performed - possibly using double(s) throughout and
- * rounding the values at the correct point - it is likely that these errors
- * could be reduced or removed.
- *
- * @author Mark Beardsley [msb at apache.org]
- * @version 1.00 5th August 2009.
- */
-public class AddDimensionedImage {
-
-    // Four constants that determine how - and indeed whether - the rows
-    // and columns an image may overlie should be expanded to accomodate that
-    // image.
-    // Passing EXPAND_ROW will result in the height of a row being increased
-    // to accomodate the image if it is not already larger. The image will
-    // be layed across one or more columns.
-    // Passing EXPAND_COLUMN will result in the width of the column being
-    // increased to accomodate the image if it is not already larger. The image
-    // will be layed across one or many rows.
-    // Passing EXPAND_ROW_AND_COLUMN will result in the height of the row
-    // bing increased along with the width of the column to accomdate the
-    // image if either is not already larger.
-    // Passing OVERLAY_ROW_AND_COLUMN will result in the image being layed
-    // over one or more rows and columns. No row or column will be resized,
-    // instead, code will determine how many rows and columns the image should
-    // overlie.
-    public static final int EXPAND_ROW = 1;
-    public static final int EXPAND_COLUMN = 2;
-    public static final int EXPAND_ROW_AND_COLUMN = 3;
-    public static final int OVERLAY_ROW_AND_COLUMN = 7;
-
-    /**
-     * Add an image to a worksheet.
-     *
-     * @param cellNumber A String that contains the location of the cell whose
-     *                   top left hand corner should be aligned with the top
-     *                   left hand corner of the image; for example "A1", "A2"
-     *                   etc. This is to support the familiar Excel syntax.
-     *                   Whilst images are are not actually inserted into cells
-     *                   this provides a convenient method of indicating where
-     *                   the image should be positioned on the sheet.
-     * @param sheet A reference to the sheet that contains the cell referenced
-     *              above.
-     * @param imageFile A String that encapsulates the name of and path to
-     *                  the image that is to be 'inserted into' the sheet.
-     * @param reqImageWidthMM A primitive double that contains the required
-     *                        width of the image in millimetres.
-     * @param reqImageHeightMM A primitive double that contains the required
-     *                         height of the image in millimetres.
-     * @param resizeBehaviour A primitive int whose value will determine how
-     *                        the code should react if the image is larger than
-     *                        the cell referenced by the cellNumber parameter.
-     *                        Four constants are provided to determine what
-     *                        should happen;
-     *                          AddDimensionedImage.EXPAND_ROW
-     *                          AddDimensionedImage.EXPAND_COLUMN
-     *                          AddDimensionedImage.EXPAND_ROW_AND_COLUMN
-     *                          AddDimensionedImage.OVERLAY_ROW_AND_COLUMN
-     * @throws java.io.FileNotFoundException If the file containing the image
-     *                                       cannot be located.
-     * @throws java.io.IOException If a problem occurs whilst reading the file
-     *                             of image data.
-     * @throws java.lang.IllegalArgumentException If an invalid value is passed
-     *                                            to the resizeBehaviour
-     *                                            parameter.
-     */
-    public void addImageToSheet(String cellNumber, HSSFSheet sheet,
-            String imageFile, double reqImageWidthMM, double reqImageHeightMM,
-            int resizeBehaviour) throws FileNotFoundException, IOException,
-                                                      IllegalArgumentException {
-        // Convert the String into column and row indices then chain the
-        // call to the overridden addImageToSheet() method.
-        CellReference cellRef = new CellReference(cellNumber);
-        this.addImageToSheet(cellRef.getCol(), cellRef.getRow(), sheet,
-                imageFile, reqImageWidthMM, reqImageHeightMM,resizeBehaviour);
-    }
-
-    /**
-     * Add an image to a worksheet.
-     *
-     * @param colNumber A primitive int that contains the index number of a
-     *                  column on the worksheet; POI column indices are zero
-     *                  based. Together with the rowNumber parameter's value,
-     *                  this parameter identifies a cell on the worksheet. The
-     *                  image's top left hand corner will be aligned with the
-     *                  top left hand corner of this cell.
-     * @param rowNumber A primtive int that contains the index number of a row
-     *                  on the worksheet; POI row indices are zero based.
-     *                  Together with the rowNumber parameter's value, this
-     *                  parameter identifies a cell on the worksheet. The
-     *                  image's top left hand corner will be aligned with the
-     *                  top left hand corner of this cell.
-     * @param sheet A reference to the sheet that contains the cell identified
-     *              by the two parameters above.
-     * @param imageFile A String that encapsulates the name of and path to
-     *                  the image that is to be 'inserted into' the sheet.
-     * @param reqImageWidthMM A primitive double that contains the required
-     *                        width of the image in millimetres.
-     * @param reqImageHeightMM A primitive double that contains the required
-     *                         height of the image in millimetres.
-     * @param resizeBehaviour A primitive int whose value will determine how
-     *                        the code should react if the image is larger than
-     *                        the cell referenced by the colNumber and
-     *                        rowNumber parameters. Four constants are provided
-     *                        to determine what should happen;
-     *                          AddDimensionedImage.EXPAND_ROW
-     *                          AddDimensionedImage.EXPAND_COLUMN
-     *                          AddDimensionedImage.EXPAND_ROW_AND_COLUMN
-     *                          AddDimensionedImage.OVERLAY_ROW_AND_COLUMN
-     * @throws java.io.FileNotFoundException If the file containing the image
-     *                                       cannot be located.
-     * @throws java.io.IOException If a problem occurs whilst reading the file
-     *                             of image data.
-     * @throws java.lang.IllegalArgumentException If an invalid value is passed
-     *                                            to the resizeBehaviour
-     *                                            parameter.
-     */
-    private void addImageToSheet(int colNumber, int rowNumber, HSSFSheet sheet,
-            String imageFile, double reqImageWidthMM, double reqImageHeightMM,
-            int resizeBehaviour) throws FileNotFoundException, IOException,
-                                                     IllegalArgumentException  {
-        HSSFClientAnchor anchor = null;
-        HSSFPatriarch patriarch = null;
-        ClientAnchorDetail rowClientAnchorDetail = null;
-        ClientAnchorDetail colClientAnchorDetail = null;
-
-        // Validate the resizeBehaviour parameter.
-        if((resizeBehaviour != AddDimensionedImage.EXPAND_COLUMN) &&
-           (resizeBehaviour != AddDimensionedImage.EXPAND_ROW) &&
-           (resizeBehaviour != AddDimensionedImage.EXPAND_ROW_AND_COLUMN) &&
-           (resizeBehaviour != AddDimensionedImage.OVERLAY_ROW_AND_COLUMN)) {
-            throw new IllegalArgumentException("Invalid value passed to the " +
-                    "resizeBehaviour parameter of AddDimensionedImage.addImageToSheet()");
-        }
-
-        // Call methods to calculate how the image and sheet should be
-        // manipulated to accomodate the image; columns and then rows.
-        colClientAnchorDetail = this.fitImageToColumns(sheet, colNumber,
-                reqImageWidthMM, resizeBehaviour);
-        rowClientAnchorDetail = this.fitImageToRows(sheet, rowNumber,
-                reqImageHeightMM, resizeBehaviour);
-
-        // Having determined if and how to resize the rows, columns and/or the
-        // image, create the HSSFClientAnchor object to position the image on
-        // the worksheet. Note how the two ClientAnchorDetail records are
-        // interrogated to recover the row/column co-ordinates and any insets.
-        // The first two parameters are not used currently but could be if the
-        // need arose to extend the functionality of this code by adding the
-        // ability to specify that a clear 'border' be placed around the image.
-        anchor = new HSSFClientAnchor(0,
-                                      0,
-                                      colClientAnchorDetail.getInset(),
-                                      rowClientAnchorDetail.getInset(),
-                                      (short)colClientAnchorDetail.getFromIndex(),
-                                      rowClientAnchorDetail.getFromIndex(),
-                                      (short)colClientAnchorDetail.getToIndex(),
-                                      rowClientAnchorDetail.getToIndex());
-
-        // For now, set the anchor type to do not move or resize the
-        // image as the size of the row/column is adjusted. This could easilly
-        // become another parameter passed to the method.
-        anchor.setAnchorType(HSSFClientAnchor.DONT_MOVE_AND_RESIZE);
-
-        // Now, add the picture to the workbook. Note that the type is assumed
-        // to be a JPEG/JPG, this could easily (and should) be parameterised
-        // however.
-        int index = sheet.getWorkbook().addPicture(this.imageToBytes(imageFile),
-                    HSSFWorkbook.PICTURE_TYPE_JPEG);
-
-        // Get the drawing patriarch and create the picture.
-        patriarch = sheet.createDrawingPatriarch();
-        patriarch.createPicture(anchor, index);
-    }
-
-    /**
-     * Determines whether the sheets columns should be re-sized to accomodate
-     * the image, adjusts the columns width if necessary and creates then
-     * returns a ClientAnchorDetail object that facilitates construction of
-     * an HSSFClientAnchor that will fix the image on the sheet and establish
-     * it's size.
-     *
-     * @param sheet A reference to the sheet that will 'contain' the image.
-     * @param colNumber A primtive int that contains the index number of a
-     *                  column on the sheet.
-     * @param reqImageWidthMM A primtive double that contains the required
-     *                        width of the image in millimetres
-     * @param resizeBehaviour A primitve int whose value will indicate how the
-     *                        width of the column should be adjusted if the
-     *                        required width of the image is greater than the
-     *                        width of the column.
-     * @return An instance of the ClientAnchorDetail class that will contain
-     *         the index number of the column containing the cell whose top
-     *         left hand corner also defines the top left hand corner of the
-     *         image, the index number column containing the cell whose top
-     *         left hand corner also defines the bottom right hand corner of
-     *         the image and an inset that determines how far the right hand
-     *         edge of the image can protrude into the next column - expressed
-     *         as a specific number of co-ordinate positions.
-     */
-    private ClientAnchorDetail fitImageToColumns(HSSFSheet sheet, int colNumber,
-            double reqImageWidthMM, int resizeBehaviour) {
-
-        double colWidthMM = 0.0D;
-        double colCoordinatesPerMM = 0.0D;
-        int pictureWidthCoordinates = 0;
-        ClientAnchorDetail colClientAnchorDetail = null;
-
-        // Get the colum's width in millimetres
-        colWidthMM = ConvertImageUnits.widthUnits2Millimetres(
-                (short)sheet.getColumnWidth(colNumber));
-
-        // Check that the column's width will accomodate the image at the
-        // required dimension. If the width of the column is LESS than the
-        // required width of the image, decide how the application should
-        // respond - resize the column or overlay the image across one or more
-        // columns.
-        if(colWidthMM < reqImageWidthMM) {
-
-            // Should the column's width simply be expanded?
-            if((resizeBehaviour == AddDimensionedImage.EXPAND_COLUMN) ||
-               (resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) {
-                // Set the width of the column by converting the required image
-                // width from millimetres into Excel's column width units.
-                sheet.setColumnWidth(colNumber,
-                        ConvertImageUnits.millimetres2WidthUnits(reqImageWidthMM));
-                // To make the image occupy the full width of the column, convert
-                // the required width of the image into co-ordinates. This value
-                // will become the inset for the ClientAnchorDetail class that
-                // is then instantiated.
-                colWidthMM = reqImageWidthMM;
-                colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS /
-                    colWidthMM;
-                pictureWidthCoordinates = (int)(reqImageWidthMM * colCoordinatesPerMM);
-                colClientAnchorDetail = new ClientAnchorDetail(colNumber,
-                        colNumber, pictureWidthCoordinates);
-            }
-            // If the user has chosen to overlay both rows and columns or just
-            // to expand ONLY the size of the rows, then calculate how to lay
-            // the image out across one or more columns.
-            else if ((resizeBehaviour == AddDimensionedImage.OVERLAY_ROW_AND_COLUMN) ||
-                     (resizeBehaviour == AddDimensionedImage.EXPAND_ROW)) {
-                colClientAnchorDetail = this.calculateColumnLocation(sheet,
-                        colNumber, reqImageWidthMM);
-            }
-        }
-        // If the column is wider than the image.
-        else {
-            // Mow many co-ordinate positions are there per millimetre?
-            colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS /
-                    colWidthMM;
-            // Given the width of the image, what should be it's co-ordinate?
-            pictureWidthCoordinates = (int)(reqImageWidthMM * colCoordinatesPerMM);
-            colClientAnchorDetail = new ClientAnchorDetail(colNumber,
-                    colNumber, pictureWidthCoordinates);
-        }
-        return(colClientAnchorDetail);
-    }
-
-    /**
-     * Determines whether the sheet's row should be re-sized to accomodate
-     * the image, adjusts the rows height if necessary and creates then
-     * returns a ClientAnchorDetail object that facilitates construction of
-     * an HSSFClientAnchor that will fix the image on the sheet and establish
-     * it's size.
-     *
-     * @param sheet A reference to the sheet that will 'contain' the image.
-     * @param rowNumber A primtive int that contains the index number of a
-     *                  row on the sheet.
-     * @param reqImageHeightMM A primtive double that contains the required
-     *                         height of the image in millimetres
-     * @param resizeBehaviour A primitve int whose value will indicate how the
-     *                        height of the row should be adjusted if the
-     *                        required height of the image is greater than the
-     *                        height of the row.
-     * @return An instance of the ClientAnchorDetail class that will contain
-     *         the index number of the row containing the cell whose top
-     *         left hand corner also defines the top left hand corner of the
-     *         image, the index number of the row containing the cell whose
-     *         top left hand corner also defines the bottom right hand
-     *         corner of the image and an inset that determines how far the
-     *         bottom edge of the image can protrude into the next (lower)
-     *         row - expressed as a specific number of co-ordinate positions.
-     */
-    private ClientAnchorDetail fitImageToRows(HSSFSheet sheet, int rowNumber,
-            double reqImageHeightMM, int resizeBehaviour) {
-        HSSFRow row = null;
-        double rowHeightMM = 0.0D;
-        double rowCoordinatesPerMM = 0.0D;
-        int pictureHeightCoordinates = 0;
-        ClientAnchorDetail rowClientAnchorDetail = null;
-
-        // Get the row and it's height
-        row = sheet.getRow(rowNumber);
-        if(row == null) {
-            // Create row if it does not exist.
-            row = sheet.createRow(rowNumber);
-        }
-
-        // Get the row's height in millimetres
-        rowHeightMM = row.getHeightInPoints() / ConvertImageUnits.POINTS_PER_MILLIMETRE;
-
-        // Check that the row's height will accomodate the image at the required
-        // dimensions. If the height of the row is LESS than the required height
-        // of the image, decide how the application should respond - resize the
-        // row or overlay the image across a series of rows.
-        if(rowHeightMM < reqImageHeightMM) {
-            if((resizeBehaviour == AddDimensionedImage.EXPAND_ROW) ||
-               (resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) {
-                row.setHeightInPoints((float)(reqImageHeightMM *
-                        ConvertImageUnits.POINTS_PER_MILLIMETRE));
-                rowHeightMM = reqImageHeightMM;
-                rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS /
-                    rowHeightMM;
-                pictureHeightCoordinates = (int)(reqImageHeightMM * rowCoordinatesPerMM);
-                rowClientAnchorDetail = new ClientAnchorDetail(rowNumber,
-                        rowNumber, pictureHeightCoordinates);
-            }
-            // If the user has chosen to overlay both rows and columns or just
-            // to expand ONLY the size of the columns, then calculate how to lay
-            // the image out ver one or more rows.
-            else if((resizeBehaviour == AddDimensionedImage.OVERLAY_ROW_AND_COLUMN) ||
-                    (resizeBehaviour == AddDimensionedImage.EXPAND_COLUMN)) {
-                rowClientAnchorDetail = this.calculateRowLocation(sheet,
-                        rowNumber, reqImageHeightMM);
-            }
-        }
-        // Else, if the image is smaller than the space available
-        else {
-            rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS /
-                    rowHeightMM;
-            pictureHeightCoordinates = (int)(reqImageHeightMM * rowCoordinatesPerMM);
-            rowClientAnchorDetail = new ClientAnchorDetail(rowNumber,
-                        rowNumber, pictureHeightCoordinates);
-        }
-        return(rowClientAnchorDetail);
-    }
-
-    /**
-     * If the image is to overlie more than one column, calculations need to be
-     * performed to determine how many columns and whether the image will
-     * overlie just a part of one column in order to be presented at the
-     * required size.
-     *
-     * @param sheet The sheet that will 'contain' the image.
-     * @param startingColumn A primitive int whose value is the index of the
-     *                       column that contains the cell whose top left hand
-     *                       corner should be aligned with the top left hand
-     *                       corner of the image.
-     * @param reqImageWidthMM A primitive double whose value will indicate the
-     *                        required width of the image in millimetres.
-     * @return An instance of the ClientAnchorDetail class that will contain
-     *         the index number of the column containing the cell whose top
-     *         left hand corner also defines the top left hand corner of the
-     *         image, the index number column containing the cell whose top
-     *         left hand corner also defines the bottom right hand corner of
-     *         the image and an inset that determines how far the right hand
-     *         edge of the image can protrude into the next column - expressed
-     *         as a specific number of co-ordinate positions.
-     */
-    private ClientAnchorDetail calculateColumnLocation(HSSFSheet sheet,
-                                                       int startingColumn,
-                                                       double reqImageWidthMM) {
-        ClientAnchorDetail anchorDetail = null;
-        double totalWidthMM = 0.0D;
-        double colWidthMM = 0.0D;
-        double overlapMM = 0.0D;
-        double coordinatePositionsPerMM = 0.0D;
-        int toColumn = startingColumn;
-        int inset = 0;
-
-        // Calculate how many columns the image will have to
-        // span in order to be presented at the required size.
-        while(totalWidthMM < reqImageWidthMM) {
-            colWidthMM = ConvertImageUnits.widthUnits2Millimetres(
-                    (short)(sheet.getColumnWidth(toColumn)));
-            // Note use of the cell border width constant. Testing with an image
-            // declared to fit exactly into one column demonstrated that it's
-            // width was greater than the width of the column the POI returned.
-            // Further, this difference was a constant value that I am assuming
-            // related to the cell's borders. Either way, that difference needs
-            // to be allowed for in this calculation.
-            totalWidthMM += (colWidthMM + ConvertImageUnits.CELL_BORDER_WIDTH_MILLIMETRES);
-            toColumn++;
-        }
-        // De-crement by one the last column value.
-        toColumn--;
-        // Highly unlikely that this will be true but, if the width of a series
-        // of columns is exactly equal to the required width of the image, then
-        // simply build a ClientAnchorDetail object with an inset equal to the
-        // total number of co-ordinate positions available in a column, a
-        // from column co-ordinate (top left hand corner) equal to the value
-        // of the startingColumn parameter and a to column co-ordinate equal
-        // to the toColumn variable.
-        //
-        // Convert both values to ints to perform the test.
-        if((int)totalWidthMM == (int)reqImageWidthMM) {
-            // A problem could occur if the image is sized to fit into one or
-            // more columns. If that occurs, the value in the toColumn variable
-            // will be in error. To overcome this, there are two options, to
-            // ibcrement the toColumn variable's value by one or to pass the
-            // total number of co-ordinate positions to the third paramater
-            // of the ClientAnchorDetail constructor. For no sepcific reason,
-            // the latter option is used below.
-            anchorDetail = new ClientAnchorDetail(startingColumn,
-                    toColumn, ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS);
-        }
-        // In this case, the image will overlap part of another column and it is
-        // necessary to calculate just how much - this will become the inset
-        // for the ClientAnchorDetail object.
-        else {
-            // Firstly, claculate how much of the image should overlap into
-            // the next column.
-            overlapMM = reqImageWidthMM - (totalWidthMM - colWidthMM);
-
-            // When the required size is very close indded to the column size,
-            // the calcaulation above can produce a negative value. To prevent
-            // problems occuring in later caculations, this is simply removed
-            // be setting the overlapMM value to zero.
-            if(overlapMM < 0) {
-                overlapMM = 0.0D;
-            }
-
-            // Next, from the columns width, calculate how many co-ordinate
-            // positons there are per millimetre
-            coordinatePositionsPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS /
-                    colWidthMM;
-            // From this figure, determine how many co-ordinat positions to
-            // inset the left hand or bottom edge of the image.
-            inset = (int)(coordinatePositionsPerMM * overlapMM);
-
-            // Now create the ClientAnchorDetail object, setting the from and to
-            // columns and the inset.
-            anchorDetail = new ClientAnchorDetail(startingColumn, toColumn, inset);
-        }
-        return(anchorDetail);
-    }
-
-    /**
-     * If the image is to overlie more than one rows, calculations need to be
-     * performed to determine how many rows and whether the image will
-     * overlie just a part of one row in order to be presented at the
-     * required size.
-     *
-     * @param sheet The sheet that will 'contain' the image.
-     * @param startingRow A primitive int whose value is the index of the row
-     *                    that contains the cell whose top left hand corner
-     *                    should be aligned with the top left hand corner of
-     *                    the image.
-     * @param reqImageHeightMM A primitive double whose value will indicate the
-     *                         required height of the image in millimetres.
-     * @return An instance of the ClientAnchorDetail class that will contain
-     *         the index number of the row containing the cell whose top
-     *         left hand corner also defines the top left hand corner of the
-     *         image, the index number of the row containing the cell whose top
-     *         left hand corner also defines the bottom right hand corner of
-     *         the image and an inset that determines how far the bottom edge
-     *         can protrude into the next (lower) row - expressed as a specific
-     *         number of co-ordinate positions.
-     */
-    private ClientAnchorDetail calculateRowLocation(HSSFSheet sheet,
-            int startingRow, double reqImageHeightMM) {
-        ClientAnchorDetail clientAnchorDetail = null;
-        HSSFRow row = null;
-        double rowHeightMM = 0.0D;
-        double totalRowHeightMM = 0.0D;
-        double overlapMM = 0.0D;
-        double rowCoordinatesPerMM = 0.0D;
-        int toRow = startingRow;
-        int inset = 0;
-
-        // Step through the rows in the sheet and accumulate a total of their
-        // heights.
-        while(totalRowHeightMM < reqImageHeightMM) {
-            row = sheet.getRow(toRow);
-            // Note, if the row does not already exist on the sheet then create
-            // it here.
-            if(row == null) {
-                row = sheet.createRow(toRow);
-            }
-            // Get the row's height in millimetres and add to the running total.
-            rowHeightMM = row.getHeightInPoints() /
-                    ConvertImageUnits.POINTS_PER_MILLIMETRE;
-            totalRowHeightMM += rowHeightMM;
-            toRow++;
-        }
-        // Owing to the way the loop above works, the rowNumber will have been
-        // incremented one row too far. Undo that here.
-        toRow--;
-        // Check to see whether the image should occupy an exact number of
-        // rows. If so, build the ClientAnchorDetail record to point
-        // to those rows and with an inset of the total number of co-ordinate
-        // position in the row.
-        //
-        // To overcome problems that can occur with comparing double values for
-        // equality, cast both to int(s) to truncate the value; VERY crude and
-        // I do not really like it!!
-        if((int)totalRowHeightMM == (int)reqImageHeightMM) {
-            clientAnchorDetail = new ClientAnchorDetail(startingRow, toRow,
-                    ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS);
-        }
-        else {
-            // Calculate how far the image will project into the next row. Note
-            // that the height of the last row assessed is subtracted from the
-            // total height of all rows assessed so far.
-            overlapMM = reqImageHeightMM - (totalRowHeightMM - rowHeightMM);
-
-            // To prevent an exception being thrown when the required width of
-            // the image is very close indeed to the column size.
-            if(overlapMM < 0) {
-                overlapMM = 0.0D;
-            }
-
-            rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS /
-                    rowHeightMM;
-            inset = (int)(overlapMM * rowCoordinatesPerMM);
-            clientAnchorDetail = new ClientAnchorDetail(startingRow,
-                        toRow, inset);
-        }
-        return(clientAnchorDetail);
-    }
-
-    /**
-     * Loads - reads in and converts into an array of byte(s) - an image from
-     * a named file.
-     *
-     * Note: this method should be modified so that the type of the image may
-     * also be passed to it. Currently, it assumes that all images are
-     * JPG/JPEG(s).
-     *
-     * @param imageFilename A String that encapsulates the path to and name
-     *                      of the file that contains the image which is to be
-     *                      'loaded'.
-     * @return An array of type byte that contains the raw data of the named
-     *         image.
-     * @throws java.io.FileNotFoundException Thrown if it was not possible to
-     *                                       open the specified file.
-     * @throws java.io.IOException Thrown if reading the file failed or was
-     *                             interrupted.
-     */
-    private byte[] imageToBytes(String imageFilename)
-                                     throws FileNotFoundException, IOException {
-        File imageFile = null;
-        FileInputStream fis = null;
-        ByteArrayOutputStream bos = null;
-        int read = 0;
-        try {
-            imageFile = new File(imageFilename);
-            fis = new FileInputStream(imageFile);
-            bos = new ByteArrayOutputStream();
-            while((read = fis.read()) != -1) {
-                bos.write(read);
-            }
-            return(bos.toByteArray());
-        }
-        finally {
-            if(fis != null) {
-                try {
-                    fis.close();
-                    fis = null;
-                }
-                catch(IOException ioEx) {
-                    // Nothing to do here
-                }
-            }
-        }
-    }
-
-    /**
-     * The main entry point to the program. It contains code that demonstrates
-     * one way to use the program.
-     *
-     * Note, the code is not restricted to use on new workbooks only. If an
-     * image is to be inserted into an existing workbook. just open that
-     * workbook, gat a reference to a sheet and pass that;
-     *
-     *      AddDimensionedImage addImage = new AddDimensionedImage();
-     *
-     *      File file = new File("....... Existing Workbook .......");
-     *      FileInputStream fis = new FileInputStream(file);
-     *      HSSFWorkbook workbook = new HSSFWorkbook(fis);
-     *      HSSFSheet sheet = workbook.getSheetAt(0);
-     *      addImage.addImageToSheet("C3", sheet, "image.jpg", 30, 20,
-     *          AddDimensionedImage.EXPAND.ROW);
-     *
-     * @param args the command line arguments
-     */
-    public static void main(String[] args) {
-        FileOutputStream fos = null;
-        HSSFWorkbook workbook = null;
-        HSSFSheet sheet = null;
-        try {
-            workbook = new HSSFWorkbook();
-            sheet = workbook.createSheet("Picture Test");
-            new AddDimensionedImage().addImageToSheet("B5", sheet,
-                    "image.jpg", 25, 25,
-                    AddDimensionedImage.OVERLAY_ROW_AND_COLUMN);
-            fos = new FileOutputStream("Workbook.xls");
-            workbook.write(fos);
-        }
-        catch(FileNotFoundException fnfEx) {
-            System.out.println("Caught an: " + fnfEx.getClass().getName());
-            System.out.println("Message: " + fnfEx.getMessage());
-            System.out.println("Stacktrace follows...........");
-            fnfEx.printStackTrace(System.out);
-        }
-        catch(IOException ioEx) {
-            System.out.println("Caught an: " + ioEx.getClass().getName());
-            System.out.println("Message: " + ioEx.getMessage());
-            System.out.println("Stacktrace follows...........");
-            ioEx.printStackTrace(System.out);
-        }
-        finally {
-            if(fos != null) {
-                try {
-                    fos.close();
-                    fos = null;
-                }
-                catch(IOException ioEx) {
-                    // I G N O R E
-                }
-            }
-        }
-    }
-
-    /**
-     * The HSSFClientAnchor class accepts eight parameters. In order, these are;
-     *
-     *      * How far the left hand edge of the image is inset from the left hand
-     *      edge of the cell
-     *      * How far the top edge of the image is inset from the top of the cell
-     *      * How far the right hand edge of the image is inset from the left
-     *      hand edge of the cell
-     *      * How far the bottom edge of the image is inset from the top of the
-     *      cell.
-     *      * Together, parameters five and six determine the column and row
-     *      co-ordinates of the cell whose top left hand corner will be aligned
-     *      with the image's top left hand corner.
-     *      * Together, parameter seven and eight determine the column and row
-     *      co-ordinates of the cell whose top left hand corner will be aligned
-     *      with the images bottom right hand corner.
-     *
-     * An instance of the ClientAnchorDetail class provides three of the eight
-     * parameters, one of the co-ordinates for the images top left hand corner,
-     * one of the co-ordinates for the images bottom right hand corner and
-     * either how far the image should be inset from the top or the left hand
-     * edge of the cell.
-     *
-     * @author Mark Beardsley [msb at apache.org]
-     * @version 1.00 5th August 2009.
-     */
-    public class ClientAnchorDetail {
-
-        public int fromIndex = 0;
-        public int toIndex = 0;
-        public int inset = 0;
-
-        /**
-         * Create a new instance of the ClientAnchorDetail class using the
-         * following parameters.
-         *
-         * @param fromIndex A primitive int that contains one of the
-         *                  co-ordinates (row or column index) for the top left
-         *                  hand corner of the image.
-         * @param toIndex A primitive int that contains one of the
-         *                co-ordinates (row or column index) for the bottom
-         *                right hand corner of the image.
-         * @param inset A primitive int that contains a value which indicates
-         *              how far the image should be inset from the top or the
-         *              left hand edge of a cell.
-         */
-        public ClientAnchorDetail(int fromIndex, int toIndex, int inset) {
-            this.fromIndex = fromIndex;
-            this.toIndex = toIndex;
-            this.inset = inset;
-        }
-
-        /**
-         * Get one of the number of the column or row that contains the cell
-         * whose top left hand corner will be aligned with the top left hand
-         * corner of the image.
-         *
-         * @return The value - row or column index - for one of the co-ordinates
-         *         of the top left hand corner of the image.
-         */
-        public int getFromIndex() {
-            return(this.fromIndex);
-        }
-
-        /**
-         * Get one of the number of the column or row that contains the cell
-         * whose top left hand corner will be aligned with the bottom righ hand
-         * corner of the image.
-         *
-         * @return The value - row or column index - for one of the co-ordinates
-         *         of the bottom right hand corner of the image.
-         */
-        public int getToIndex() {
-            return(this.toIndex);
-        }
-
-        /**
-         * Get the image's offset from the edge of a cell.
-         *
-         * @return How far either the right hand or bottom edge of the image is
-         *         inset from the left hand or top edge of a cell.
-         */
-        public int getInset() {
-            return(this.inset);
-        }
-    }
-
-    /**
-     * Utility methods used to convert Excel's character based column and row
-     * size measurements into pixels and/or millimetres. The class also contains
-     * various constants that are required in other calculations.
-     *
-     * @author xio[darjino@hotmail.com]
-     * @version 1.01 30th July 2009.
-     *      Added by Mark Beardsley [msb at apache.org].
-     *          Additional constants.
-     *          widthUnits2Millimetres() and millimetres2Units() methods.
-     */
-    public static class ConvertImageUnits {
-
-        // Each cell conatins a fixed number of co-ordinate points; this number
-        // does not vary with row height or column width or with font. These two
-        // constants are defined below.
-        public static final int TOTAL_COLUMN_COORDINATE_POSITIONS = 1023; // MB
-        public static final int TOTAL_ROW_COORDINATE_POSITIONS = 255;     // MB
-        // The resoultion of an image can be expressed as a specific number
-        // of pixels per inch. Displays and printers differ but 96 pixels per
-        // inch is an acceptable standard to beging with.
-        public static final int PIXELS_PER_INCH = 96;                     // MB
-        // Cnstants that defines how many pixels and points there are in a
-        // millimetre. These values are required for the conversion algorithm.
-        public static final double PIXELS_PER_MILLIMETRES = 3.78;         // MB
-        public static final double POINTS_PER_MILLIMETRE = 2.83;          // MB
-        // The column width returned by HSSF and the width of a picture when
-        // positioned to exactly cover one cell are different by almost exactly
-        // 2mm - give or take rounding errors. This constant allows that
-        // additional amount to be accounted for when calculating how many
-        // celles the image ought to overlie.
-        public static final double CELL_BORDER_WIDTH_MILLIMETRES = 2.0D;  // MB
-        public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;
-        public static final int UNIT_OFFSET_LENGTH = 7;
-        public static final int[] UNIT_OFFSET_MAP = new int[]
-            { 0, 36, 73, 109, 146, 182, 219 };
-
-        /**
-        * pixel units to excel width units(units of 1/256th of a character width)
-        * @param pxs
-        * @return
-        */
-        public static short pixel2WidthUnits(int pxs) {
-            short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR *
-                    (pxs / UNIT_OFFSET_LENGTH));
-            widthUnits += UNIT_OFFSET_MAP[(pxs % UNIT_OFFSET_LENGTH)];
-            return widthUnits;
-        }
-
-        /**
-         * excel width units(units of 1/256th of a character width) to pixel
-         * units.
-         *
-         * @param widthUnits
-         * @return
-         */
-        public static int widthUnits2Pixel(short widthUnits) {
-            int pixels = (widthUnits / EXCEL_COLUMN_WIDTH_FACTOR)
-                    * UNIT_OFFSET_LENGTH;
-            int offsetWidthUnits = widthUnits % EXCEL_COLUMN_WIDTH_FACTOR;
-            pixels += Math.round(offsetWidthUnits /
-                    ((float) EXCEL_COLUMN_WIDTH_FACTOR / UNIT_OFFSET_LENGTH));
-            return pixels;
-        }
-
-        /**
-         * Convert Excel's width units into millimetres.
-         *
-         * @param widthUnits The width of the column or the height of the
-         *                   row in Excel's units.
-         * @return A primitive double that contains the columns width or rows
-         *         height in millimetres.
-         */
-        public static double widthUnits2Millimetres(short widthUnits) {
-            return(ConvertImageUnits.widthUnits2Pixel(widthUnits) /
-                   ConvertImageUnits.PIXELS_PER_MILLIMETRES);
-        }
-
-        /**
-         * Convert into millimetres Excel's width units..
-         *
-         * @param millimetres A primitive double that contains the columns
-         *                    width or rows height in millimetres.
-         * @return A primitive int that contains the columns width or rows
-         *         height in Excel's units.
-         */
-        public static int millimetres2WidthUnits(double millimetres) {
-            return(ConvertImageUnits.pixel2WidthUnits((int)(millimetres *
-                    ConvertImageUnits.PIXELS_PER_MILLIMETRES)));
-        }
-    }
-}
+/* ====================================================================
+   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.hssf.usermodel.examples;
+
+package bookfromtemplate;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
+import org.apache.poi.hssf.usermodel.HSSFPatriarch;
+import org.apache.poi.hssf.util.CellReference;
+
+
+/**
+ * Demonstrates how to add an image to a worksheet and set that image's size
+ * to a specific number of milimetres irrespective of the width of the columns
+ * or height of the rows. Overridden methods are provided so that the location
+ * of the image - the cells row and column co-ordinates that define the top
+ * left hand corners of the image - can be identified either in the familiar
+ * Excel manner - A1 for instance - or using POI's methodolody of a column and
+ * row index where 0, 0 would indicate cell A1.
+ *
+ * The best way to make use of these techniques is to delay adding the image to
+ * the sheet until all other work has been completed. That way, the sizes of
+ * all rows and columns will have been adjusted - assuming that step was
+ * necessary. Even though the anchors type is set to prevent the image moving
+ * or re-sizing, this setting does not have any effect until the sheet is being
+ * viewed using the Excel application.
+ *
+ * The key to the process is the HSSFClientAnchor class. It accepts eight
+ * parameters that define, in order;
+ *
+ *      * How far - in terms of co-ordinate position - the image should be inset
+ *      from the left hand border of a cell.
+ *      * How far - in terms of co-ordinate positions - the image should be inset
+ *      from the from the top of the cell.
+ *      * How far - in terms of co-ordinate positions - the right hand edge of
+ *      the image should protrude into a cell (measured from the cell's left hand
+ *      edge to the image's right hand edge).
+ *      * How far - in terms of co-ordinate positions - the bottm edge of the
+ *      image should protrude into a row (measured from the cell's top edge to
+ *      the image's bottom edge).
+ *      * The index of the column that contains the cell whose top left hand
+ *      corner should be aligned with the top left hand corner of the image.
+ *      * The index of the row that contains the cell whose top left hand corner
+ *      should be aligned with the image's top left hand corner.
+ *      * The index of the column that contains the cell whose top left hand
+ *      corner should be aligned with the image's bottom right hand corner
+ *      * The index number of the row that contains the cell whose top left
+ *      hand corner should be aligned with the images bottom right hand corner.
+ *
+ * It can be used to add an image into cell A1, for example, in the following
+ * manner;
+ *
+ *      HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0,
+ *          (short)0, 0, (short)1, 1);
+ *
+ * The final four parameters determine that the top left hand corner should be
+ * aligned with the top left hand corner of cell A1 and it's bottom right
+ * hand corner with the top left hand corner of cell B2. Think of the image as
+ * being stretched so that it's top left hand corner is aligned with the top
+ * left hand corner of cell A1 and it's bottom right hand corner is aligned with
+ * the top left hand corner of cell B1. Interestingly, this would also produce
+ * the same results;
+ *
+ *       anchor = new HSSFClientAnchor(0, 0, 1023, 255,
+ *          (short)0, 0, (short)0, 0);
+ *
+ * Note that the final four parameters all contain the same value and seem to
+ * indicate that the images top left hand corner is aligned with the top left
+ * hand corner of cell A1 and that it's bottom right hand corner is also
+ * aligned with the top left hand corner of cell A1. Yet, running this code
+ * would see the image fully occupying cell A1. That is the result of the
+ * values passed to parameters three and four; these I have referred to as
+ * determing the images co-ordinates within the cell. They indicate that the
+ * image should occupy - in order - the full width of the column and the full
+ * height of the row.
+ *
+ * The co-ordinate values shown are the maxima; and they are independent of
+ * row height/column width and of the font used. Passing 255 will always result
+ * in the image occupying the full height of the row and passing 1023 will
+ * always result in the image occupying the full width of the column. They help
+ * in situations where an image is larger than a column/row and must overlap
+ * into the next column/row. Using them does mean, however, that it is often
+ * necessary to perform conversions between Excel's characters units, points,
+ * pixels and millimetres in order to establish how many rows/columns an image
+ * should occupy and just what the varous insets ought to be.
+ *
+ * Note that the first two parameters of the HSSFClientAchor classes constructor
+ * are not made use of in the code that follows. It would be fairly trivial
+ * however to extend these example further and provide methods that would centre
+ * an image within a cell or allow the user to specify that a plain border a
+ * fixed number of millimetres wide should wrap around the image. Those first
+ * two parameters would make this sort of functionality perfectly possible.
+ *
+ * Owing to the various conversions used, the actual size of the image may vary
+ * from that required; testing has so far found this to be in the region of
+ * plus or minus two millimetres. Most likely by modifying the way the
+ * calculations are performed - possibly using double(s) throughout and
+ * rounding the values at the correct point - it is likely that these errors
+ * could be reduced or removed.
+ *
+ * A note concerning Excels' image resizing behaviour. The HSSFClientAnchor
+ * class contains a method called setAnchorType(int) which can be used to
+ * determine how Excel will resize an image in reponse to the user increasing
+ * or decreasing the dimensions of the cell containing the image. There are 
+ * three values that can be passed to this method; 0 = To move and size the 
+ * image with the cell, 2 = To move but don't size the image with the cell,
+ * 3 = To prevent the image from moving or being resized along with the cell. If
+ * an image is inserted using this class and placed into a single cell then if
+ * the setAnchorType(int) method is called and a value of either 0 or 2 passed
+ * to it, the resultant resizing behaviour may be a surprise. The image will not
+ * grow in size of the column is made wider or the row higher but it will shrink
+ * if the columns width or rows height are reduced.
+ *
+ * @author Mark Beardsley [msb at apache.org]
+ * @version 1.00 5th August 2009.
+ */
+public class AddDimensionedImage {
+
+    // Four constants that determine how - and indeed whether - the rows
+    // and columns an image may overlie should be expanded to accomodate that
+    // image.
+    // Passing EXPAND_ROW will result in the height of a row being increased
+    // to accomodate the image if it is not already larger. The image will
+    // be layed across one or more columns.
+    // Passing EXPAND_COLUMN will result in the width of the column being
+    // increased to accomodate the image if it is not already larger. The image
+    // will be layed across one or many rows.
+    // Passing EXPAND_ROW_AND_COLUMN will result in the height of the row
+    // bing increased along with the width of the column to accomdate the
+    // image if either is not already larger.
+    // Passing OVERLAY_ROW_AND_COLUMN will result in the image being layed
+    // over one or more rows and columns. No row or column will be resized,
+    // instead, code will determine how many rows and columns the image should
+    // overlie.
+    public static final int EXPAND_ROW = 1;
+    public static final int EXPAND_COLUMN = 2;
+    public static final int EXPAND_ROW_AND_COLUMN = 3;
+    public static final int OVERLAY_ROW_AND_COLUMN = 7;
+
+    /**
+     * Add an image to a worksheet.
+     *
+     * @param cellNumber A String that contains the location of the cell whose
+     *                   top left hand corner should be aligned with the top
+     *                   left hand corner of the image; for example "A1", "A2"
+     *                   etc. This is to support the familiar Excel syntax.
+     *                   Whilst images are are not actually inserted into cells
+     *                   this provides a convenient method of indicating where
+     *                   the image should be positioned on the sheet.
+     * @param sheet A reference to the sheet that contains the cell referenced
+     *              above.
+     * @param imageFile A String that encapsulates the name of and path to
+     *                  the image that is to be 'inserted into' the sheet.
+     * @param reqImageWidthMM A primitive double that contains the required
+     *                        width of the image in millimetres.
+     * @param reqImageHeightMM A primitive double that contains the required
+     *                         height of the image in millimetres.
+     * @param resizeBehaviour A primitive int whose value will determine how
+     *                        the code should react if the image is larger than
+     *                        the cell referenced by the cellNumber parameter.
+     *                        Four constants are provided to determine what
+     *                        should happen;
+     *                          AddDimensionedImage.EXPAND_ROW
+     *                          AddDimensionedImage.EXPAND_COLUMN
+     *                          AddDimensionedImage.EXPAND_ROW_AND_COLUMN
+     *                          AddDimensionedImage.OVERLAY_ROW_AND_COLUMN
+     * @throws java.io.FileNotFoundException If the file containing the image
+     *                                       cannot be located.
+     * @throws java.io.IOException If a problem occurs whilst reading the file
+     *                             of image data.
+     * @throws java.lang.IllegalArgumentException If an invalid value is passed
+     *                                            to the resizeBehaviour
+     *                                            parameter.
+     */
+    public void addImageToSheet(String cellNumber, HSSFSheet sheet,
+            String imageFile, double reqImageWidthMM, double reqImageHeightMM,
+            int resizeBehaviour) throws FileNotFoundException, IOException,
+                                                      IllegalArgumentException {
+        // Convert the String into column and row indices then chain the
+        // call to the overridden addImageToSheet() method.
+        CellReference cellRef = new CellReference(cellNumber);
+        this.addImageToSheet(cellRef.getCol(), cellRef.getRow(), sheet,
+                imageFile, reqImageWidthMM, reqImageHeightMM,resizeBehaviour);
+    }
+
+    /**
+     * Add an image to a worksheet.
+     *
+     * @param colNumber A primitive int that contains the index number of a
+     *                  column on the worksheet; POI column indices are zero
+     *                  based. Together with the rowNumber parameter's value,
+     *                  this parameter identifies a cell on the worksheet. The
+     *                  image's top left hand corner will be aligned with the
+     *                  top left hand corner of this cell.
+     * @param rowNumber A primtive int that contains the index number of a row
+     *                  on the worksheet; POI row indices are zero based.
+     *                  Together with the rowNumber parameter's value, this
+     *                  parameter identifies a cell on the worksheet. The
+     *                  image's top left hand corner will be aligned with the
+     *                  top left hand corner of this cell.
+     * @param sheet A reference to the sheet that contains the cell identified
+     *              by the two parameters above.
+     * @param imageFile A String that encapsulates the name of and path to
+     *                  the image that is to be 'inserted into' the sheet.
+     * @param reqImageWidthMM A primitive double that contains the required
+     *                        width of the image in millimetres.
+     * @param reqImageHeightMM A primitive double that contains the required
+     *                         height of the image in millimetres.
+     * @param resizeBehaviour A primitive int whose value will determine how
+     *                        the code should react if the image is larger than
+     *                        the cell referenced by the colNumber and
+     *                        rowNumber parameters. Four constants are provided
+     *                        to determine what should happen;
+     *                          AddDimensionedImage.EXPAND_ROW
+     *                          AddDimensionedImage.EXPAND_COLUMN
+     *                          AddDimensionedImage.EXPAND_ROW_AND_COLUMN
+     *                          AddDimensionedImage.OVERLAY_ROW_AND_COLUMN
+     * @throws java.io.FileNotFoundException If the file containing the image
+     *                                       cannot be located.
+     * @throws java.io.IOException If a problem occurs whilst reading the file
+     *                             of image data.
+     * @throws java.lang.IllegalArgumentException If an invalid value is passed
+     *                                            to the resizeBehaviour
+     *                                            parameter.
+     */
+    private void addImageToSheet(int colNumber, int rowNumber, HSSFSheet sheet,
+            String imageFile, double reqImageWidthMM, double reqImageHeightMM,
+            int resizeBehaviour) throws FileNotFoundException, IOException,
+                                                     IllegalArgumentException  {
+        HSSFRow row = null;
+        HSSFClientAnchor anchor = null;
+        HSSFPatriarch patriarch = null;
+        ClientAnchorDetail rowClientAnchorDetail = null;
+        ClientAnchorDetail colClientAnchorDetail = null;
+
+        // Validate the resizeBehaviour parameter.
+        if((resizeBehaviour != AddDimensionedImage.EXPAND_COLUMN) &&
+           (resizeBehaviour != AddDimensionedImage.EXPAND_ROW) &&
+           (resizeBehaviour != AddDimensionedImage.EXPAND_ROW_AND_COLUMN) &&
+           (resizeBehaviour != AddDimensionedImage.OVERLAY_ROW_AND_COLUMN)) {
+            throw new IllegalArgumentException("Invalid value passed to the " +
+                    "resizeBehaviour parameter of AddDimensionedImage.addImageToSheet()");
+        }
+
+        // Call methods to calculate how the image and sheet should be
+        // manipulated to accomodate the image; columns and then rows.
+        colClientAnchorDetail = this.fitImageToColumns(sheet, colNumber,
+                reqImageWidthMM, resizeBehaviour);
+        rowClientAnchorDetail = this.fitImageToRows(sheet, rowNumber,
+                reqImageHeightMM, resizeBehaviour);
+
+        // Having determined if and how to resize the rows, columns and/or the
+        // image, create the HSSFClientAnchor object to position the image on
+        // the worksheet. Note how the two ClientAnchorDetail records are
+        // interrogated to recover the row/column co-ordinates and any insets.
+        // The first two parameters are not used currently but could be if the
+        // need arose to extend the functionality of this code by adding the
+        // ability to specify that a clear 'border' be placed around the image.
+        anchor = new HSSFClientAnchor(0,
+                                      0,
+                                      colClientAnchorDetail.getInset(),
+                                      rowClientAnchorDetail.getInset(),
+                                      (short)colClientAnchorDetail.getFromIndex(),
+                                      rowClientAnchorDetail.getFromIndex(),
+                                      (short)colClientAnchorDetail.getToIndex(),
+                                      rowClientAnchorDetail.getToIndex());
+
+        // For now, set the anchor type to do not move or resize the
+        // image as the size of the row/column is adjusted. This could easilly
+        // become another parameter passed to the method.
+        //anchor.setAnchorType(HSSFClientAnchor.DONT_MOVE_AND_RESIZE);
+        anchor.setAnchorType(HSSFClientAnchor.MOVE_AND_RESIZE);
+        
+        // Now, add the picture to the workbook. Note that the type is assumed
+        // to be a JPEG/JPG, this could easily (and should) be parameterised
+        // however.
+        //int index = sheet.getWorkbook().addPicture(this.imageToBytes(imageFile),
+        //            HSSFWorkbook.PICTURE_TYPE_JPEG);
+        int index = sheet.getWorkbook().addPicture(this.imageToBytes(imageFile), HSSFWorkbook.PICTURE_TYPE_PNG);
+
+        // Get the drawing patriarch and create the picture.
+        patriarch = sheet.createDrawingPatriarch();
+        patriarch.createPicture(anchor, index);
+    }
+
+    /**
+     * Determines whether the sheets columns should be re-sized to accomodate
+     * the image, adjusts the columns width if necessary and creates then
+     * returns a ClientAnchorDetail object that facilitates construction of
+     * an HSSFClientAnchor that will fix the image on the sheet and establish
+     * it's size.
+     *
+     * @param sheet A reference to the sheet that will 'contain' the image.
+     * @param colNumber A primtive int that contains the index number of a
+     *                  column on the sheet.
+     * @param reqImageWidthMM A primtive double that contains the required
+     *                        width of the image in millimetres
+     * @param resizeBehaviour A primitve int whose value will indicate how the
+     *                        width of the column should be adjusted if the
+     *                        required width of the image is greater than the
+     *                        width of the column.
+     * @return An instance of the ClientAnchorDetail class that will contain
+     *         the index number of the column containing the cell whose top
+     *         left hand corner also defines the top left hand corner of the
+     *         image, the index number column containing the cell whose top
+     *         left hand corner also defines the bottom right hand corner of
+     *         the image and an inset that determines how far the right hand
+     *         edge of the image can protrude into the next column - expressed
+     *         as a specific number of co-ordinate positions.
+     */
+    private ClientAnchorDetail fitImageToColumns(HSSFSheet sheet, int colNumber,
+            double reqImageWidthMM, int resizeBehaviour) {
+
+        double colWidthMM = 0.0D;
+        double colCoordinatesPerMM = 0.0D;
+        int pictureWidthCoordinates = 0;
+        ClientAnchorDetail colClientAnchorDetail = null;
+
+        // Get the colum's width in millimetres
+        colWidthMM = ConvertImageUnits.widthUnits2Millimetres(
+                (short)sheet.getColumnWidth(colNumber));
+
+        // Check that the column's width will accomodate the image at the
+        // required dimension. If the width of the column is LESS than the
+        // required width of the image, decide how the application should
+        // respond - resize the column or overlay the image across one or more
+        // columns.
+        if(colWidthMM < reqImageWidthMM) {
+
+            // Should the column's width simply be expanded?
+            if((resizeBehaviour == AddDimensionedImage.EXPAND_COLUMN) ||
+               (resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) {
+                // Set the width of the column by converting the required image
+                // width from millimetres into Excel's column width units.
+                sheet.setColumnWidth(colNumber,
+                        ConvertImageUnits.millimetres2WidthUnits(reqImageWidthMM));
+                // To make the image occupy the full width of the column, convert
+                // the required width of the image into co-ordinates. This value
+                // will become the inset for the ClientAnchorDetail class that
+                // is then instantiated.
+                colWidthMM = reqImageWidthMM;
+                colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS /
+                    colWidthMM;
+                pictureWidthCoordinates = (int)(reqImageWidthMM * colCoordinatesPerMM);
+                colClientAnchorDetail = new ClientAnchorDetail(colNumber,
+                        colNumber, pictureWidthCoordinates);
+            }
+            // If the user has chosen to overlay both rows and columns or just
+            // to expand ONLY the size of the rows, then calculate how to lay
+            // the image out across one or more columns.
+            else if ((resizeBehaviour == AddDimensionedImage.OVERLAY_ROW_AND_COLUMN) ||
+                     (resizeBehaviour == AddDimensionedImage.EXPAND_ROW)) {
+                colClientAnchorDetail = this.calculateColumnLocation(sheet,
+                        colNumber, reqImageWidthMM);
+            }
+        }
+        // If the column is wider than the image.
+        else {
+            // Mow many co-ordinate positions are there per millimetre?
+            colCoordinatesPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS /
+                    colWidthMM;
+            // Given the width of the image, what should be it's co-ordinate?
+            pictureWidthCoordinates = (int)(reqImageWidthMM * colCoordinatesPerMM);
+            colClientAnchorDetail = new ClientAnchorDetail(colNumber,
+                    colNumber, pictureWidthCoordinates);
+        }
+        return(colClientAnchorDetail);
+    }
+
+    /**
+     * Determines whether the sheet's row should be re-sized to accomodate
+     * the image, adjusts the rows height if necessary and creates then
+     * returns a ClientAnchorDetail object that facilitates construction of
+     * an HSSFClientAnchor that will fix the image on the sheet and establish
+     * it's size.
+     *
+     * @param sheet A reference to the sheet that will 'contain' the image.
+     * @param rowNumber A primtive int that contains the index number of a
+     *                  row on the sheet.
+     * @param reqImageHeightMM A primtive double that contains the required
+     *                         height of the image in millimetres
+     * @param resizeBehaviour A primitve int whose value will indicate how the
+     *                        height of the row should be adjusted if the
+     *                        required height of the image is greater than the
+     *                        height of the row.
+     * @return An instance of the ClientAnchorDetail class that will contain
+     *         the index number of the row containing the cell whose top
+     *         left hand corner also defines the top left hand corner of the
+     *         image, the index number of the row containing the cell whose
+     *         top left hand corner also defines the bottom right hand
+     *         corner of the image and an inset that determines how far the
+     *         bottom edge of the image can protrude into the next (lower)
+     *         row - expressed as a specific number of co-ordinate positions.
+     */
+    private ClientAnchorDetail fitImageToRows(HSSFSheet sheet, int rowNumber,
+            double reqImageHeightMM, int resizeBehaviour) {
+        HSSFRow row = null;
+        double rowHeightMM = 0.0D;
+        double rowCoordinatesPerMM = 0.0D;
+        int pictureHeightCoordinates = 0;
+        ClientAnchorDetail rowClientAnchorDetail = null;
+
+        // Get the row and it's height
+        row = sheet.getRow(rowNumber);
+        if(row == null) {
+            // Create row if it does not exist.
+            row = sheet.createRow(rowNumber);
+        }
+
+        // Get the row's height in millimetres
+        rowHeightMM = row.getHeightInPoints() / ConvertImageUnits.POINTS_PER_MILLIMETRE;
+
+        // Check that the row's height will accomodate the image at the required
+        // dimensions. If the height of the row is LESS than the required height
+        // of the image, decide how the application should respond - resize the
+        // row or overlay the image across a series of rows.
+        if(rowHeightMM < reqImageHeightMM) {
+            if((resizeBehaviour == AddDimensionedImage.EXPAND_ROW) ||
+               (resizeBehaviour == AddDimensionedImage.EXPAND_ROW_AND_COLUMN)) {
+                row.setHeightInPoints((float)(reqImageHeightMM *
+                        ConvertImageUnits.POINTS_PER_MILLIMETRE));
+                rowHeightMM = reqImageHeightMM;
+                rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS /
+                    rowHeightMM;
+                pictureHeightCoordinates = (int)(reqImageHeightMM * rowCoordinatesPerMM);
+                rowClientAnchorDetail = new ClientAnchorDetail(rowNumber,
+                        rowNumber, pictureHeightCoordinates);
+            }
+            // If the user has chosen to overlay both rows and columns or just
+            // to expand ONLY the size of the columns, then calculate how to lay
+            // the image out ver one or more rows.
+            else if((resizeBehaviour == AddDimensionedImage.OVERLAY_ROW_AND_COLUMN) ||
+                    (resizeBehaviour == AddDimensionedImage.EXPAND_COLUMN)) {
+                rowClientAnchorDetail = this.calculateRowLocation(sheet,
+                        rowNumber, reqImageHeightMM);
+            }
+        }
+        // Else, if the image is smaller than the space available
+        else {
+            rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS /
+                    rowHeightMM;
+            pictureHeightCoordinates = (int)(reqImageHeightMM * rowCoordinatesPerMM);
+            rowClientAnchorDetail = new ClientAnchorDetail(rowNumber,
+                        rowNumber, pictureHeightCoordinates);
+        }
+        return(rowClientAnchorDetail);
+    }
+
+    /**
+     * If the image is to overlie more than one column, calculations need to be
+     * performed to determine how many columns and whether the image will
+     * overlie just a part of one column in order to be presented at the
+     * required size.
+     *
+     * @param sheet The sheet that will 'contain' the image.
+     * @param startingColumn A primitive int whose value is the index of the
+     *                       column that contains the cell whose top left hand
+     *                       corner should be aligned with the top left hand
+     *                       corner of the image.
+     * @param reqImageWidthMM A primitive double whose value will indicate the
+     *                        required width of the image in millimetres.
+     * @return An instance of the ClientAnchorDetail class that will contain
+     *         the index number of the column containing the cell whose top
+     *         left hand corner also defines the top left hand corner of the
+     *         image, the index number column containing the cell whose top
+     *         left hand corner also defines the bottom right hand corner of
+     *         the image and an inset that determines how far the right hand
+     *         edge of the image can protrude into the next column - expressed
+     *         as a specific number of co-ordinate positions.
+     */
+    private ClientAnchorDetail calculateColumnLocation(HSSFSheet sheet,
+                                                       int startingColumn,
+                                                       double reqImageWidthMM) {
+        ClientAnchorDetail anchorDetail = null;
+        double totalWidthMM = 0.0D;
+        double colWidthMM = 0.0D;
+        double overlapMM = 0.0D;
+        double coordinatePositionsPerMM = 0.0D;
+        int fromNumber = startingColumn;
+        int toColumn = startingColumn;
+        int inset = 0;
+
+        // Calculate how many columns the image will have to
+        // span in order to be presented at the required size.
+        while(totalWidthMM < reqImageWidthMM) {
+            colWidthMM = ConvertImageUnits.widthUnits2Millimetres(
+                    (short)(sheet.getColumnWidth(toColumn)));
+            // Note use of the cell border width constant. Testing with an image
+            // declared to fit exactly into one column demonstrated that it's
+            // width was greater than the width of the column the POI returned.
+            // Further, this difference was a constant value that I am assuming
+            // related to the cell's borders. Either way, that difference needs
+            // to be allowed for in this calculation.
+            totalWidthMM += (colWidthMM + ConvertImageUnits.CELL_BORDER_WIDTH_MILLIMETRES);
+            toColumn++;
+        }
+        // De-crement by one the last column value.
+        toColumn--;
+        // Highly unlikely that this will be true but, if the width of a series
+        // of columns is exactly equal to the required width of the image, then
+        // simply build a ClientAnchorDetail object with an inset equal to the
+        // total number of co-ordinate positions available in a column, a
+        // from column co-ordinate (top left hand corner) equal to the value
+        // of the startingColumn parameter and a to column co-ordinate equal
+        // to the toColumn variable.
+        //
+        // Convert both values to ints to perform the test.
+        if((int)totalWidthMM == (int)reqImageWidthMM) {
+            // A problem could occur if the image is sized to fit into one or
+            // more columns. If that occurs, the value in the toColumn variable
+            // will be in error. To overcome this, there are two options, to
+            // ibcrement the toColumn variable's value by one or to pass the
+            // total number of co-ordinate positions to the third paramater
+            // of the ClientAnchorDetail constructor. For no sepcific reason,
+            // the latter option is used below.
+            anchorDetail = new ClientAnchorDetail(startingColumn, 
+                    toColumn, ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS);
+        }
+        // In this case, the image will overlap part of another column and it is
+        // necessary to calculate just how much - this will become the inset
+        // for the ClientAnchorDetail object.
+        else {
+            // Firstly, claculate how much of the image should overlap into
+            // the next column.
+            overlapMM = reqImageWidthMM - (totalWidthMM - colWidthMM);
+
+            // When the required size is very close indded to the column size,
+            // the calcaulation above can produce a negative value. To prevent
+            // problems occuring in later caculations, this is simply removed
+            // be setting the overlapMM value to zero.
+            if(overlapMM < 0) {
+                overlapMM = 0.0D;
+            }
+
+            // Next, from the columns width, calculate how many co-ordinate
+            // positons there are per millimetre
+            coordinatePositionsPerMM = ExcelUtil.TOTAL_COLUMN_COORDINATE_POSITIONS /
+                    colWidthMM;
+            // From this figure, determine how many co-ordinat positions to
+            // inset the left hand or bottom edge of the image.
+            inset = (int)(coordinatePositionsPerMM * overlapMM);
+
+            // Now create the ClientAnchorDetail object, setting the from and to
+            // columns and the inset.
+            anchorDetail = new ClientAnchorDetail(startingColumn, toColumn, inset);
+        }
+        return(anchorDetail);
+    }
+
+    /**
+     * If the image is to overlie more than one rows, calculations need to be
+     * performed to determine how many rows and whether the image will
+     * overlie just a part of one row in order to be presented at the
+     * required size.
+     *
+     * @param sheet The sheet that will 'contain' the image.
+     * @param startingRow A primitive int whose value is the index of the row
+     *                    that contains the cell whose top left hand corner
+     *                    should be aligned with the top left hand corner of
+     *                    the image.
+     * @param reqImageHeightMM A primitive double whose value will indicate the
+     *                         required height of the image in millimetres.
+     * @return An instance of the ClientAnchorDetail class that will contain
+     *         the index number of the row containing the cell whose top
+     *         left hand corner also defines the top left hand corner of the
+     *         image, the index number of the row containing the cell whose top
+     *         left hand corner also defines the bottom right hand corner of
+     *         the image and an inset that determines how far the bottom edge
+     *         can protrude into the next (lower) row - expressed as a specific
+     *         number of co-ordinate positions.
+     */
+    private ClientAnchorDetail calculateRowLocation(HSSFSheet sheet,
+            int startingRow, double reqImageHeightMM) {
+        ClientAnchorDetail clientAnchorDetail = null;
+        HSSFRow row = null;
+        double rowHeightMM = 0.0D;
+        double totalRowHeightMM = 0.0D;
+        double overlapMM = 0.0D;
+        double rowCoordinatesPerMM = 0.0D;
+        int toRow = startingRow;
+        int inset = 0;
+
+        // Step through the rows in the sheet and accumulate a total of their
+        // heights.
+        while(totalRowHeightMM < reqImageHeightMM) {
+            row = sheet.getRow(toRow);
+            // Note, if the row does not already exist on the sheet then create
+            // it here.
+            if(row == null) {
+                row = sheet.createRow(toRow);
+            }
+            // Get the row's height in millimetres and add to the running total.
+            rowHeightMM = row.getHeightInPoints() /
+                    ConvertImageUnits.POINTS_PER_MILLIMETRE;
+            totalRowHeightMM += rowHeightMM;
+            toRow++;
+        }
+        // Owing to the way the loop above works, the rowNumber will have been
+        // incremented one row too far. Undo that here.
+        toRow--;
+        // Check to see whether the image should occupy an exact number of
+        // rows. If so, build the ClientAnchorDetail record to point
+        // to those rows and with an inset of the total number of co-ordinate
+        // position in the row.
+        //
+        // To overcome problems that can occur with comparing double values for
+        // equality, cast both to int(s) to truncate the value; VERY crude and
+        // I do not really like it!!
+        if((int)totalRowHeightMM == (int)reqImageHeightMM) {
+            clientAnchorDetail = new ClientAnchorDetail(startingRow, toRow,
+                    ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS);
+        }
+        else {
+            // Calculate how far the image will project into the next row. Note
+            // that the height of the last row assessed is subtracted from the
+            // total height of all rows assessed so far.
+            overlapMM = reqImageHeightMM - (totalRowHeightMM - rowHeightMM);
+
+            // To prevent an exception being thrown when the required width of
+            // the image is very close indeed to the column size.
+            if(overlapMM < 0) {
+                overlapMM = 0.0D;
+            }
+
+            rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS /
+                    rowHeightMM;
+            inset = (int)(overlapMM * rowCoordinatesPerMM);
+            clientAnchorDetail = new ClientAnchorDetail(startingRow,
+                        toRow, inset);
+        }
+        return(clientAnchorDetail);
+    }
+
+    /**
+     * Loads - reads in and converts into an array of byte(s) - an image from
+     * a named file.
+     *
+     * Note: this method should be modified so that the type of the image may
+     * also be passed to it. Currently, it assumes that all images are
+     * JPG/JPEG(s).
+     *
+     * @param imageFilename A String that encapsulates the path to and name
+     *                      of the file that contains the image which is to be
+     *                      'loaded'.
+     * @return An array of type byte that contains the raw data of the named
+     *         image.
+     * @throws java.io.FileNotFoundException Thrown if it was not possible to
+     *                                       open the specified file.
+     * @throws java.io.IOException Thrown if reading the file failed or was
+     *                             interrupted.
+     */
+    private byte[] imageToBytes(String imageFilename)
+                                     throws FileNotFoundException, IOException {
+        File imageFile = null;
+        FileInputStream fis = null;
+        ByteArrayOutputStream bos = null;
+        int read = 0;
+        try {
+            imageFile = new File(imageFilename);
+            fis = new FileInputStream(imageFile);
+            bos = new ByteArrayOutputStream();
+            while((read = fis.read()) != -1) {
+                bos.write(read);
+            }
+            return(bos.toByteArray());
+        }
+        finally {
+            if(fis != null) {
+                try {
+                    fis.close();
+                    fis = null;
+                }
+                catch(IOException ioEx) {
+                    // Nothing to do here
+                }
+            }
+        }
+    }
+
+    /**
+     * The main entry point to the program. It contains code that demonstrates
+     * one way to use the program.
+     *
+     * Note, the code is not restricted to use on new workbooks only. If an
+     * image is to be inserted into an existing workbook. just open that
+     * workbook, gat a reference to a sheet and pass that;
+     *
+     *      AddDimensionedImage addImage = new AddDimensionedImage();
+     *
+     *      File file = new File("....... Existing Workbook .......");
+     *      FileInputStream fis = new FileInputStream(file);

[... 228 lines stripped ...]


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message