diff --git a/src/documentation/content/xdocs/hssf/quick-guide.xml b/src/documentation/content/xdocs/hssf/quick-guide.xml index 39a175338..df76e74a6 100644 --- a/src/documentation/content/xdocs/hssf/quick-guide.xml +++ b/src/documentation/content/xdocs/hssf/quick-guide.xml @@ -40,6 +40,9 @@
  • Create split and freeze panes.
  • Repeating rows and columns.
  • Headers and Footers.
  • +
  • Drawing Shapes.
  • +
  • Styling Shapes.
  • +
  • Shapes and Graphics2d.
  • Features @@ -672,6 +675,7 @@ fileOut.close();
    +
    Headers and Footers

    @@ -692,6 +696,211 @@ fileOut.close();

    + + +
    Drawing Shapes +

    + POI supports drawing shapes using the Microsoft Office + drawing tools. Shapes on a sheet are organized in a + hiearchy of groups and and shapes. The top-most shape + is the patriarch. This is not visisble on the sheet + at all. To start drawing you need to call createPatriarch + on the HSSFSheet class. This has the + effect erasing any other shape information stored + in that sheet. By default POI will leave shape + records alone in the sheet unless you make a call to + this method. +

    +

    + To create a shape you have to go through the following + steps: +

    +
      +
    1. Create the patriarch.
    2. +
    3. Create an anchor to position the shape on the sheet.
    4. +
    5. Ask the patriarch to create the shape.
    6. +
    7. Set the shape type (line, oval, rectangle etc...)
    8. +
    9. Set any other style details converning the shape. (eg: + line thickness, etc...)
    10. +
    + + HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); + a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 0, (short) 1, 0 ); + HSSFSimpleShape shape1 = patriarch.createSimpleShape(a1); + shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); + +

    + Text boxes are created using a different call: +

    + + HSSFTextbox textbox1 = patriarch.createTextbox( + new HSSFClientAnchor(0,0,0,0,(short)1,1,(short)2,2)); + textbox1.setString(new HSSFRichTextString("This is a test") ); + +

    + It's possible to use different fonts to style parts of + the text in the textbox. Here's how: +

    + + HSSFFont font = wb.createFont(); + font.setItalic(true); + font.setUnderline(HSSFFont.U_DOUBLE); + HSSFRichTextString string = new HSSFRichTextString("Woo!!!"); + string.applyFont(2,5,font); + textbox.setString(string ); + +

    + Just as can be done manually using Excel, it is possible + to group shapes together. This is done by calling + createGroup() and then creating the shapes + using those groups. +

    +

    + It's also possible to create groups within groups. +

    + Any group you create should contain at least two + other shapes or subgroups. +

    + Here's how to create a shape group: +

    + + // Create a shape group. + HSSFShapeGroup group = patriarch.createGroup( + new HSSFClientAnchor(0,0,900,200,(short)2,2,(short)2,2)); + + // Create a couple of lines in the group. + HSSFSimpleShape shape1 = group.createShape(new HSSFChildAnchor(3,3,500,500)); + shape1.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); + ( (HSSFChildAnchor) shape1.getAnchor() ).setAnchor((short)3,3,500,500); + HSSFSimpleShape shape2 = group.createShape(new HSSFChildAnchor((short)1,200,400,600)); + shape2.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE); + +

    + If you're being observant you'll noticed that the shapes + that are added to the group use a new type of anchor: + the HSSFChildAnchor. What happens is that + the created group has it's own coordinate space for + shapes that are placed into it. POI defaults this to + (0,0,1023,255) but you are able to change it as desired. + Here's how: +

    + + myGroup.setCoordinates(10,10,20,20); // top-left, bottom-right + +

    + If you create a group within a group it's also going + to have it's own coordinate space. +

    +
    + + +
    Styling Shapes +

    + By default shapes can look a little plain. It's possible + to apply different styles to the shapes however. The + sorts of things that can currently be done are: +

    +
      +
    • Change the fill color.
    • +
    • Make a shape with no fill color.
    • +
    • Change the thickness of the lines.
    • +
    • Change the style of the lines. Eg: dashed, dotted.
    • +
    • Change the line color.
    • +
    +

    + Here's an examples of how this is done: +

    + + HSSFSimpleShape s = patriarch.createSimpleShape(a); + s.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL); + s.setLineStyleColor(10,10,10); + s.setFillColor(90,10,200); + s.setLineWidth(HSSFShape.LINEWIDTH_ONE_PT * 3); + s.setLineStyle(HSSFShape.LINESTYLE_DOTSYS); + +
    + +
    Shapes and Graphics2d +

    + While the native POI shape drawing commands are the + recommended way to draw shapes in a shape it's sometimes + desirable to use a standard API for compatibility with + external libraries. With this in mind we created some + wrappers for Graphics and Graphics2d. +

    + + It's important to not however before continuing that + Graphics2d is a poor match to the capabilities + of the Microsoft Office drawing commands. The older + Graphics class offers a closer match but is + still a square peg in a round hole. + +

    + All Graphics commands are issued into an HSSFShapeGroup. + Here's how it's done: +

    + + a = new HSSFClientAnchor( 0, 0, 1023, 255, (short) 1, 0, (short) 1, 0 ); + group = patriarch.createGroup( a ); + group.setCoordinates( 0, 0, 80 * 4 , 12 * 23 ); + float verticalPointsPerPixel = a.getAnchorHeightInPoints(sheet) / (float)Math.abs(group.getY2() - group.getY1()); + g = new EscherGraphics( group, wb, Color.black, verticalPointsPerPixel ); + g2d = new EscherGraphics2d( g ); + drawChemicalStructure( g2d ); + +

    + The first thing we do is create the group and set it's coordinates + to match what we plan to draw. Next we calculate a reasonable + fontSizeMultipler then create the EscherGraphics object. + Since what we really want is a Graphics2d + object we create an EscherGraphics2d object and pass in + the graphics object we created. Finally we call a routine + that draws into the EscherGraphics2d object. +

    +

    + The vertical points per pixel deserves some more explanation. + One of the difficulties in converting Graphics calls + into escher drawing calls is that Excel does not have + the concept of absolute pixel positions. It measures + it's cell widths in 'characters' and the cell heights in points. + Unfortunately it's not defined exactly what type of character it's + measuring. Presumably this is due to the fact that the Excel will be + using different fonts on different platforms or even within the same + platform. +

    +

    + Because of this constraint we've had to implement the concept of a + verticalPointsPerPixel. This the amount the font should be scaled by when + you issue commands such as drawString(). To calculate this value + use the follow formula: +

    + + multipler = groupHeightInPoints / heightOfGroup + +

    + The height of the group is calculated fairly simply by calculating the + difference between the y coordinates of the bounding box of the shape. The + height of the group can be calculated by using a convenience called + HSSFClientAnchor.getAnchorHeightInPoints(). +

    +

    + Many of the functions supported by the graphics classes + are not complete. Here's some of the functions that are known + to work. +

    +
      +
    • fillRect()
    • +
    • fillOval()
    • +
    • drawString()
    • +
    • drawOval()
    • +
    • drawLine()
    • +
    • clearRect()
    • +
    +

    + Functions that are not supported will return and log a message + using the POI logging infrastructure (disabled by default). +

    +