User model for drawing format support

git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/branches/REL_2_BRANCH@353497 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Glen Stampoultzis 2004-02-10 22:00:27 +00:00
parent 3df231642a
commit 9ef45e5f61
20 changed files with 3500 additions and 133 deletions

View File

@ -0,0 +1,773 @@
package org.apache.poi.hssf.usermodel;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.awt.font.GlyphVector;
import java.awt.font.FontRenderContext;
import java.util.Map;
import java.text.AttributedCharacterIterator;
public class DummyGraphics2d
extends Graphics2D
{
BufferedImage img;
private Graphics2D g2D;
public DummyGraphics2d()
{
img = new BufferedImage(1000, 1000, 2);
g2D = (Graphics2D)img.getGraphics();
}
public void addRenderingHints(Map hints)
{
System.out.println( "addRenderingHinds(Map):" );
System.out.println( " hints = " + hints );
g2D.addRenderingHints( hints );
}
public void clip(Shape s)
{
System.out.println( "clip(Shape):" );
System.out.println( " s = " + s );
g2D.clip( s );
}
public void draw(Shape s)
{
System.out.println( "draw(Shape):" );
System.out.println( "s = " + s );
g2D.draw( s );
}
public void drawGlyphVector(GlyphVector g, float x, float y)
{
System.out.println( "drawGlyphVector(GlyphVector, float, float):" );
System.out.println( "g = " + g );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
g2D.drawGlyphVector( g, x, y );
}
public void drawImage(BufferedImage img,
BufferedImageOp op,
int x,
int y)
{
System.out.println( "drawImage(BufferedImage, BufferedImageOp, x, y):" );
System.out.println( "img = " + img );
System.out.println( "op = " + op );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
g2D.drawImage( img, op, x, y );
}
public boolean drawImage(Image img,
AffineTransform xform,
ImageObserver obs)
{
System.out.println( "drawImage(Image,AfflineTransform,ImageObserver):" );
System.out.println( "img = " + img );
System.out.println( "xform = " + xform );
System.out.println( "obs = " + obs );
return g2D.drawImage( img, xform, obs );
}
public void drawRenderableImage(RenderableImage img,
AffineTransform xform)
{
System.out.println( "drawRenderableImage(RenderableImage, AfflineTransform):" );
System.out.println( "img = " + img );
System.out.println( "xform = " + xform );
g2D.drawRenderableImage( img, xform );
}
public void drawRenderedImage(RenderedImage img,
AffineTransform xform)
{
System.out.println( "drawRenderedImage(RenderedImage, AffineTransform):" );
System.out.println( "img = " + img );
System.out.println( "xform = " + xform );
g2D.drawRenderedImage( img, xform );
}
public void drawString(AttributedCharacterIterator iterator,
float x, float y)
{
System.out.println( "drawString(AttributedCharacterIterator):" );
System.out.println( "iterator = " + iterator );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
g2D.drawString( iterator, x, y );
}
// public void drawString(AttributedCharacterIterator iterator,
// int x, int y)
// {
// g2D.drawString( iterator, x, y );
// }
public void drawString(String s, float x, float y)
{
System.out.println( "drawString(s,x,y):" );
System.out.println( "s = " + s );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
g2D.drawString( s, x, y );
}
// public void drawString(String str, int x, int y)
// {
// g2D.drawString( str, x, y );
// }
public void fill(Shape s)
{
System.out.println( "fill(Shape):" );
System.out.println( "s = " + s );
g2D.fill( s );
}
// public void fill3DRect(int x, int y, int width, int height,
// boolean raised) {
// g2D.fill3DRect( x, y, width, height, raised );
// }
public Color getBackground()
{
System.out.println( "getBackground():" );
return g2D.getBackground();
}
public Composite getComposite()
{
System.out.println( "getComposite():" );
return g2D.getComposite();
}
public GraphicsConfiguration getDeviceConfiguration()
{
System.out.println( "getDeviceConfiguration():" );
return g2D.getDeviceConfiguration();
}
public FontRenderContext getFontRenderContext()
{
System.out.println( "getFontRenderContext():" );
return g2D.getFontRenderContext();
}
public Paint getPaint()
{
System.out.println( "getPaint():" );
return g2D.getPaint();
}
public Object getRenderingHint(RenderingHints.Key hintKey)
{
System.out.println( "getRenderingHint(RenderingHints.Key):" );
System.out.println( "hintKey = " + hintKey );
return g2D.getRenderingHint( hintKey );
}
public RenderingHints getRenderingHints()
{
System.out.println( "getRenderingHints():" );
return g2D.getRenderingHints();
}
public Stroke getStroke()
{
System.out.println( "getStroke():" );
return g2D.getStroke();
}
public AffineTransform getTransform()
{
System.out.println( "getTransform():" );
return g2D.getTransform();
}
public boolean hit(Rectangle rect,
Shape s,
boolean onStroke)
{
System.out.println( "hit(Rectangle, Shape, onStroke):" );
System.out.println( "rect = " + rect );
System.out.println( "s = " + s );
System.out.println( "onStroke = " + onStroke );
return g2D.hit( rect, s, onStroke );
}
public void rotate(double theta)
{
System.out.println( "rotate(theta):" );
System.out.println( "theta = " + theta );
g2D.rotate( theta );
}
public void rotate(double theta, double x, double y)
{
System.out.println( "rotate(double,double,double):" );
System.out.println( "theta = " + theta );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
g2D.rotate( theta, x, y );
}
public void scale(double sx, double sy)
{
System.out.println( "scale(double,double):" );
System.out.println( "sx = " + sx );
System.out.println( "sy" );
g2D.scale( sx, sy );
}
public void setBackground(Color color)
{
System.out.println( "setBackground(Color):" );
System.out.println( "color = " + color );
g2D.setBackground( color );
}
public void setComposite(Composite comp)
{
System.out.println( "setComposite(Composite):" );
System.out.println( "comp = " + comp );
g2D.setComposite( comp );
}
public void setPaint( Paint paint )
{
System.out.println( "setPain(Paint):" );
System.out.println( "paint = " + paint );
g2D.setPaint( paint );
}
public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue)
{
System.out.println( "setRenderingHint(RenderingHints.Key, Object):" );
System.out.println( "hintKey = " + hintKey );
System.out.println( "hintValue = " + hintValue );
g2D.setRenderingHint( hintKey, hintValue );
}
public void setRenderingHints(Map hints)
{
System.out.println( "setRenderingHints(Map):" );
System.out.println( "hints = " + hints );
g2D.setRenderingHints( hints );
}
public void setStroke(Stroke s)
{
System.out.println( "setStroke(Stoke):" );
System.out.println( "s = " + s );
g2D.setStroke( s );
}
public void setTransform(AffineTransform Tx)
{
System.out.println( "setTransform():" );
System.out.println( "Tx = " + Tx );
g2D.setTransform( Tx );
}
public void shear(double shx, double shy)
{
System.out.println( "shear(shx, dhy):" );
System.out.println( "shx = " + shx );
System.out.println( "shy = " + shy );
g2D.shear( shx, shy );
}
public void transform(AffineTransform Tx)
{
System.out.println( "transform(AffineTransform):" );
System.out.println( "Tx = " + Tx );
g2D.transform( Tx );
}
public void translate(double tx, double ty)
{
System.out.println( "translate(double, double):" );
System.out.println( "tx = " + tx );
System.out.println( "ty = " + ty );
g2D.translate( tx, ty );
}
// public void translate(int x, int y)
// {
// g2D.translate( x, y );
// }
public void clearRect(int x, int y, int width, int height)
{
System.out.println( "clearRect(int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
g2D.clearRect( x, y, width, height );
}
public void clipRect(int x, int y, int width, int height)
{
System.out.println( "clipRect(int, int, int, int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
g2D.clipRect( x, y, width, height );
}
public void copyArea(int x, int y, int width, int height,
int dx, int dy)
{
System.out.println( "copyArea(int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
g2D.copyArea( x, y, width, height, dx, dy );
}
public Graphics create()
{
System.out.println( "create():" );
return g2D.create();
}
public Graphics create(int x, int y, int width, int height) {
System.out.println( "create(int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
return g2D.create( x, y, width, height );
}
public void dispose()
{
System.out.println( "dispose():" );
g2D.dispose();
}
public void draw3DRect(int x, int y, int width, int height,
boolean raised) {
System.out.println( "draw3DRect(int,int,int,int,boolean):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
System.out.println( "raised = " + raised );
g2D.draw3DRect( x, y, width, height, raised );
}
public void drawArc(int x, int y, int width, int height,
int startAngle, int arcAngle)
{
System.out.println( "drawArc(int,int,int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
System.out.println( "startAngle = " + startAngle );
System.out.println( "arcAngle = " + arcAngle );
g2D.drawArc( x, y, width, height, startAngle, arcAngle );
}
public void drawBytes(byte data[], int offset, int length, int x, int y) {
System.out.println( "drawBytes(byte[],int,int,int,int):" );
System.out.println( "data = " + data );
System.out.println( "offset = " + offset );
System.out.println( "length = " + length );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
g2D.drawBytes( data, offset, length, x, y );
}
public void drawChars(char data[], int offset, int length, int x, int y) {
System.out.println( "drawChars(data,int,int,int,int):" );
System.out.println( "data = " + data );
System.out.println( "offset = " + offset );
System.out.println( "length = " + length );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
g2D.drawChars( data, offset, length, x, y );
}
public boolean drawImage(Image img,
int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
ImageObserver observer)
{
System.out.println( "drawImage(Image,int,int,int,int,int,int,int,int,ImageObserver):" );
System.out.println( "img = " + img );
System.out.println( "dx1 = " + dx1 );
System.out.println( "dy1 = " + dy1 );
System.out.println( "dx2 = " + dx2 );
System.out.println( "dy2 = " + dy2 );
System.out.println( "sx1 = " + sx1 );
System.out.println( "sy1 = " + sy1 );
System.out.println( "sx2 = " + sx2 );
System.out.println( "sy2 = " + sy2 );
System.out.println( "observer = " + observer );
return g2D.drawImage( img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer );
}
public boolean drawImage(Image img,
int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
Color bgcolor,
ImageObserver observer)
{
System.out.println( "drawImage(Image,int,int,int,int,int,int,int,int,Color,ImageObserver):" );
System.out.println( "img = " + img );
System.out.println( "dx1 = " + dx1 );
System.out.println( "dy1 = " + dy1 );
System.out.println( "dx2 = " + dx2 );
System.out.println( "dy2 = " + dy2 );
System.out.println( "sx1 = " + sx1 );
System.out.println( "sy1 = " + sy1 );
System.out.println( "sx2 = " + sx2 );
System.out.println( "sy2 = " + sy2 );
System.out.println( "bgcolor = " + bgcolor );
System.out.println( "observer = " + observer );
return g2D.drawImage( img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bgcolor, observer );
}
public boolean drawImage(Image img, int x, int y,
Color bgcolor,
ImageObserver observer)
{
System.out.println( "drawImage(Image,int,int,Color,ImageObserver):" );
System.out.println( "img = " + img );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "bgcolor = " + bgcolor );
System.out.println( "observer = " + observer );
return g2D.drawImage( img, x, y, bgcolor, observer );
}
public boolean drawImage(Image img, int x, int y,
ImageObserver observer)
{
System.out.println( "drawImage(Image,int,int,observer):" );
System.out.println( "img = " + img );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "observer = " + observer );
return g2D.drawImage( img, x, y, observer );
}
public boolean drawImage(Image img, int x, int y,
int width, int height,
Color bgcolor,
ImageObserver observer)
{
System.out.println( "drawImage(Image,int,int,int,int,Color,ImageObserver):" );
System.out.println( "img = " + img );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
System.out.println( "bgcolor = " + bgcolor );
System.out.println( "observer = " + observer );
return g2D.drawImage( img, x, y, width, height, bgcolor, observer );
}
public boolean drawImage(Image img, int x, int y,
int width, int height,
ImageObserver observer)
{
System.out.println( "drawImage(Image,int,int,width,height,observer):" );
System.out.println( "img = " + img );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
System.out.println( "observer = " + observer );
return g2D.drawImage( img, x, y, width, height, observer );
}
public void drawLine(int x1, int y1, int x2, int y2)
{
System.out.println( "drawLine(int,int,int,int):" );
System.out.println( "x1 = " + x1 );
System.out.println( "y1 = " + y1 );
System.out.println( "x2 = " + x2 );
System.out.println( "y2 = " + y2 );
g2D.drawLine( x1, y1, x2, y2 );
}
public void drawOval(int x, int y, int width, int height)
{
System.out.println( "drawOval(int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
g2D.drawOval( x, y, width, height );
}
public void drawPolygon(Polygon p) {
System.out.println( "drawPolygon(Polygon):" );
System.out.println( "p = " + p );
g2D.drawPolygon( p );
}
public void drawPolygon(int xPoints[], int yPoints[],
int nPoints)
{
System.out.println( "drawPolygon(int[],int[],int):" );
System.out.println( "xPoints = " + xPoints );
System.out.println( "yPoints = " + yPoints );
System.out.println( "nPoints = " + nPoints );
g2D.drawPolygon( xPoints, yPoints, nPoints );
}
public void drawPolyline(int xPoints[], int yPoints[],
int nPoints)
{
System.out.println( "drawPolyline(int[],int[],int):" );
System.out.println( "xPoints = " + xPoints );
System.out.println( "yPoints = " + yPoints );
System.out.println( "nPoints = " + nPoints );
g2D.drawPolyline( xPoints, yPoints, nPoints );
}
public void drawRect(int x, int y, int width, int height) {
System.out.println( "drawRect(int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
g2D.drawRect( x, y, width, height );
}
public void drawRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight)
{
System.out.println( "drawRoundRect(int,int,int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
System.out.println( "arcWidth = " + arcWidth );
System.out.println( "arcHeight = " + arcHeight );
g2D.drawRoundRect( x, y, width, height, arcWidth, arcHeight );
}
public void drawString(AttributedCharacterIterator iterator,
int x, int y)
{
System.out.println( "drawString(AttributedCharacterIterator,int,int):" );
System.out.println( "iterator = " + iterator );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
g2D.drawString( iterator, x, y );
}
public void drawString(String str, int x, int y)
{
System.out.println( "drawString(str,int,int):" );
System.out.println( "str = " + str );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
g2D.drawString( str, x, y );
}
public void fill3DRect(int x, int y, int width, int height,
boolean raised) {
System.out.println( "fill3DRect(int,int,int,int,boolean):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
System.out.println( "raised = " + raised );
g2D.fill3DRect( x, y, width, height, raised );
}
public void fillArc(int x, int y, int width, int height,
int startAngle, int arcAngle)
{
System.out.println( "fillArc(int,int,int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
System.out.println( "startAngle = " + startAngle );
System.out.println( "arcAngle = " + arcAngle );
g2D.fillArc( x, y, width, height, startAngle, arcAngle );
}
public void fillOval(int x, int y, int width, int height)
{
System.out.println( "fillOval(int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
g2D.fillOval( x, y, width, height );
}
public void fillPolygon(Polygon p) {
System.out.println( "fillPolygon(Polygon):" );
System.out.println( "p = " + p );
g2D.fillPolygon( p );
}
public void fillPolygon(int xPoints[], int yPoints[],
int nPoints)
{
System.out.println( "fillPolygon(int[],int[],int):" );
System.out.println( "xPoints = " + xPoints );
System.out.println( "yPoints = " + yPoints );
System.out.println( "nPoints = " + nPoints );
g2D.fillPolygon( xPoints, yPoints, nPoints );
}
public void fillRect(int x, int y, int width, int height)
{
System.out.println( "fillRect(int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
g2D.fillRect( x, y, width, height );
}
public void fillRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight)
{
System.out.println( "fillRoundRect(int,int,int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
g2D.fillRoundRect( x, y, width, height, arcWidth, arcHeight );
}
public void finalize() {
System.out.println( "finalize():" );
g2D.finalize();
}
public Shape getClip()
{
System.out.println( "getClip():" );
return g2D.getClip();
}
public Rectangle getClipBounds()
{
System.out.println( "getClipBounds():" );
return g2D.getClipBounds();
}
public Rectangle getClipBounds(Rectangle r) {
System.out.println( "getClipBounds(Rectangle):" );
System.out.println( "r = " + r );
return g2D.getClipBounds( r );
}
public Rectangle getClipRect() {
System.out.println( "getClipRect():" );
return g2D.getClipRect();
}
public Color getColor()
{
System.out.println( "getColor():" );
return g2D.getColor();
}
public Font getFont()
{
System.out.println( "getFont():" );
return g2D.getFont();
}
public FontMetrics getFontMetrics() {
System.out.println( "getFontMetrics():" );
return g2D.getFontMetrics();
}
public FontMetrics getFontMetrics(Font f)
{
System.out.println( "getFontMetrics():" );
return g2D.getFontMetrics( f );
}
public boolean hitClip(int x, int y, int width, int height) {
System.out.println( "hitClip(int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
return g2D.hitClip( x, y, width, height );
}
public void setClip(Shape clip)
{
System.out.println( "setClip(Shape):" );
System.out.println( "clip = " + clip );
g2D.setClip( clip );
}
public void setClip(int x, int y, int width, int height)
{
System.out.println( "setClip(int,int,int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
System.out.println( "width = " + width );
System.out.println( "height = " + height );
g2D.setClip( x, y, width, height );
}
public void setColor(Color c)
{
System.out.println( "setColor():" );
System.out.println( "c = " + c );
g2D.setColor( c );
}
public void setFont(Font font)
{
System.out.println( "setFont(Font):" );
System.out.println( "font = " + font );
g2D.setFont( font );
}
public void setPaintMode()
{
System.out.println( "setPaintMode():" );
g2D.setPaintMode();
}
public void setXORMode(Color c1)
{
System.out.println( "setXORMode(Color):" );
System.out.println( "c1 = " + c1 );
g2D.setXORMode( c1 );
}
public String toString() {
System.out.println( "toString():" );
return g2D.toString();
}
public void translate(int x, int y)
{
System.out.println( "translate(int,int):" );
System.out.println( "x = " + x );
System.out.println( "y = " + y );
g2D.translate( x, y );
}
}

View File

@ -0,0 +1,450 @@
package org.apache.poi.hssf.usermodel;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.hssf.util.HSSFColor;
import java.awt.*;
import java.awt.image.ImageObserver;
import java.text.AttributedCharacterIterator;
/**
* Translates Graphics calls into escher calls. The translation is lossy so
* many features are not supported and some just aren't implemented yet. If
* in doubt test the specific calls you wish to make. Graphics calls are
* always performed into an EscherGroup so one will need to be created.
* <p>
* <b>Important:</b>
* <blockquote>
* One important concept worth considering is that of font size. 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 a 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.
* <p>
* Because of this constraint we've had to calculate the
* verticalPointsPerPixel. This the amount the font should be scaled by when
* you issue commands such as drawString(). A good way to calculate this
* is to use the follow formula:
* <p>
* <pre>
* multipler = groupHeightInPoints / heightOfGroup
* </pre>
* <p>
* 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
* <code>HSSFClientAnchor.getAnchorHeightInPoints()</code>.
* </blockquote>
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class EscherGraphics
extends Graphics
{
private HSSFShapeGroup escherGroup;
private HSSFWorkbook workbook;
private float verticalPointsPerPixel = 1.0f;
private float verticalPixelsPerPoint;
private Color foreground;
private Color background = Color.white;
private Font font;
private static POILogger logger = POILogFactory.getLogger(EscherGraphics.class);
/**
* Construct an escher graphics object.
*
* @param escherGroup The escher group to write the graphics calls into.
* @param workbook The workbook we are using.
* @param forecolor The foreground color to use as default.
* @param verticalPointsPerPixel The font multiplier. (See class description for information on how this works.).
*/
public EscherGraphics(HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color forecolor, float verticalPointsPerPixel )
{
this.escherGroup = escherGroup;
this.workbook = workbook;
this.verticalPointsPerPixel = verticalPointsPerPixel;
this.verticalPixelsPerPoint = 1 / verticalPointsPerPixel;
this.font = new Font("Arial", 0, 10);
this.foreground = forecolor;
// background = backcolor;
}
/**
* Constructs an escher graphics object.
*
* @param escherGroup The escher group to write the graphics calls into.
* @param workbook The workbook we are using.
* @param foreground The foreground color to use as default.
* @param verticalPointsPerPixel The font multiplier. (See class description for information on how this works.).
* @param font The font to use.
*/
EscherGraphics( HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color foreground, Font font, float verticalPointsPerPixel )
{
this.escherGroup = escherGroup;
this.workbook = workbook;
this.foreground = foreground;
// this.background = background;
this.font = font;
this.verticalPointsPerPixel = verticalPointsPerPixel;
this.verticalPixelsPerPoint = 1 / verticalPointsPerPixel;
}
/**
* Constructs an escher graphics object.
*
* @param escherGroup The escher group to write the graphics calls into.
* @param workbook The workbook we are using.
* @param forecolor The default foreground color.
*/
// public EscherGraphics( HSSFShapeGroup escherGroup, HSSFWorkbook workbook, Color forecolor)
// {
// this(escherGroup, workbook, forecolor, 1.0f);
// }
public void clearRect(int x, int y, int width, int height)
{
Color color = foreground;
setColor(background);
fillRect(x,y,width,height);
setColor(color);
}
public void clipRect(int x, int y, int width, int height)
{
logger.log(POILogger.WARN,"clipRect not supported");
}
public void copyArea(int x, int y, int width, int height, int dx, int dy)
{
logger.log(POILogger.WARN,"copyArea not supported");
}
public Graphics create()
{
EscherGraphics g = new EscherGraphics(escherGroup, workbook,
foreground, font, verticalPointsPerPixel );
return g;
}
public void dispose()
{
}
public void drawArc(int x, int y, int width, int height,
int startAngle, int arcAngle)
{
logger.log(POILogger.WARN,"drawArc not supported");
}
public boolean drawImage(Image img,
int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
Color bgcolor,
ImageObserver observer)
{
logger.log(POILogger.WARN,"drawImage not supported");
return true;
}
public boolean drawImage(Image img,
int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
ImageObserver observer)
{
logger.log(POILogger.WARN,"drawImage not supported");
return true;
}
public boolean drawImage(Image image, int i, int j, int k, int l, Color color, ImageObserver imageobserver)
{
return drawImage(image, i, j, i + k, j + l, 0, 0, image.getWidth(imageobserver), image.getHeight(imageobserver), color, imageobserver);
}
public boolean drawImage(Image image, int i, int j, int k, int l, ImageObserver imageobserver)
{
return drawImage(image, i, j, i + k, j + l, 0, 0, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver);
}
public boolean drawImage(Image image, int i, int j, Color color, ImageObserver imageobserver)
{
return drawImage(image, i, j, image.getWidth(imageobserver), image.getHeight(imageobserver), color, imageobserver);
}
public boolean drawImage(Image image, int i, int j, ImageObserver imageobserver)
{
return drawImage(image, i, j, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver);
}
public void drawLine(int x1, int y1, int x2, int y2)
{
HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor(x1, y1, x2, y2) );
shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_LINE);
shape.setLineWidth(0);
shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
}
public void drawOval(int x, int y, int width, int height)
{
HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor(x,y,x+width,y+height) );
shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);
shape.setLineWidth(0);
shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
shape.setNoFill(true);
}
public void drawPolygon(int xPoints[], int yPoints[],
int nPoints)
{
int right = findBiggest(xPoints);
int bottom = findBiggest(yPoints);
int left = findSmallest(xPoints);
int top = findSmallest(yPoints);
HSSFPolygon shape = escherGroup.createPolygon(new HSSFChildAnchor(left,top,right,bottom) );
shape.setPolygonDrawArea(right - left, bottom - top);
shape.setPoints(addToAll(xPoints, -left), addToAll(yPoints, -top));
shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
shape.setLineWidth(0);
shape.setNoFill(true);
}
private int[] addToAll( int[] values, int amount )
{
int[] result = new int[values.length];
for ( int i = 0; i < values.length; i++ )
result[i] = values[i] + amount;
return result;
}
public void drawPolyline(int xPoints[], int yPoints[],
int nPoints)
{
logger.log(POILogger.WARN,"drawPolyline not supported");
}
public void drawRect(int x, int y, int width, int height)
{
logger.log(POILogger.WARN,"drawRect not supported");
}
public void drawRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight)
{
logger.log(POILogger.WARN,"drawRoundRect not supported");
}
public void drawString(String str, int x, int y)
{
if (str == null || str.equals(""))
return;
Font excelFont = font;
if ( font.getName().equals( "SansSerif" ) )
{
excelFont = new Font( "Arial", font.getStyle(), (int) ( font.getSize() / verticalPixelsPerPoint ) );
}
else
{
excelFont = new Font( font.getName(), font.getStyle(), (int) ( font.getSize() / verticalPixelsPerPoint ));
}
FontDetails d = StaticFontMetrics.getFontDetails( excelFont );
int width = (int) ( (d.getStringWidth( str ) * 2.5) + 12 );
int height = (int) ( ( font.getSize() * 2.0 * verticalPixelsPerPoint ) + 6 );
y -= ( font.getSize() * verticalPixelsPerPoint ); // we want to draw the shape from the top-left
HSSFTextbox textbox = escherGroup.createTextbox( new HSSFChildAnchor( x, y, x + width, y + height ) );
textbox.setNoFill( true );
textbox.setLineStyle( HSSFShape.LINESTYLE_NONE );
HSSFRichTextString s = new HSSFRichTextString( str );
HSSFFont hssfFont = matchFont( excelFont );
s.applyFont( hssfFont );
textbox.setString( s );
}
private HSSFFont matchFont( Font font )
{
HSSFColor hssfColor = workbook.getCustomPalette()
.findColor((byte)foreground.getRed(), (byte)foreground.getGreen(), (byte)foreground.getBlue());
if (hssfColor == null)
hssfColor = workbook.getCustomPalette().findSimilarColor((byte)foreground.getRed(), (byte)foreground.getGreen(), (byte)foreground.getBlue());
boolean bold = (font.getStyle() & Font.BOLD) != 0;
boolean italic = (font.getStyle() & Font.ITALIC) != 0;
HSSFFont hssfFont = workbook.findFont(bold ? HSSFFont.BOLDWEIGHT_BOLD : 0,
hssfColor.getIndex(),
(short)(font.getSize() * 20),
font.getName(),
italic,
false,
(short)0,
(byte)0);
if (hssfFont == null)
{
hssfFont = workbook.createFont();
hssfFont.setBoldweight(bold ? HSSFFont.BOLDWEIGHT_BOLD : 0);
hssfFont.setColor(hssfColor.getIndex());
hssfFont.setFontHeight((short)(font.getSize() * 20));
hssfFont.setFontName(font.getName());
hssfFont.setItalic(italic);
hssfFont.setStrikeout(false);
hssfFont.setTypeOffset((short) 0);
hssfFont.setUnderline((byte) 0);
}
return hssfFont;
}
public void drawString(AttributedCharacterIterator iterator,
int x, int y)
{
logger.log(POILogger.WARN,"drawString not supported");
}
public void fillArc(int x, int y, int width, int height,
int startAngle, int arcAngle)
{
logger.log(POILogger.WARN,"fillArc not supported");
}
public void fillOval(int x, int y, int width, int height)
{
HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor( x, y, x + width, y + height ) );
shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_OVAL);
shape.setLineStyle(HSSFShape.LINESTYLE_NONE);
shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
}
public void fillPolygon(int xPoints[], int yPoints[],
int nPoints)
{
int right = findBiggest(xPoints);
int bottom = findBiggest(yPoints);
int left = findSmallest(xPoints);
int top = findSmallest(yPoints);
HSSFPolygon shape = escherGroup.createPolygon(new HSSFChildAnchor(left,top,right,bottom) );
shape.setPolygonDrawArea(right - left, bottom - top);
shape.setPoints(addToAll(xPoints, -left), addToAll(yPoints, -top));
shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
}
private int findBiggest( int[] values )
{
int result = Integer.MIN_VALUE;
for ( int i = 0; i < values.length; i++ )
{
if (values[i] > result)
result = values[i];
}
return result;
}
private int findSmallest( int[] values )
{
int result = Integer.MAX_VALUE;
for ( int i = 0; i < values.length; i++ )
{
if (values[i] < result)
result = values[i];
}
return result;
}
public void fillRect(int x, int y, int width, int height)
{
HSSFSimpleShape shape = escherGroup.createShape(new HSSFChildAnchor( x, y, x + width, y + height ) );
shape.setShapeType(HSSFSimpleShape.OBJECT_TYPE_RECTANGLE);
shape.setLineStyle(HSSFShape.LINESTYLE_NONE);
shape.setFillColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
shape.setLineStyleColor(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
}
public void fillRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight)
{
logger.log(POILogger.WARN,"fillRoundRect not supported");
}
public Shape getClip()
{
return getClipBounds();
}
public Rectangle getClipBounds()
{
return null;
}
public Rectangle getClipRect()
{
return getClipBounds();
}
public Color getColor()
{
return foreground;
}
public Font getFont()
{
return font;
}
public FontMetrics getFontMetrics(Font f)
{
return Toolkit.getDefaultToolkit().getFontMetrics(f);
}
public void setClip(int x, int y, int width, int height)
{
setClip(((Shape) (new Rectangle(x,y,width,height))));
}
public void setClip(Shape shape)
{
// ignore... not implemented
}
public void setColor(Color color)
{
foreground = color;
}
public void setFont(Font f)
{
font = f;
}
public void setPaintMode()
{
logger.log(POILogger.WARN,"setPaintMode not supported");
}
public void setXORMode(Color color)
{
logger.log(POILogger.WARN,"setXORMode not supported");
}
public void translate(int x, int y)
{
logger.log(POILogger.WARN,"translate not supported");
}
public Color getBackground()
{
return background;
}
public void setBackground( Color background )
{
this.background = background;
}
}

View File

@ -0,0 +1,567 @@
package org.apache.poi.hssf.usermodel;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;
import java.awt.image.BufferedImageOp;
import java.awt.image.ImageObserver;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.RenderableImage;
import java.text.AttributedCharacterIterator;
import java.util.Map;
/**
* Translates Graphics2d calls into escher calls. The translation is lossy so
* many features are not supported and some just aren't implemented yet. If
* in doubt test the specific calls you wish to make. Graphics calls are
* always drawn into an EscherGroup so one will need to be created.
* <p>
* <b>Important:</b>
* <blockquote>
* One important concept worth considering is that of font size. 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 a 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.
* <p>
* Because of this constraint you have to calculate the verticalPointsPerPixel.
* This the amount the font should be scaled by when
* you issue commands such as drawString(). A good way to calculate this
* is to use the follow formula:
* <p>
* <pre>
* multipler = groupHeightInPoints / heightOfGroup
* </pre>
* <p>
* 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
* <code>HSSFClientAnchor.getAnchorHeightInPoints()</code>.
* </blockquote>
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class EscherGraphics2d extends Graphics2D
{
private EscherGraphics escherGraphics;
private BufferedImage img;
private AffineTransform trans;
private Stroke stroke;
private Paint paint;
private Shape deviceclip;
private POILogger logger = POILogFactory.getLogger(getClass());
/**
* Constructs one escher graphics object from an escher graphics object.
*
* @param escherGraphics the original EscherGraphics2d object to copy
*/
public EscherGraphics2d(EscherGraphics escherGraphics)
{
this.escherGraphics = escherGraphics;
setImg( new BufferedImage(1, 1, 2) );
setColor(Color.black);
}
public void addRenderingHints(Map map)
{
getG2D().addRenderingHints(map);
}
public void clearRect(int i, int j, int k, int l)
{
Paint paint1 = getPaint();
setColor(getBackground());
fillRect(i, j, k, l);
setPaint(paint1);
}
public void clip(Shape shape)
{
if(getDeviceclip() != null)
{
Area area = new Area(getClip());
if(shape != null)
area.intersect(new Area(shape));
shape = area;
}
setClip(shape);
}
public void clipRect(int x, int y, int width, int height)
{
clip(new Rectangle(x,y,width,height));
}
public void copyArea(int x, int y, int width, int height,
int dx, int dy)
{
getG2D().copyArea(x,y,width,height,dx,dy);
}
public Graphics create()
{
EscherGraphics2d g2d = new EscherGraphics2d(escherGraphics);
return g2d;
}
public void dispose()
{
getEscherGraphics().dispose();
getG2D().dispose();
getImg().flush();
}
public void draw(Shape shape)
{
logger.log(POILogger.WARN,"copyArea not supported");
}
public void drawArc(int x, int y, int width, int height,
int startAngle, int arcAngle)
{
draw(new java.awt.geom.Arc2D.Float(x, y, width, height, startAngle, arcAngle, 0));
}
public void drawGlyphVector(GlyphVector g, float x, float y)
{
fill(g.getOutline(x, y));
}
public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
int sx2, int sy2, Color bgColor, ImageObserver imageobserver)
{
logger.log(POILogger.WARN,"drawImage() not supported");
return true;
}
public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
int sx2, int sy2, ImageObserver imageobserver)
{
logger.log(POILogger.WARN,"drawImage() not supported");
return drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null, imageobserver);
}
public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, Color bgColor, ImageObserver imageobserver)
{
logger.log(POILogger.WARN,"drawImage() not supported");
return true;
}
public boolean drawImage(Image img, int x, int y,
int width, int height,
ImageObserver observer)
{
return drawImage(img, x,y,width,height, null, observer);
}
public boolean drawImage(Image image, int x, int y, Color bgColor, ImageObserver imageobserver)
{
return drawImage(image, x, y, image.getWidth(imageobserver), image.getHeight(imageobserver), bgColor, imageobserver);
}
public boolean drawImage(Image image, int x, int y, ImageObserver imageobserver)
{
return drawImage(image, x, y, image.getWidth(imageobserver), image.getHeight(imageobserver), imageobserver);
}
public boolean drawImage(Image image, AffineTransform affinetransform, ImageObserver imageobserver)
{
AffineTransform affinetransform1 = (AffineTransform)getTrans().clone();
getTrans().concatenate(affinetransform);
drawImage(image, 0, 0, imageobserver);
setTrans( affinetransform1 );
return true;
}
public void drawImage(BufferedImage bufferedimage, BufferedImageOp op, int x, int y)
{
BufferedImage img = op.filter(bufferedimage, null);
drawImage(((Image) (img)), new AffineTransform(1.0F, 0.0F, 0.0F, 1.0F, x, y), null);
}
public void drawLine(int x1, int y1, int x2, int y2)
{
getEscherGraphics().drawLine(x1,y1,x2,y2);
// draw(new GeneralPath(new java.awt.geom.Line2D.Float(x1, y1, x2, y2)));
}
public void drawOval(int x, int y, int width, int height)
{
getEscherGraphics().drawOval(x,y,width,height);
// draw(new java.awt.geom.Ellipse2D.Float(x, y, width, height));
}
public void drawPolygon(int xPoints[], int yPoints[],
int nPoints)
{
getEscherGraphics().drawPolygon(xPoints, yPoints, nPoints);
}
public void drawPolyline(int xPoints[], int yPoints[], int nPoints)
{
if(nPoints > 0)
{
GeneralPath generalpath = new GeneralPath();
generalpath.moveTo(xPoints[0], yPoints[0]);
for(int j = 1; j < nPoints; j++)
generalpath.lineTo(xPoints[j], yPoints[j]);
draw(generalpath);
}
}
public void drawRect(int x, int y, int width, int height)
{
escherGraphics.drawRect(x,y,width,height);
}
public void drawRenderableImage(RenderableImage renderableimage, AffineTransform affinetransform)
{
drawRenderedImage(renderableimage.createDefaultRendering(), affinetransform);
}
public void drawRenderedImage(RenderedImage renderedimage, AffineTransform affinetransform)
{
BufferedImage bufferedimage = new BufferedImage(renderedimage.getColorModel(), renderedimage.getData().createCompatibleWritableRaster(), false, null);
bufferedimage.setData(renderedimage.getData());
drawImage(bufferedimage, affinetransform, null);
}
public void drawRoundRect(int i, int j, int k, int l, int i1, int j1)
{
draw(new java.awt.geom.RoundRectangle2D.Float(i, j, k, l, i1, j1));
}
public void drawString(String string, float x, float y)
{
getEscherGraphics().drawString(string, (int)x, (int)y);
}
public void drawString(String string, int x, int y)
{
getEscherGraphics().drawString(string, x, y);
}
public void drawString(AttributedCharacterIterator attributedcharacteriterator, float x, float y)
{
TextLayout textlayout = new TextLayout(attributedcharacteriterator, getFontRenderContext());
Paint paint1 = getPaint();
setColor(getColor());
fill(textlayout.getOutline(AffineTransform.getTranslateInstance(x, y)));
setPaint(paint1);
}
public void drawString(AttributedCharacterIterator attributedcharacteriterator, int x, int y)
{
drawString(attributedcharacteriterator, x, y);
}
public void fill(Shape shape)
{
logger.log(POILogger.WARN,"fill(Shape) not supported");
}
public void fillArc(int i, int j, int k, int l, int i1, int j1)
{
fill(new java.awt.geom.Arc2D.Float(i, j, k, l, i1, j1, 2));
}
public void fillOval(int x, int y, int width, int height)
{
escherGraphics.fillOval(x,y,width,height);
}
/**
* Fills a closed polygon defined by
* arrays of <i>x</i> and <i>y</i> coordinates.
* <p>
* This method draws the polygon defined by <code>nPoint</code> line
* segments, where the first <code>nPoint&nbsp;-&nbsp;1</code>
* line segments are line segments from
* <code>(xPoints[i&nbsp;-&nbsp;1],&nbsp;yPoints[i&nbsp;-&nbsp;1])</code>
* to <code>(xPoints[i],&nbsp;yPoints[i])</code>, for
* 1&nbsp;&le;&nbsp;<i>i</i>&nbsp;&le;&nbsp;<code>nPoints</code>.
* The figure is automatically closed by drawing a line connecting
* the final point to the first point, if those points are different.
* <p>
* The area inside the polygon is defined using an
* even-odd fill rule, also known as the alternating rule.
* @param xPoints a an array of <code>x</code> coordinates.
* @param yPoints a an array of <code>y</code> coordinates.
* @param nPoints a the total number of points.
* @see java.awt.Graphics#drawPolygon(int[], int[], int)
*/
public void fillPolygon(int xPoints[], int yPoints[], int nPoints)
{
escherGraphics.fillPolygon(xPoints, yPoints, nPoints);
}
public void fillRect(int x, int y, int width, int height)
{
getEscherGraphics().fillRect(x,y,width,height);
}
public void fillRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight)
{
fill(new java.awt.geom.RoundRectangle2D.Float(x, y, width, height, arcWidth, arcHeight));
}
public Color getBackground()
{
return getEscherGraphics().getBackground();
}
public Shape getClip()
{
try
{
return getTrans().createInverse().createTransformedShape(getDeviceclip());
}
catch(Exception _ex)
{
return null;
}
}
public Rectangle getClipBounds()
{
if(getDeviceclip() != null)
return getClip().getBounds();
else
return null;
}
public Color getColor()
{
return escherGraphics.getColor();
}
public Composite getComposite()
{
return getG2D().getComposite();
}
public GraphicsConfiguration getDeviceConfiguration()
{
return getG2D().getDeviceConfiguration();
}
public Font getFont()
{
return getEscherGraphics().getFont();
}
public FontMetrics getFontMetrics(Font font)
{
return getEscherGraphics().getFontMetrics(font);
}
public FontRenderContext getFontRenderContext()
{
getG2D().setTransform(getTrans());
return getG2D().getFontRenderContext();
}
public Paint getPaint()
{
return paint;
}
public Object getRenderingHint(java.awt.RenderingHints.Key key)
{
return getG2D().getRenderingHint(key);
}
public RenderingHints getRenderingHints()
{
return getG2D().getRenderingHints();
}
public Stroke getStroke()
{
return stroke;
}
public AffineTransform getTransform()
{
return (AffineTransform)getTrans().clone();
}
public boolean hit(Rectangle rectangle, Shape shape, boolean flag)
{
getG2D().setTransform(getTrans());
getG2D().setStroke(getStroke());
getG2D().setClip(getClip());
return getG2D().hit(rectangle, shape, flag);
}
public void rotate(double d)
{
getTrans().rotate(d);
}
public void rotate(double d, double d1, double d2)
{
getTrans().rotate(d, d1, d2);
}
public void scale(double d, double d1)
{
getTrans().scale(d, d1);
}
public void setBackground(Color c)
{
getEscherGraphics().setBackground(c);
}
public void setClip(int i, int j, int k, int l)
{
setClip(((Shape) (new Rectangle(i, j, k, l))));
}
public void setClip(Shape shape)
{
setDeviceclip( getTrans().createTransformedShape(shape) );
}
public void setColor(Color c)
{
escherGraphics.setColor(c);
}
public void setComposite(Composite composite)
{
getG2D().setComposite(composite);
}
public void setFont(Font font)
{
getEscherGraphics().setFont(font);
}
public void setPaint(Paint paint1)
{
if(paint1 != null)
{
paint = paint1;
if(paint1 instanceof Color)
setColor( (Color)paint1 );
}
}
public void setPaintMode()
{
getEscherGraphics().setPaintMode();
}
public void setRenderingHint(java.awt.RenderingHints.Key key, Object obj)
{
getG2D().setRenderingHint(key, obj);
}
public void setRenderingHints(Map map)
{
getG2D().setRenderingHints(map);
}
public void setStroke(Stroke s)
{
stroke = s;
}
public void setTransform(AffineTransform affinetransform)
{
setTrans( (AffineTransform)affinetransform.clone() );
}
public void setXORMode(Color color1)
{
getEscherGraphics().setXORMode(color1);
}
public void shear(double d, double d1)
{
getTrans().shear(d, d1);
}
public void transform(AffineTransform affinetransform)
{
getTrans().concatenate(affinetransform);
}
// Image transformImage(Image image, Rectangle rectangle, Rectangle rectangle1, ImageObserver imageobserver, Color color1)
// {
// logger.log(POILogger.WARN,"transformImage() not supported");
// return null;
// }
//
// Image transformImage(Image image, int ai[], Rectangle rectangle, ImageObserver imageobserver, Color color1)
// {
// logger.log(POILogger.WARN,"transformImage() not supported");
// return null;
// }
public void translate(double d, double d1)
{
getTrans().translate(d, d1);
}
public void translate(int i, int j)
{
getTrans().translate(i, j);
}
private EscherGraphics getEscherGraphics()
{
return escherGraphics;
}
private BufferedImage getImg()
{
return img;
}
private void setImg( BufferedImage img )
{
this.img = img;
}
private Graphics2D getG2D()
{
return (Graphics2D) img.getGraphics();
}
private AffineTransform getTrans()
{
return trans;
}
private void setTrans( AffineTransform trans )
{
this.trans = trans;
}
private Shape getDeviceclip()
{
return deviceclip;
}
private void setDeviceclip( Shape deviceclip )
{
this.deviceclip = deviceclip;
}
}

View File

@ -0,0 +1,143 @@
package org.apache.poi.hssf.usermodel;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
/**
* Stores width and height details about a font.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class FontDetails
{
private String fontName;
private int height;
private Map charWidths = new HashMap();
/**
* Construct the font details with the given name and height.
*
* @param fontName The font name.
* @param height The height of the font.
*/
public FontDetails( String fontName, int height )
{
this.fontName = fontName;
this.height = height;
}
public String getFontName()
{
return fontName;
}
public int getHeight()
{
return height;
}
public void addChar( char c, int width )
{
charWidths.put(new Character(c), new Integer(width));
}
/**
* Retrieves the width of the specified character. If the metrics for
* a particular character are not available it defaults to returning the
* width for the 'W' character.
*/
public int getCharWidth( char c )
{
Integer widthInteger = (Integer)(charWidths.get(new Character(c)));
if (widthInteger == null && c != 'W')
return getCharWidth('W');
else
return widthInteger.intValue();
}
public void addChars( char[] characters, int[] widths )
{
for ( int i = 0; i < characters.length; i++ )
{
charWidths.put( new Character(characters[i]), new Integer(widths[i]));
}
}
/**
* Create an instance of <code>FontDetails</code> by loading them from the
* provided property object.
* @param fontName the font name
* @param fontMetricsProps the property object holding the details of this
* particular font.
* @return a new FontDetails instance.
*/
public static FontDetails create( String fontName, Properties fontMetricsProps )
{
String heightStr = fontMetricsProps.getProperty( "font." + fontName + ".height");
String widthsStr = fontMetricsProps.getProperty( "font." + fontName + ".widths");
String charactersStr = fontMetricsProps.getProperty( "font." + fontName + ".characters");
int height = Integer.parseInt(heightStr);
FontDetails d = new FontDetails(fontName, height);
String[] charactersStrArray = split(charactersStr, ",", -1);
String[] widthsStrArray = split(widthsStr, ",", -1);
if (charactersStrArray.length != widthsStrArray.length)
throw new RuntimeException("Number of characters does not number of widths for font " + fontName);
for ( int i = 0; i < widthsStrArray.length; i++ )
{
if (charactersStrArray[i].length() != 0)
d.addChar(charactersStrArray[i].charAt(0), Integer.parseInt(widthsStrArray[i]));
}
return d;
}
/**
* Gets the width of all characters in a string.
*
* @param str The string to measure.
* @return The width of the string for a 10 point font.
*/
public int getStringWidth(String str)
{
int width = 0;
for (int i = 0; i < str.length(); i++)
{
width += getCharWidth(str.charAt(i));
}
return width;
}
/**
* Split the given string into an array of strings using the given
* delimiter.
*/
private static String[] split(String text, String separator, int max)
{
StringTokenizer tok = new StringTokenizer(text, separator);
int listSize = tok.countTokens();
if(max != -1 && listSize > max)
listSize = max;
String list[] = new String[listSize];
for(int i = 0; tok.hasMoreTokens(); i++)
{
if(max != -1 && i == listSize - 1)
{
StringBuffer buf = new StringBuffer((text.length() * (listSize - i)) / listSize);
while(tok.hasMoreTokens())
{
buf.append(tok.nextToken());
if(tok.hasMoreTokens())
buf.append(separator);
}
list[i] = buf.toString().trim();
break;
}
list[i] = tok.nextToken().trim();
}
return list;
}
}

View File

@ -0,0 +1,40 @@
package org.apache.poi.hssf.usermodel;
/**
* An anchor is what specifics the position of a shape within a client object
* or within another containing shape.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public abstract class HSSFAnchor
{
int dx1;
int dy1;
int dx2;
int dy2;
public HSSFAnchor()
{
}
public HSSFAnchor( int dx1, int dy1, int dx2, int dy2 )
{
this.dx1 = dx1;
this.dy1 = dy1;
this.dx2 = dx2;
this.dy2 = dy2;
}
public int getDx1(){ return dx1; }
public void setDx1( int dx1 ){ this.dx1 = dx1; }
public int getDy1(){ return dy1; }
public void setDy1( int dy1 ){ this.dy1 = dy1; }
public int getDy2(){ return dy2; }
public void setDy2( int dy2 ){ this.dy2 = dy2; }
public int getDx2(){ return dx2; }
public void setDx2( int dx2 ){ this.dx2 = dx2; }
public abstract boolean isHorizontallyFlipped();
public abstract boolean isVerticallyFlipped();
}

View File

@ -0,0 +1,37 @@
package org.apache.poi.hssf.usermodel;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.ddf.EscherClientAnchorRecord;
import org.apache.poi.ddf.EscherChildAnchorRecord;
public class HSSFChildAnchor
extends HSSFAnchor
{
public HSSFChildAnchor()
{
}
public HSSFChildAnchor( int dx1, int dy1, int dx2, int dy2 )
{
super( dx1, dy1, dx2, dy2 );
}
public void setAnchor(int dx1, int dy1, int dx2, int dy2)
{
this.dx1 = dx1;
this.dy1 = dy1;
this.dx2 = dx2;
this.dy2 = dy2;
}
public boolean isHorizontallyFlipped()
{
return dx1 > dx2;
}
public boolean isVerticallyFlipped()
{
return dy1 > dy2;
}
}

View File

@ -0,0 +1,207 @@
package org.apache.poi.hssf.usermodel;
import org.apache.poi.ddf.EscherClientAnchorRecord;
import org.apache.poi.ddf.EscherRecord;
/**
* A client anchor is attached to an excel worksheet. It anchors against a
* top-left and buttom-right cell.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class HSSFClientAnchor
extends HSSFAnchor
{
short col1;
int row1;
short col2;
int row2;
/**
* Creates a new client anchor and defaults all the anchor positions to 0.
*/
public HSSFClientAnchor()
{
}
/**
* Creates a new client anchor and sets the top-left and bottom-right
* coordinates of the anchor.
*
* @param dx1 the x coordinate within the first cell.
* @param dy1 the y coordinate within the first cell.
* @param dx2 the x coordinate within the second cell.
* @param dy2 the y coordinate within the second cell.
* @param col1 the column (0 based) of the first cell.
* @param row1 the row (0 based) of the first cell.
* @param col2 the column (0 based) of the second cell.
* @param row2 the row (0 based) of the second cell.
*/
public HSSFClientAnchor( int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2 )
{
super( dx1, dy1, dx2, dy2 );
checkRange(dx1, 0, 1023, "dx1");
checkRange(dx2, 0, 1023, "dx2");
checkRange(dy1, 0, 255, "dy1");
checkRange(dy2, 0, 255, "dy2");
checkRange(col1, 0, 255, "col1");
checkRange(col2, 0, 255, "col2");
checkRange(row1, 0, 255 * 256, "row1");
checkRange(row2, 0, 255 * 256, "row2");
this.col1 = col1;
this.row1 = row1;
this.col2 = col2;
this.row2 = row2;
}
/**
* Calculates the height of a client anchor in points.
*
* @param sheet the sheet the anchor will be attached to
* @return the shape height.
*/
public float getAnchorHeightInPoints(HSSFSheet sheet )
{
int y1 = Math.min( getDy1(), getDy2() );
int y2 = Math.max( getDy1(), getDy2() );
int row1 = Math.min( getRow1(), getRow2() );
int row2 = Math.max( getRow1(), getRow2() );
float points = 0;
if (row1 == row2)
{
points = ((y2 - y1) / 256.0f) * getRowHeightInPoints(sheet, row2);
}
else
{
points += ((256.0f - y1) / 256.0f) * getRowHeightInPoints(sheet, row1);
for (int i = row1 + 1; i < row2; i++)
{
points += getRowHeightInPoints(sheet, i);
}
points += (y2 / 256.0f) * getRowHeightInPoints(sheet, row2);
}
return points;
}
private float getRowHeightInPoints(HSSFSheet sheet, int rowNum)
{
HSSFRow row = sheet.getRow(rowNum);
if (row == null)
return sheet.getDefaultRowHeightInPoints();
else
return row.getHeightInPoints();
}
public short getCol1()
{
return col1;
}
public void setCol1( short col1 )
{
checkRange(col1, 0, 255, "col1");
this.col1 = col1;
}
public short getCol2()
{
return col2;
}
public void setCol2( short col2 )
{
checkRange(col2, 0, 255, "col2");
this.col2 = col2;
}
public int getRow1()
{
return row1;
}
public void setRow1( int row1 )
{
checkRange(row1, 0, 256 * 256, "row1");
this.row1 = row1;
}
public int getRow2()
{
return row2;
}
public void setRow2( int row2 )
{
checkRange(row2, 0, 256 * 256, "row2");
this.row2 = row2;
}
/**
* Dets the top-left and bottom-right
* coordinates of the anchor.
*
* @param x1 the x coordinate within the first cell.
* @param y1 the y coordinate within the first cell.
* @param x2 the x coordinate within the second cell.
* @param y2 the y coordinate within the second cell.
* @param col1 the column (0 based) of the first cell.
* @param row1 the row (0 based) of the first cell.
* @param col2 the column (0 based) of the second cell.
* @param row2 the row (0 based) of the second cell.
*/
public void setAnchor( short col1, int row1, int x1, int y1, short col2, int row2, int x2, int y2 )
{
checkRange(dx1, 0, 1023, "dx1");
checkRange(dx2, 0, 1023, "dx2");
checkRange(dy1, 0, 255, "dy1");
checkRange(dy2, 0, 255, "dy2");
checkRange(col1, 0, 255, "col1");
checkRange(col2, 0, 255, "col2");
checkRange(row1, 0, 255 * 256, "row1");
checkRange(row2, 0, 255 * 256, "row2");
this.col1 = col1;
this.row1 = row1;
this.dx1 = x1;
this.dy1 = y1;
this.col2 = col2;
this.row2 = row2;
this.dx2 = x2;
this.dy2 = y2;
}
/**
* @return true if the anchor goes from right to left.
*/
public boolean isHorizontallyFlipped()
{
if (col1 == col2)
return dx1 > dx2;
else
return col1 > col2;
}
/**
* @return true if the anchor goes from bottom to top.
*/
public boolean isVerticallyFlipped()
{
if (row1 == row2)
return dy1 > dy2;
else
return row1 > row2;
}
private void checkRange( int value, int minRange, int maxRange, String varName )
{
if (value < minRange || value > maxRange)
throw new IllegalArgumentException(varName + " must be between " + minRange + " and " + maxRange);
}
}

View File

@ -165,7 +165,7 @@ public class HSSFFont
/**
* set the name for the font (i.e. Arial)
* @param String representing the name of the font to use
* @param name String representing the name of the font to use
* @see #FONT_ARIAL
*/
@ -359,7 +359,7 @@ public class HSSFFont
/**
* set type of text underlining to use
* @param underlining type
* @param underline type
* @see #U_NONE
* @see #U_SINGLE
* @see #U_DOUBLE
@ -386,4 +386,13 @@ public class HSSFFont
{
return font.getUnderline();
}
public String toString()
{
return "org.apache.poi.hssf.usermodel.HSSFFont{" +
font +
"}";
}
}

View File

@ -110,7 +110,35 @@ public class HSSFPalette
}
return null;
}
/**
* Finds the closest matching color in the custom palette. The
* method for finding the distance between the colors is fairly
* primative.
*
* @param red The red component of the color to match.
* @param green The green component of the color to match.
* @param blue The blue component of the color to match.
* @return The closest color or null if there are no custom
* colors currently defined.
*/
public HSSFColor findSimilarColor(byte red, byte green, byte blue)
{
HSSFColor result = null;
int minColorDistance = Integer.MAX_VALUE;
byte[] b = palette.getColor(PaletteRecord.FIRST_COLOR_INDEX);
for (short i = (short) PaletteRecord.FIRST_COLOR_INDEX; b != null;
b = palette.getColor(++i))
{
int colorDistance = red - b[0] + green - b[1] + blue - b[2];
if (colorDistance < minColorDistance)
{
result = getColor(i);
}
}
return result;
}
/**
* Sets the color at the given offset
*
@ -123,7 +151,32 @@ public class HSSFPalette
{
palette.setColor(index, red, green, blue);
}
/**
* Adds a new color into an empty color slot.
* @param red The red component
* @param green The green component
* @param blue The blue component
*
* @return The new custom color.
*
* @throws RuntimeException if there are more more free color indexes.
*/
public HSSFColor addColor( byte red, byte green, byte blue )
{
byte[] b = palette.getColor(PaletteRecord.FIRST_COLOR_INDEX);
short i;
for (i = (short) PaletteRecord.FIRST_COLOR_INDEX; i < PaletteRecord.STANDARD_PALETTE_SIZE + PaletteRecord.FIRST_COLOR_INDEX; b = palette.getColor(++i))
{
if (b == null)
{
setColorAtIndex( i, red, green, blue );
return getColor(i);
}
}
throw new RuntimeException("Could not find free color index");
}
private static class CustomColor extends HSSFColor
{
private short byteOffset;

View File

@ -0,0 +1,159 @@
package org.apache.poi.hssf.usermodel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* The patriarch is the toplevel container for shapes in a sheet. It does
* little other than act as a container for other shapes and groups.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class HSSFPatriarch
implements HSSFShapeContainer
{
List shapes = new ArrayList();
HSSFSheet sheet;
int x1 = 0;
int y1 = 0 ;
int x2 = 1023;
int y2 = 255;
/**
* Creates the patriarch.
*
* @param sheet the sheet this patriarch is stored in.
*/
HSSFPatriarch(HSSFSheet sheet)
{
this.sheet = sheet;
}
/**
* Creates a new group record stored under this patriarch.
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created group.
*/
public HSSFShapeGroup createGroup(HSSFClientAnchor anchor)
{
HSSFShapeGroup group = new HSSFShapeGroup(null, anchor);
group.anchor = anchor;
shapes.add(group);
return group;
}
/**
* Creates a simple shape. This includes such shapes as lines, rectangles,
* and ovals.
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created shape.
*/
public HSSFSimpleShape createSimpleShape(HSSFClientAnchor anchor)
{
HSSFSimpleShape shape = new HSSFSimpleShape(null, anchor);
shape.anchor = anchor;
shapes.add(shape);
return shape;
}
/**
* Creates a polygon
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created shape.
*/
public HSSFPolygon createPolygon(HSSFClientAnchor anchor)
{
HSSFPolygon shape = new HSSFPolygon(null, anchor);
shape.anchor = anchor;
shapes.add(shape);
return shape;
}
/**
* Constructs a textbox under the patriarch.
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created textbox.
*/
public HSSFTextbox createTextbox(HSSFClientAnchor anchor)
{
HSSFTextbox shape = new HSSFTextbox(null, anchor);
shape.anchor = anchor;
shapes.add(shape);
return shape;
}
/**
* Returns a list of all shapes contained by the patriarch.
*/
public List getChildren()
{
return shapes;
}
/**
* Total count of all children and their children's children.
*/
public int countOfAllChildren()
{
int count = shapes.size();
for ( Iterator iterator = shapes.iterator(); iterator.hasNext(); )
{
HSSFShape shape = (HSSFShape) iterator.next();
count += shape.countOfAllChildren();
}
return count;
}
/**
* Sets the coordinate space of this group. All children are contrained
* to these coordinates.
*/
public void setCoordinates( int x1, int y1, int x2, int y2 )
{
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
/**
* The top left x coordinate of this group.
*/
public int getX1()
{
return x1;
}
/**
* The top left y coordinate of this group.
*/
public int getY1()
{
return y1;
}
/**
* The bottom right x coordinate of this group.
*/
public int getX2()
{
return x2;
}
/**
* The bottom right y coordinate of this group.
*/
public int getY2()
{
return y2;
}
}

View File

@ -0,0 +1,66 @@
package org.apache.poi.hssf.usermodel;
/**
* @author Glen Stampoultzis (glens at superlinksoftware.com)
*/
public class HSSFPolygon
extends HSSFShape
{
int[] xPoints;
int[] yPoints;
int drawAreaWidth = 100;
int drawAreaHeight = 100;
HSSFPolygon( HSSFShape parent, HSSFAnchor anchor )
{
super( parent, anchor );
}
public int[] getXPoints()
{
return xPoints;
}
public int[] getYPoints()
{
return yPoints;
}
public void setPoints(int[] xPoints, int[] yPoints)
{
this.xPoints = cloneArray(xPoints);
this.yPoints = cloneArray(yPoints);
}
private int[] cloneArray( int[] a )
{
int[] result = new int[a.length];
for ( int i = 0; i < a.length; i++ )
result[i] = a[i];
return result;
}
/**
* Defines the width and height of the points in the polygon
* @param width
* @param height
*/
public void setPolygonDrawArea( int width, int height )
{
this.drawAreaWidth = width;
this.drawAreaHeight = height;
}
public int getDrawAreaWidth()
{
return drawAreaWidth;
}
public int getDrawAreaHeight()
{
return drawAreaHeight;
}
}

View File

@ -0,0 +1,179 @@
package org.apache.poi.hssf.usermodel;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
/**
* Rich text unicode string. These strings can have fonts applied to
* arbitary parts of the string.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class HSSFRichTextString
implements Comparable
{
/** Place holder for indicating that NO_FONT has been applied here */
public static final short NO_FONT = -1;
String string;
SortedMap formattingRuns = new TreeMap();
public HSSFRichTextString()
{
this("");
}
public HSSFRichTextString( String string )
{
this.string = string;
this.formattingRuns.put(new Integer(0), new Short(NO_FONT));
}
/**
* Applies a font to the specified characters of a string.
*
* @param startIndex The start index to apply the font to (inclusive)
* @param endIndex The end index to apply the font to (exclusive)
* @param fontIndex The font to use.
*/
public void applyFont(int startIndex, int endIndex, short fontIndex)
{
if (startIndex > endIndex)
throw new IllegalArgumentException("Start index must be less than end index.");
if (startIndex < 0 || endIndex > length())
throw new IllegalArgumentException("Start and end index not in range.");
if (startIndex == endIndex)
return;
Integer from = new Integer(startIndex);
Integer to = new Integer(endIndex);
short fontAtIndex = NO_FONT;
if (endIndex != length())
fontAtIndex = getFontAtIndex(endIndex);
formattingRuns.subMap(from, to).clear();
formattingRuns.put(from, new Short(fontIndex));
if (endIndex != length())
{
if (fontIndex != fontAtIndex)
formattingRuns.put(to, new Short(fontAtIndex));
}
}
/**
* Applies a font to the specified characters of a string.
*
* @param startIndex The start index to apply the font to (inclusive)
* @param endIndex The end index to apply to font to (exclusive)
* @param font The index of the font to use.
*/
public void applyFont(int startIndex, int endIndex, HSSFFont font)
{
applyFont(startIndex, endIndex, font.getIndex());
}
/**
* Sets the font of the entire string.
* @param font The font to use.
*/
public void applyFont(HSSFFont font)
{
applyFont(0, string.length(), font);
}
/**
* Returns the plain string representation.
*/
public String getString()
{
return string;
}
/**
* @return the number of characters in the font.
*/
public int length()
{
return string.length();
}
/**
* Returns the font in use at a particular index.
*
* @param index The index.
* @return The font that's currently being applied at that
* index or null if no font is being applied or the
* index is out of range.
*/
public short getFontAtIndex( int index )
{
if (index < 0 || index >= string.length())
throw new ArrayIndexOutOfBoundsException("Font index " + index + " out of bounds of string");
Integer key = new Integer(index + 1);
SortedMap head = formattingRuns.headMap(key);
if (head.isEmpty())
throw new IllegalStateException("Should not reach here. No font found.");
else
return ((Short) head.get(head.lastKey())).shortValue();
}
/**
* @return The number of formatting runs used. There will always be at
* least one of font NO_FONT.
*
* @see #NO_FONT
*/
public int numFormattingRuns()
{
return formattingRuns.size();
}
/**
* The index within the string to which the specified formatting run applies.
* @param index the index of the formatting run
* @return the index within the string.
*/
public int getIndexOfFormattingRun(int index)
{
Map.Entry[] runs = (Map.Entry[]) formattingRuns.entrySet().toArray(new Map.Entry[formattingRuns.size()] );
return ((Integer)runs[index].getKey()).intValue();
}
/**
* Gets the font used in a particular formatting run.
*
* @param index the index of the formatting run
* @return the font number used.
*/
public short getFontOfFormattingRun(int index)
{
Map.Entry[] runs = (Map.Entry[]) formattingRuns.entrySet().toArray(new Map.Entry[formattingRuns.size()] );
return ((Short)(runs[index].getValue())).shortValue();
}
/**
* Compares one rich text string to another.
*/
public int compareTo( Object o )
{
return 0; // todo
}
/**
* @return the plain text representation of this string.
*/
public String toString()
{
return string;
}
/**
* Applies the specified font to the entire string.
*
* @param fontIndex the font to apply.
*/
public void applyFont( short fontIndex )
{
applyFont(0, string.length(), fontIndex);
}
}

View File

@ -0,0 +1,195 @@
package org.apache.poi.hssf.usermodel;
/**
* An abstract shape.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public abstract class HSSFShape
{
public static final int LINEWIDTH_ONE_PT = 12700;
public static final int LINEWIDTH_DEFAULT = 9525;
public static final int LINESTYLE_SOLID = 0; // Solid (continuous) pen
public static final int LINESTYLE_DASHSYS = 1; // PS_DASH system dash style
public static final int LINESTYLE_DOTSYS = 2; // PS_DOT system dash style
public static final int LINESTYLE_DASHDOTSYS = 3; // PS_DASHDOT system dash style
public static final int LINESTYLE_DASHDOTDOTSYS = 4; // PS_DASHDOTDOT system dash style
public static final int LINESTYLE_DOTGEL = 5; // square dot style
public static final int LINESTYLE_DASHGEL = 6; // dash style
public static final int LINESTYLE_LONGDASHGEL = 7; // long dash style
public static final int LINESTYLE_DASHDOTGEL = 8; // dash short dash
public static final int LINESTYLE_LONGDASHDOTGEL = 9; // long dash short dash
public static final int LINESTYLE_LONGDASHDOTDOTGEL = 10; // long dash short dash short dash
public static final int LINESTYLE_NONE = -1;
HSSFShape parent;
HSSFAnchor anchor;
int lineStyleColor = 0x08000040;
int fillColor = 0x08000009;
int lineWidth = LINEWIDTH_DEFAULT; // 12700 = 1pt
int lineStyle = LINESTYLE_SOLID;
boolean noFill = false;
/**
* Create a new shape with the specified parent and anchor.
*/
HSSFShape( HSSFShape parent, HSSFAnchor anchor )
{
this.parent = parent;
this.anchor = anchor;
}
/**
* Gets the parent shape.
*/
public HSSFShape getParent()
{
return parent;
}
/**
* @return the anchor that is used by this shape.
*/
public HSSFAnchor getAnchor()
{
return anchor;
}
/**
* Sets a particular anchor. A top-level shape must have an anchor of
* HSSFClientAnchor. A child anchor must have an anchor of HSSFChildAnchor
*
* @param anchor the anchor to use.
* @throws IllegalArgumentException when the wrong anchor is used for
* this particular shape.
*
* @see HSSFChildAnchor
* @see HSSFClientAnchor
*/
public void setAnchor( HSSFAnchor anchor )
{
if ( parent == null )
{
if ( anchor instanceof HSSFChildAnchor )
throw new IllegalArgumentException( "Must use client anchors for shapes directly attached to sheet." );
}
else
{
if ( anchor instanceof HSSFClientAnchor )
throw new IllegalArgumentException( "Must use child anchors for shapes attached to groups." );
}
this.anchor = anchor;
}
/**
* The color applied to the lines of this shape.
*/
public int getLineStyleColor()
{
return lineStyleColor;
}
/**
* The color applied to the lines of this shape.
*/
public void setLineStyleColor( int lineStyleColor )
{
this.lineStyleColor = lineStyleColor;
}
/**
* The color applied to the lines of this shape.
*/
public void setLineStyleColor( int red, int green, int blue )
{
this.lineStyleColor = ((blue) << 16) | ((green) << 8) | red;
}
/**
* The color used to fill this shape.
*/
public int getFillColor()
{
return fillColor;
}
/**
* The color used to fill this shape.
*/
public void setFillColor( int fillColor )
{
this.fillColor = fillColor;
}
/**
* The color used to fill this shape.
*/
public void setFillColor( int red, int green, int blue )
{
this.fillColor = ((blue) << 16) | ((green) << 8) | red;
}
/**
* @return returns with width of the line in EMUs. 12700 = 1 pt.
*/
public int getLineWidth()
{
return lineWidth;
}
/**
* Sets the width of the line. 12700 = 1 pt.
*
* @param lineWidth width in EMU's. 12700EMU's = 1 pt
*
* @see HSSFShape#LINEWIDTH_ONE_PT
*/
public void setLineWidth( int lineWidth )
{
this.lineWidth = lineWidth;
}
/**
* @return One of the constants in LINESTYLE_*
*/
public int getLineStyle()
{
return lineStyle;
}
/**
* Sets the line style.
*
* @param lineStyle One of the constants in LINESTYLE_*
*/
public void setLineStyle( int lineStyle )
{
this.lineStyle = lineStyle;
}
/**
* @return true if this shape is not filled with a color.
*/
public boolean isNoFill()
{
return noFill;
}
/**
* Sets whether this shape is filled or transparent.
*/
public void setNoFill( boolean noFill )
{
this.noFill = noFill;
}
/**
* Count of all children and their childrens children.
*/
public int countOfAllChildren()
{
return 1;
}
}

View File

@ -0,0 +1,17 @@
package org.apache.poi.hssf.usermodel;
import java.util.List;
/**
* An interface that indicates whether a class can contain children.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public interface HSSFShapeContainer
{
/**
* @return Any children contained by this shape.
*/
List getChildren();
}

View File

@ -0,0 +1,148 @@
package org.apache.poi.hssf.usermodel;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
/**
* A shape group may contain other shapes. It was no actual form on the
* sheet.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class HSSFShapeGroup
extends HSSFShape
implements HSSFShapeContainer
{
List shapes = new ArrayList();
int x1 = 0;
int y1 = 0 ;
int x2 = 1023;
int y2 = 255;
public HSSFShapeGroup( HSSFShape parent, HSSFAnchor anchor )
{
super( parent, anchor );
}
/**
* Create another group under this group.
* @param anchor the position of the new group.
* @return the group
*/
public HSSFShapeGroup createGroup(HSSFChildAnchor anchor)
{
HSSFShapeGroup group = new HSSFShapeGroup(this, anchor);
group.anchor = anchor;
shapes.add(group);
return group;
}
/**
* Create a new simple shape under this group.
* @param anchor the position of the shape.
* @return the shape
*/
public HSSFSimpleShape createShape(HSSFChildAnchor anchor)
{
HSSFSimpleShape shape = new HSSFSimpleShape(this, anchor);
shape.anchor = anchor;
shapes.add(shape);
return shape;
}
/**
* Create a new textbox under this group.
* @param anchor the position of the shape.
* @return the textbox
*/
public HSSFTextbox createTextbox(HSSFChildAnchor anchor)
{
HSSFTextbox shape = new HSSFTextbox(this, anchor);
shape.anchor = anchor;
shapes.add(shape);
return shape;
}
/**
* Creates a polygon
*
* @param anchor the client anchor describes how this group is attached
* to the sheet.
* @return the newly created shape.
*/
public HSSFPolygon createPolygon(HSSFChildAnchor anchor)
{
HSSFPolygon shape = new HSSFPolygon(this, anchor);
shape.anchor = anchor;
shapes.add(shape);
return shape;
}
/**
* Return all children contained by this shape.
*/
public List getChildren()
{
return shapes;
}
/**
* Sets the coordinate space of this group. All children are contrained
* to these coordinates.
*/
public void setCoordinates( int x1, int y1, int x2, int y2 )
{
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
/**
* The top left x coordinate of this group.
*/
public int getX1()
{
return x1;
}
/**
* The top left y coordinate of this group.
*/
public int getY1()
{
return y1;
}
/**
* The bottom right x coordinate of this group.
*/
public int getX2()
{
return x2;
}
/**
* The bottom right y coordinate of this group.
*/
public int getY2()
{
return y2;
}
/**
* Count of all children and their childrens children.
*/
public int countOfAllChildren()
{
int count = shapes.size();
for ( Iterator iterator = shapes.iterator(); iterator.hasNext(); )
{
HSSFShape shape = (HSSFShape) iterator.next();
count += shape.countOfAllChildren();
}
return count;
}
}

View File

@ -59,26 +59,20 @@
*/
package org.apache.poi.hssf.usermodel;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.util.Region;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.TreeMap;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.CellValueRecordInterface;
import org.apache.poi.hssf.record.HCenterRecord;
import org.apache.poi.hssf.record.PageBreakRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.RowRecord;
import org.apache.poi.hssf.record.SCLRecord;
import org.apache.poi.hssf.record.VCenterRecord;
import org.apache.poi.hssf.record.WSBoolRecord;
import org.apache.poi.hssf.record.WindowTwoRecord;
import org.apache.poi.hssf.util.Region;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
/**
* High level representation of a worksheet.
* @author Andrew C. Oliver (acoliver at apache dot org)
@ -874,13 +868,13 @@ public class HSSFSheet
{
getSheet().setMargin( margin, size );
}
/**
* Answer whether protection is enabled or disabled
* @return true => protection enabled; false => protection disabled
*/
public boolean getProtect() {
return getSheet().getProtect().getProtect();
return getSheet().getProtect().getProtect();
}
/**
@ -888,7 +882,7 @@ public class HSSFSheet
* @param protect true => protection enabled; false => protection disabled
*/
public void setProtect(boolean protect) {
getSheet().getProtect().setProtect(protect);
getSheet().getProtect().setProtect(protect);
}
/**
@ -926,34 +920,34 @@ public class HSSFSheet
//move merged regions completely if they fall within the new region boundaries when they are shifted
for (int i = 0; i < this.getNumMergedRegions(); i++) {
Region merged = this.getMergedRegionAt(i);
boolean inStart = (merged.getRowFrom() >= startRow || merged.getRowTo() >= startRow);
boolean inEnd = (merged.getRowTo() <= endRow || merged.getRowFrom() <= endRow);
//dont check if it's not within the shifted area
if (! (inStart && inEnd)) continue;
//only shift if the region outside the shifted rows is not merged too
//only shift if the region outside the shifted rows is not merged too
if (!merged.contains(startRow-1, (short)0) && !merged.contains(endRow+1, (short)0)){
merged.setRowFrom(merged.getRowFrom()+n);
merged.setRowFrom(merged.getRowFrom()+n);
merged.setRowTo(merged.getRowTo()+n);
//have to remove/add it back
shiftedRegions.add(merged);
this.removeMergedRegion(i);
i = i -1; // we have to back up now since we removed one
}
}
//readd so it doesn't get shifted again
Iterator iterator = shiftedRegions.iterator();
while (iterator.hasNext()) {
Region region = (Region)iterator.next();
this.addMergedRegion(region);
}
}
/**
@ -978,7 +972,7 @@ public class HSSFSheet
* Shifts rows between startRow and endRow n number of rows.
* If you use a negative number, it will shift rows up.
* Code ensures that rows don't wrap around
*
*
* <p>
* Additionally shifts merged regions that are completely defined in these
* rows (ie. merged 2 cells on a row to be shifted).
@ -1006,19 +1000,19 @@ public class HSSFSheet
inc = -1;
}
shiftMerged(startRow, endRow, n, true);
sheet.shiftRowBreaks(startRow, endRow, n);
shiftMerged(startRow, endRow, n, true);
sheet.shiftRowBreaks(startRow, endRow, n);
for ( int rowNum = s; rowNum >= startRow && rowNum <= endRow && rowNum >= 0 && rowNum < 65536; rowNum += inc )
{
HSSFRow row = getRow( rowNum );
HSSFRow row2Replace = getRow( rowNum + n );
HSSFRow row2Replace = getRow( rowNum + n );
if ( row2Replace == null )
row2Replace = createRow( rowNum + n );
HSSFCell cell;
// Removes the cells before over writting them.
@ -1033,10 +1027,10 @@ public class HSSFSheet
if (copyRowHeight) {
row2Replace.setHeight(row.getHeight());
}
if (resetOriginalRowHeight) {
row.setHeight((short)0xff);
}
}
}
for ( short col = row.getFirstCellNum(); col <= row.getLastCellNum(); col++ )
{
@ -1255,4 +1249,46 @@ public class HSSFSheet
if (column > 255) throw new IllegalArgumentException("Maximum column number is 255");
if (column < 0) throw new IllegalArgumentException("Minimum column number is 0");
}
/**
* Aggregates the drawing records and dumps the escher record hierarchy
* to the standard output.
*/
public void dumpDrawingRecords()
{
sheet.aggregateDrawingRecords(book.getDrawingManager());
EscherAggregate r = (EscherAggregate) getSheet().findFirstRecordBySid(EscherAggregate.sid);
List escherRecords = r.getEscherRecords();
for ( Iterator iterator = escherRecords.iterator(); iterator.hasNext(); )
{
EscherRecord escherRecord = (EscherRecord) iterator.next();
PrintWriter w = new PrintWriter(System.out);
escherRecord.display(w, 0);
w.close();
}
}
/**
* Creates the toplevel drawing patriarch. This will have the effect of
* removing any existing drawings on this sheet.
*
* @return The new patriarch.
*/
public HSSFPatriarch createDrawingPatriarch()
{
// Create the drawing group if it doesn't already exist.
book.createDrawingGroup();
sheet.aggregateDrawingRecords(book.getDrawingManager());
EscherAggregate agg = (EscherAggregate) sheet.findFirstRecordBySid(EscherAggregate.sid);
HSSFPatriarch patriarch = new HSSFPatriarch(this);
agg.clear(); // Initially the behaviour will be to clear out any existing shapes in the sheet when
// creating a new patriarch.
agg.setPatriarch(patriarch);
return patriarch;
}
}

View File

@ -0,0 +1,64 @@
package org.apache.poi.hssf.usermodel;
/**
* Represents a simple shape such as a line, rectangle or oval.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class HSSFSimpleShape
extends HSSFShape
{
// The commented out ones haven't been tested yet or aren't supported
// by HSSFSimpleShape.
public final static short OBJECT_TYPE_LINE = 1;
public final static short OBJECT_TYPE_RECTANGLE = 2;
public final static short OBJECT_TYPE_OVAL = 3;
// public final static short OBJECT_TYPE_ARC = 4;
// public final static short OBJECT_TYPE_CHART = 5;
// public final static short OBJECT_TYPE_TEXT = 6;
// public final static short OBJECT_TYPE_BUTTON = 7;
// public final static short OBJECT_TYPE_PICTURE = 8;
// public final static short OBJECT_TYPE_POLYGON = 9;
// public final static short OBJECT_TYPE_CHECKBOX = 11;
// public final static short OBJECT_TYPE_OPTION_BUTTON = 12;
// public final static short OBJECT_TYPE_EDIT_BOX = 13;
// public final static short OBJECT_TYPE_LABEL = 14;
// public final static short OBJECT_TYPE_DIALOG_BOX = 15;
// public final static short OBJECT_TYPE_SPINNER = 16;
// public final static short OBJECT_TYPE_SCROLL_BAR = 17;
// public final static short OBJECT_TYPE_LIST_BOX = 18;
// public final static short OBJECT_TYPE_GROUP_BOX = 19;
// public final static short OBJECT_TYPE_COMBO_BOX = 20;
// public final static short OBJECT_TYPE_COMMENT = 25;
// public final static short OBJECT_TYPE_MICROSOFT_OFFICE_DRAWING = 30;
int shapeType = OBJECT_TYPE_LINE;
HSSFSimpleShape( HSSFShape parent, HSSFAnchor anchor )
{
super( parent, anchor );
}
/**
* Gets the shape type.
* @return One of the OBJECT_TYPE_* constants.
*
* @see #OBJECT_TYPE_LINE
* @see #OBJECT_TYPE_OVAL
* @see #OBJECT_TYPE_RECTANGLE
*/
public int getShapeType() { return shapeType; }
/**
* Sets the shape types.
*
* @param shapeType One of the OBJECT_TYPE_* constants.
*
* @see #OBJECT_TYPE_LINE
* @see #OBJECT_TYPE_OVAL
* @see #OBJECT_TYPE_RECTANGLE
*/
public void setShapeType( int shapeType ){ this.shapeType = shapeType; }
}

View File

@ -0,0 +1,107 @@
package org.apache.poi.hssf.usermodel;
/**
* A textbox is a shape that may hold a rich text string.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
public class HSSFTextbox
extends HSSFSimpleShape
{
public final static short OBJECT_TYPE_TEXT = 6;
int marginLeft, marginRight, marginTop, marginBottom;
HSSFRichTextString string = new HSSFRichTextString("");
/**
* Construct a new textbox with the given parent and anchor.
* @param parent
* @param anchor One of HSSFClientAnchor or HSSFChildAnchor
*/
public HSSFTextbox( HSSFShape parent, HSSFAnchor anchor )
{
super( parent, anchor );
setShapeType(OBJECT_TYPE_TEXT);
}
/**
* @return the rich text string for this textbox.
*/
public HSSFRichTextString getString()
{
return string;
}
/**
* @param string Sets the rich text string used by this object.
*/
public void setString( HSSFRichTextString string )
{
this.string = string;
}
/**
* @return Returns the left margin within the textbox.
*/
public int getMarginLeft()
{
return marginLeft;
}
/**
* Sets the left margin within the textbox.
*/
public void setMarginLeft( int marginLeft )
{
this.marginLeft = marginLeft;
}
/**
* @return returns the right margin within the textbox.
*/
public int getMarginRight()
{
return marginRight;
}
/**
* Sets the right margin within the textbox.
*/
public void setMarginRight( int marginRight )
{
this.marginRight = marginRight;
}
/**
* @return returns the top margin within the textbox.
*/
public int getMarginTop()
{
return marginTop;
}
/**
* Sets the top margin within the textbox.
*/
public void setMarginTop( int marginTop )
{
this.marginTop = marginTop;
}
/**
* Gets the bottom margin within the textbox.
*/
public int getMarginBottom()
{
return marginBottom;
}
/**
* Sets the bottom margin within the textbox.
*/
public void setMarginBottom( int marginBottom )
{
this.marginBottom = marginBottom;
}
}

View File

@ -71,14 +71,7 @@ import java.util.Stack;
import org.apache.poi.hssf.eventmodel.EventRecordFactory;
import org.apache.poi.hssf.model.Sheet;
import org.apache.poi.hssf.model.Workbook;
import org.apache.poi.hssf.record.BackupRecord;
import org.apache.poi.hssf.record.ExtendedFormatRecord;
import org.apache.poi.hssf.record.FontRecord;
import org.apache.poi.hssf.record.NameRecord;
import org.apache.poi.hssf.record.RecordFactory;
import org.apache.poi.hssf.record.SSTRecord;
import org.apache.poi.hssf.record.UnknownRecord;
import org.apache.poi.hssf.record.WindowTwoRecord;
import org.apache.poi.hssf.record.*;
import org.apache.poi.hssf.record.formula.Area3DPtg;
import org.apache.poi.hssf.record.formula.MemFuncPtg;
import org.apache.poi.hssf.record.formula.UnionPtg;
@ -90,6 +83,8 @@ import org.apache.poi.poifs.filesystem.Entry;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.HexDump;
import org.apache.poi.ddf.*;
/**
* High level representation of a workbook. This is the first object most users
@ -129,16 +124,16 @@ public class HSSFWorkbook
*/
private ArrayList sheets;
/**
* this holds the HSSFName objects attached to this workbook
*/
private ArrayList names;
/**
* holds whether or not to preserve other nodes in the POIFS. Used
* for macros and embedded objects.
* for macros and embedded objects.
*/
private boolean preserveNodes;
@ -155,7 +150,7 @@ public class HSSFWorkbook
* someplace else.
*/
private HSSFDataFormat formatter;
private static POILogger log = POILogFactory.getLogger(HSSFWorkbook.class);
/**
@ -179,7 +174,7 @@ public class HSSFWorkbook
* low level models. If you're reading in a workbook...start here.
*
* @param fs the POI filesystem that contains the Workbook stream.
* @param preserveNodes whether to preseve other nodes, such as
* @param preserveNodes whether to preseve other nodes, such as
* macros. This takes more memory, so only say yes if you
* need to.
* @see org.apache.poi.poifs.filesystem.POIFSFileSystem
@ -190,20 +185,20 @@ public class HSSFWorkbook
throws IOException
{
this.preserveNodes = preserveNodes;
if (preserveNodes) {
this.poifs = fs;
this.poifs = fs;
}
sheets = new ArrayList(INITIAL_CAPACITY);
names = new ArrayList(INITIAL_CAPACITY);
InputStream stream = fs.createDocumentInputStream("Workbook");
EventRecordFactory factory = new EventRecordFactory();
List records = RecordFactory.createRecords(stream);
workbook = Workbook.createWorkbook(records);
@ -224,7 +219,7 @@ public class HSSFWorkbook
// workbook.setSheetName(sheets.size() -1, "Sheet"+sheets.size());
}
for (int i = 0 ; i < workbook.getNumNames() ; ++i){
HSSFName name = new HSSFName(workbook, workbook.getNameRecord(i));
names.add(name);
@ -240,7 +235,7 @@ public class HSSFWorkbook
* inputstream.
*
* @param s the POI filesystem that contains the Workbook stream.
* @param preserveNodes whether to preseve other nodes, such as
* @param preserveNodes whether to preseve other nodes, such as
* macros. This takes more memory, so only say yes if you
* need to.
* @see org.apache.poi.poifs.filesystem.POIFSFileSystem
@ -264,22 +259,22 @@ public class HSSFWorkbook
// none currently
}
/**
* sets the order of appearance for a given sheet.
*
* @param sheetname the name of the sheet to reorder
* @param pos the position that we want to insert the sheet into (0 based)
*/
public void setSheetOrder(String sheetname, int pos ) {
workbook.setSheetOrder(sheetname, pos);
}
public final static byte ENCODING_COMPRESSED_UNICODE = 0;
public final static byte ENCODING_UTF_16 = 1;
/**
* set the sheet name.
* Will throw IllegalArgumentException if the name is greater than 31 chars
@ -299,17 +294,17 @@ public class HSSFWorkbook
{
throw new RuntimeException("Sheet out of bounds");
}
switch ( encoding ) {
case ENCODING_COMPRESSED_UNICODE:
case ENCODING_UTF_16:
break;
default:
// TODO java.io.UnsupportedEncodingException
throw new RuntimeException( "Unsupported encoding" );
}
workbook.setSheetName( sheet, name, encoding );
}
@ -337,14 +332,14 @@ public class HSSFWorkbook
/** Returns the index of the sheet by his name
* @param name the sheet name
* @return index of the sheet (0 based)
*/
*/
public int getSheetIndex(String name)
{
int retval = workbook.getSheetIndex(name);
return retval;
}
/**
* create an HSSFSheet for this HSSFWorkbook, adds it to the sheets and returns
* the high level representation. Use this to create new sheets.
@ -561,7 +556,7 @@ public class HSSFWorkbook
//does a lot of the house keeping for builtin records, like setting lengths to zero etc
isNewRecord = true;
}
short definitionTextLength = settingRowAndColumn ? (short)0x001a : (short)0x000b;
nameRecord.setDefinitionTextLength(definitionTextLength);
@ -663,6 +658,40 @@ public class HSSFWorkbook
return retval;
}
/**
* Finds a font that matches the one with the supplied attributes
*/
public HSSFFont findFont(short boldWeight, short color, short fontHeight,
String name, boolean italic, boolean strikeout,
short typeOffset, byte underline)
{
// System.out.println( boldWeight + ", " + color + ", " + fontHeight + ", " + name + ", " + italic + ", " + strikeout + ", " + typeOffset + ", " + underline );
for (short i = 0; i < workbook.getNumberOfFontRecords(); i++)
{
if (i == 4)
continue;
FontRecord font = workbook.getFontRecordAt(i);
HSSFFont hssfFont = new HSSFFont(i, font);
// System.out.println( hssfFont.getBoldweight() + ", " + hssfFont.getColor() + ", " + hssfFont.getFontHeight() + ", " + hssfFont.getFontName() + ", " + hssfFont.getItalic() + ", " + hssfFont.getStrikeout() + ", " + hssfFont.getTypeOffset() + ", " + hssfFont.getUnderline() );
if (hssfFont.getBoldweight() == boldWeight
&& hssfFont.getColor() == color
&& hssfFont.getFontHeight() == fontHeight
&& hssfFont.getFontName().equals(name)
&& hssfFont.getItalic() == italic
&& hssfFont.getStrikeout() == strikeout
&& hssfFont.getTypeOffset() == typeOffset
&& hssfFont.getUnderline() == underline)
{
// System.out.println( "Found font" );
return hssfFont;
}
}
// System.out.println( "No font found" );
return null;
}
/**
* get the number of fonts in the font table
* @return number of fonts
@ -741,10 +770,10 @@ public class HSSFWorkbook
{
byte[] bytes = getBytes();
POIFSFileSystem fs = new POIFSFileSystem();
fs.createDocument(new ByteArrayInputStream(bytes), "Workbook");
if (preserveNodes) {
if (preserveNodes) {
List excepts = new ArrayList(1);
excepts.add("Workbook");
copyNodes(this.poifs,fs,excepts);
@ -768,6 +797,12 @@ public class HSSFWorkbook
public byte[] getBytes()
{
log.log(DEBUG, "HSSFWorkbook.getBytes()");
// before getting the workbook size we must tell the sheets that
// serialization is about to occur.
for (int k = 0; k < sheets.size(); k++)
((HSSFSheet) sheets.get(k)).getSheet().preSerialize();
int wbsize = workbook.getSize();
// log.debug("REMOVEME: old sizing method "+workbook.serialize().length);
@ -777,10 +812,10 @@ public class HSSFWorkbook
for (int k = 0; k < sheets.size(); k++)
{
workbook.setSheetBof(k, totalsize);
// sheetbytes.add((( HSSFSheet ) sheets.get(k)).getSheet().getSize());
totalsize += ((HSSFSheet) sheets.get(k)).getSheet().getSize();
}
/* if (totalsize < 4096)
{
totalsize = 4096;
@ -818,58 +853,58 @@ public class HSSFWorkbook
{
return workbook;
}
/** gets the total number of named ranges in the workboko
* @return number of named ranges
*/
*/
public int getNumberOfNames(){
int result = names.size();
return result;
}
/** gets the Named range
* @param index position of the named range
* @return named range high level
*/
*/
public HSSFName getNameAt(int index){
HSSFName result = (HSSFName) names.get(index);
return result;
}
/** gets the named range name
* @param index the named range index (0 based)
* @return named range name
*/
*/
public String getNameName(int index){
String result = getNameAt(index).getNameName();
return result;
}
/**
* Sets the printarea for the sheet provided
* <p>
* i.e. Reference = $A$1:$B$2
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
* @param reference Valid name Reference for the Print Area
* @param reference Valid name Reference for the Print Area
*/
public void setPrintArea(int sheetIndex, String reference)
{
NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
if (name == null)
name = workbook.createBuiltInName(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
//adding one here because 0 indicates a global named region; doesnt make sense for print areas
short externSheetIndex = getWorkbook().checkExternSheet(sheetIndex);
name.setExternSheetNumber(externSheetIndex);
name.setExternSheetNumber(externSheetIndex);
name.setAreaReference(reference);
}
/**
* For the Convenience of Java Programmers maintaining pointers.
* @see setPrintArea(int, String)
@ -881,57 +916,57 @@ public class HSSFWorkbook
*/
public void setPrintArea(int sheetIndex, int startColumn, int endColumn,
int startRow, int endRow) {
//using absolute references because they dont get copied and pasted anyway
//using absolute references because they dont get copied and pasted anyway
CellReference cell = new CellReference(startRow, startColumn, true, true);
String reference = cell.toString();
cell = new CellReference(endRow, endColumn, true, true);
reference = reference+":"+cell.toString();
setPrintArea(sheetIndex, reference);
setPrintArea(sheetIndex, reference);
}
/**
* Retrieves the reference for the printarea of the specified sheet, the sheet name is appended to the reference even if it was not specified.
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
* @param sheetIndex Zero-based sheet index (0 Represents the first sheet to keep consistent with java)
* @return String Null if no print area has been defined
*/
*/
public String getPrintArea(int sheetIndex)
{
NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
NameRecord name = workbook.getSpecificBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
if (name == null) return null;
//adding one here because 0 indicates a global named region; doesnt make sense for print areas
return name.getAreaReference(workbook);
}
}
/**
* Delete the printarea for the sheet specified
* @param sheetIndex Zero-based sheet index (0 = First Sheet)
*/
public void removePrintArea(int sheetIndex) {
getWorkbook().removeBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
getWorkbook().removeBuiltinRecord(NameRecord.BUILTIN_PRINT_AREA, sheetIndex+1);
}
/** creates a new named range and add it to the model
* @return named range high level
*/
*/
public HSSFName createName(){
NameRecord nameRecord = workbook.createName();
HSSFName newName = new HSSFName(workbook, nameRecord);
names.add(newName);
return newName;
return newName;
}
/** gets the named range index by his name
* @param name named range name
* @return named range index
*/
* @return named range index
*/
public int getNameIndex(String name)
{
int retval = -1;
@ -952,10 +987,10 @@ public class HSSFWorkbook
/** remove the named range by his index
* @param index named range index (0 based)
*/
*/
public void removeName(int index){
names.remove(index);
workbook.removeName(index);
workbook.removeName(index);
}
/**
@ -969,29 +1004,29 @@ public class HSSFWorkbook
formatter = new HSSFDataFormat(workbook);
return formatter;
}
/** remove the named range by his name
* @param name named range name
*/
*/
public void removeName(String name){
int index = getNameIndex(name);
removeName(index);
removeName(index);
}
public HSSFPalette getCustomPalette()
{
return new HSSFPalette(workbook.getCustomPalette());
}
/**
* Copies nodes from one POIFS to the other minus the excepts
* @param source is the source POIFS to copy from
* @param target is the target POIFS to copy to
* @param excepts is a list of Strings specifying what nodes NOT to copy
* @param target is the target POIFS to copy to
* @param excepts is a list of Strings specifying what nodes NOT to copy
*/
private void copyNodes(POIFSFileSystem source, POIFSFileSystem target,
private void copyNodes(POIFSFileSystem source, POIFSFileSystem target,
List excepts) throws IOException {
//System.err.println("CopyNodes called");
@ -999,13 +1034,13 @@ public class HSSFWorkbook
DirectoryEntry newRoot = target.getRoot();
Iterator entries = root.getEntries();
while (entries.hasNext()) {
Entry entry = (Entry)entries.next();
if (!isInList(entry.getName(), excepts)) {
copyNodeRecursively(entry,newRoot);
}
}
}
}
private boolean isInList(String entry, List list) {
@ -1017,18 +1052,18 @@ public class HSSFWorkbook
return false;
}
private void copyNodeRecursively(Entry entry, DirectoryEntry target)
private void copyNodeRecursively(Entry entry, DirectoryEntry target)
throws IOException {
//System.err.println("copyNodeRecursively called with "+entry.getName()+
// ","+target.getName());
DirectoryEntry newTarget = null;
DirectoryEntry newTarget = null;
if (entry.isDirectoryEntry()) {
newTarget = target.createDirectory(entry.getName());
Iterator entries = ((DirectoryEntry)entry).getEntries();
while (entries.hasNext()) {
copyNodeRecursively((Entry)entries.next(),newTarget);
}
}
} else {
DocumentEntry dentry = (DocumentEntry)entry;
DocumentInputStream dstream = new DocumentInputStream(dentry);
@ -1037,6 +1072,7 @@ public class HSSFWorkbook
}
}
/** Test only. Do not use */
public void insertChartRecord()
{
int loc = workbook.findFirstRecordLocBySid(SSTRecord.sid);

View File

@ -0,0 +1,81 @@
package org.apache.poi.hssf.usermodel;
import java.util.*;
import java.awt.*;
import java.io.*;
/**
* Allows the user to lookup the font metrics for a particular font without
* actually having the font on the system. The font details are loaded
* as a resource from the POI jar file (or classpath) and should be contained
* in path "/font_metrics.properties". The font widths are for a 10 point
* version of the font. Use a multiplier for other sizes.
*
* @author Glen Stampoultzis (glens at apache.org)
*/
class StaticFontMetrics
{
private static Properties fontMetricsProps;
private static Map fontDetailsMap = new HashMap();
/**
* Retrieves the fake font details for a given font.
* @param font the font to lookup.
* @return the fake font.
*/
public static FontDetails getFontDetails(Font font)
{
if (fontMetricsProps == null)
{
InputStream metricsIn = null;
try
{
fontMetricsProps = new Properties();
if (System.getProperty("font.metrics.filename") != null)
{
String filename = System.getProperty("font.metrics.filename");
File file = new File(filename);
if (!file.exists())
throw new FileNotFoundException("font_metrics.properties not found at path " + file.getAbsolutePath());
metricsIn = new FileInputStream(file);
}
else
{
metricsIn = FontDetails.class.getResourceAsStream("/font_metrics.properties");
if (metricsIn == null)
throw new FileNotFoundException("font_metrics.properties not found in classpath");
}
fontMetricsProps.load(metricsIn);
}
catch ( IOException e )
{
throw new RuntimeException("Could not load font metrics: " + e.getMessage());
}
finally
{
if (metricsIn != null)
{
try
{
metricsIn.close();
}
catch ( IOException ignore ) { }
}
}
}
String fontName = font.getName();
if (fontDetailsMap.get(fontName) == null)
{
FontDetails fontDetails = FontDetails.create(fontName, fontMetricsProps);
fontDetailsMap.put( fontName, fontDetails );
return fontDetails;
}
else
{
return (FontDetails) fontDetailsMap.get(fontName);
}
}
}