Class AddDimensionedImage
- java.lang.Object
-
- org.apache.poi.examples.ss.AddDimensionedImage
-
- Direct Known Subclasses:
AddDimensionedImage
public class AddDimensionedImage extends Object
Demonstrates how to add an image to a worksheet and set that images size to a specific number of millimetres 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 coordinates 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 methodology 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 ClientAnchor class. It defines methods that allow us to define the location of an image by specifying the following;
* How far - in terms of coordinate positions - the image should be inset from the left hand border of a cell. * How far - in terms of coordinate positions - the image should be inset from the from the top of the cell. * How far - in terms of coordinate positions - the right hand edge of the image should protrude into a cell (measured from the cells left hand edge to the images right hand edge). * How far - in terms of coordinate positions - the bottom edge of the image should protrude into a row (measured from the cells top edge to the images 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 images top left hand corner. * The index of the column that contains the cell whose top left hand corner should be aligned with the images 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;
ClientAnchor anchor = sheet.getWorkbook().getCreationHelper().createClientAnchor();
anchor.setDx1(0); anchor.setDy1(0); anchor.setDx2(0); anchor.setDy2(0); anchor.setCol1(0); anchor.setRow1(0); anchor.setCol2(1); anchor.setRow2(1);
Taken together, the first four methods define the locations of the top left and bottom right hand corners of the image if you imagine that the image is represented by a simple rectangle. The setDx1() and setDy1() methods locate the top left hand corner of the image while setDx2() and and Dy2() locate the bottom right hand corner of the image. An individual image can be inserted into a single cell or is can lie across many cells and the latter four methods are used to define just where the image should be positioned. They do this by again by identifying where the top left and bottom right hand corners of the image should be located but this time in terms of the indexes of the cells in which those corners should be located. The setCol1() and setRow1() methods together identify the cell that should contain the top left hand corner of the image while setCol2() and setRow2() do the same for the images bottom right hand corner.
Knowing that, it is possible to look again at the example above and to see that the top left hand corner of the image will be located in cell A1 (0, 0) and it will be aligned with the very top left hand corner of the cell. Likewise, the bottom right hand corner of the image will be located in cell B2 (1, 1) and it will again be aligned with the top left hand corner of the cell. This has the effect of making the image seem to occupy the whole of cell A1. Interestingly, it also has an effect on the images resizing behaviour because testing has demonstrated that if the image is wholly contained within one cell and is not 'attached' for want of a better word, to a neighbouring cell, then that image will not increase in size in response to the user dragging the column wider or the cell higher.
The following example demonstrates a slightly different way to insert an image into cell A1 and to ensure that it occupies the whole of the cell. This is accomplished by specifying the images bottom right hand corner should be aligned with the bottom right hand corner of the cell. It is also a case where the image will not increase in size if the user increases the size of the enclosing cell - irrespective of the anchors type - but it will reduce in size if the cell is made smaller.
ClientAnchor anchor = sheet.getWorkbook().getCreationHelper().createClientAnchor();
anchor.setDx1(0); anchor.setDy1(0); anchor.setDx2(1023); anchor.setDy2(255); anchor.setCol1(0); anchor.setRow1(0); anchor.setCol2(0); anchor.setRow2(0);
Note that the final four method calls all pass 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 determining the images coordinates 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 Excels characters units, points, pixels and millimetres in order to establish how many rows/columns an image should occupy and just what the various insets ought to be.
Note that the setDx1(int) and setDy1(int) methods of the ClientAchor class are not made use of in the code that follows. It would be fairly trivial however to extend this 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 ClientAnchor class contains a method called setAnchorType(int) which can be used to determine how Excel will resize an image in response 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.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classAddDimensionedImage.ClientAnchorDetailThe HSSFClientAnchor class accepts eight arguments.static classAddDimensionedImage.ConvertImageUnitsUtility methods used to convert Excels character based column and row size measurements into pixels and/or millimetres.
-
Field Summary
Fields Modifier and Type Field Description static intEXPAND_COLUMNstatic intEXPAND_ROWstatic intEXPAND_ROW_AND_COLUMNstatic intOVERLAY_ROW_AND_COLUMN
-
Constructor Summary
Constructors Constructor Description AddDimensionedImage()
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidaddImageToSheet(int colNumber, int rowNumber, Sheet sheet, Drawing<?> drawing, URL imageFile, double reqImageWidthMM, double reqImageHeightMM, int resizeBehaviour)Add an image to a worksheet.voidaddImageToSheet(String cellNumber, Sheet sheet, Drawing<?> drawing, URL imageFile, double reqImageWidthMM, double reqImageHeightMM, int resizeBehaviour)Add an image to a worksheet.static voidmain(String[] args)The main entry point to the program.
-
-
-
Field Detail
-
EXPAND_ROW
public static final int EXPAND_ROW
- See Also:
- Constant Field Values
-
EXPAND_COLUMN
public static final int EXPAND_COLUMN
- See Also:
- Constant Field Values
-
EXPAND_ROW_AND_COLUMN
public static final int EXPAND_ROW_AND_COLUMN
- See Also:
- Constant Field Values
-
OVERLAY_ROW_AND_COLUMN
public static final int OVERLAY_ROW_AND_COLUMN
- See Also:
- Constant Field Values
-
-
Method Detail
-
addImageToSheet
public void addImageToSheet(String cellNumber, Sheet sheet, Drawing<?> drawing, URL imageFile, double reqImageWidthMM, double reqImageHeightMM, int resizeBehaviour) throws IOException, IllegalArgumentException
Add an image to a worksheet.- Parameters:
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 not actually inserted into cells this provides a convenient method of indicating where the image should be positioned on the sheet.sheet- A reference to the sheet that contains the cell referenced above.drawing- An instance of the DrawingPatriarch class. This is now passed into the method where it was, previously, recovered from the sheet in order to allow multiple pictures be inserted. If the patriarch was not 'cached in this manner each time it was created any previously positioned images would be simply over-written.imageFile- An instance of the URL class that encapsulates the name of and path to the image that is to be 'inserted into' the sheet.reqImageWidthMM- A primitive double that contains the required width of the image in millimetres.reqImageHeightMM- A primitive double that contains the required height of the image in millimetres.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:
FileNotFoundException- If the file containing the image cannot be located.IOException- If a problem occurs whilst reading the file of image data.IllegalArgumentException- If an invalid value is passed to the resizeBehaviour parameter.
-
addImageToSheet
public void addImageToSheet(int colNumber, int rowNumber, Sheet sheet, Drawing<?> drawing, URL imageFile, double reqImageWidthMM, double reqImageHeightMM, int resizeBehaviour) throws IOException, IllegalArgumentExceptionAdd an image to a worksheet.- Parameters:
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 images top left hand corner will be aligned with the top left hand corner of this cell.rowNumber- A primitive 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 images top left hand corner will be aligned with the top left hand corner of this cell.sheet- A reference to the sheet that contains the cell identified by the two parameters above.drawing- An instance of the DrawingPatriarch class. This is now passed into the method where it was, previously, recovered from the sheet in order to allow multiple pictures be inserted. If the patriarch was not 'cached in this manner each time it was created any previously positioned images would be simply over-written.imageFile- An instance of the URL class that encapsulates the name of and path to the image that is to be 'inserted into' the sheet.reqImageWidthMM- A primitive double that contains the required width of the image in millimetres.reqImageHeightMM- A primitive double that contains the required height of the image in millimetres.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:
FileNotFoundException- If the file containing the image cannot be located.IOException- If a problem occurs whilst reading the file of image data.IllegalArgumentException- If an invalid value is passed to the resizeBehaviour parameter or if the extension of the image file indicates that it is of a type that cannot currently be added to the worksheet.
-
main
public static void main(String[] args) throws IOException
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); Workbook workbook = new HSSFWorkbook(fis); HSSFSheet sheet = workbook.getSheetAt(0); addImage.addImageToSheet("C3", sheet, "image.jpg", 30, 20, AddDimensionedImage.EXPAND.ROW);
- Parameters:
args- the command line arguments- Throws:
IOException
-
-