blob: fc607eb565f1bcd1a7043eb73cd73381f499e81f [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cocoon.components.elementprocessor.impl.poi.hssf.elements;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.hssf.util.Region;
/**
* internal representation of a Sheet
*
* @author Marc Johnson (marc_johnson27591@hotmail.com)
* @author Andrew C. Oliver (acoliver2@users.sourceforge.net)
* @version CVS $Id: Sheet.java,v 1.8 2004/03/05 13:02:04 bdelacretaz Exp $
*/
// package scope
class Sheet extends AbstractLogEnabled {
private HSSFSheet _sheet;
private String _name;
private int _physical_index;
private Workbook _workbook;
// keys are Shorts (row numbers), values are Row instances
private Map _rows;
private Map regions;
//optimization constant
private final static int ROWS_CAPACITY = 200;
//optimization constant
private final static int REGION_CAPACITY = 20;
/**
* Constructor Sheet
* @param workbook
*/
Sheet(final Workbook workbook) {
_workbook = workbook;
_name = _workbook.getNextName();
_sheet = _workbook.createSheet(_name);
_physical_index = _workbook.getPhysicalIndex(_name);
_rows = new HashMap(ROWS_CAPACITY);
regions = new HashMap(REGION_CAPACITY);
}
/**
* renameSheet
* @param new_name
*/
void renameSheet(final String new_name) {
if (!_name.equals(new_name)) {
_workbook.renameSheet(_physical_index, new_name);
_name = new_name;
}
}
/**
* set a column's width
* @param number the column number
* @param points
* @exception IOException if any arguments are illegal
*/
void setColumnWidth(final int number, final double points)
throws IOException {
if (number < 0 || number > Short.MAX_VALUE) {
throw new IOException("column number " + number + " is too large");
}
if (!isValidColumnPoints(points)) {
throw new IOException("points " + points + " is out of range");
}
_sheet.setColumnWidth((short)number, (short) ((points * 48) + .5));
}
/**
* get the column width of a specified column
* @param number the column number
* @return column width in characters
*/
short getColumnWidth(short number) {
return _sheet.getColumnWidth(number);
}
/**
* set default column width
* @param width width, in points
* @exception IOException
*/
void setDefaultColumnWidth(double width) throws IOException {
if (width < 0 || (width >= (4.8 * (0.5 + Short.MAX_VALUE)))) {
throw new IOException("Invalid width (" + width + ")");
} // 12 is being used as a "guessed" points for the font
_sheet.setDefaultColumnWidth((short) ((width / 4.8) + 0.5));
}
/**
* @return default column width (in 1/256ths of a character width)
*/
short getDefaultColumnWidth() {
return _sheet.getDefaultColumnWidth();
}
/**
* set default row height
* @param height height, in points
* @exception IOException
*/
void setDefaultRowHeight(double height) throws IOException {
if (!isValidPoints(height)) {
throw new IOException("Invalid height (" + height + ")");
}
_sheet.setDefaultRowHeight((short) ((height * 20) + .5));
}
/**
* @return default row height
*/
short getDefaultRowHeight() {
return _sheet.getDefaultRowHeight();
}
/**
* @return name
*/
String getName() {
return _name;
}
/**
* @return index
*/
int getIndex() {
return _physical_index;
}
/**
* get a specified row
* @param rowNo the row number
* @return a Row object
* @exception IOException if rowNo is out of range
*/
Row getRow(int rowNo) throws IOException {
if (rowNo < 0) {
throw new IOException("Illegal row number: " + rowNo);
}
Short key = new Short((short)rowNo);
Object o = _rows.get(key);
Row rval = null;
if (o == null) {
rval = createRow(rowNo);
_rows.put(key, rval);
} else {
rval = (Row)o;
}
return rval;
}
HSSFCellStyle addStyleRegion(Region region) {
HSSFCellStyle style = _workbook.createStyle();
/*
* getLogger().debug("region = "+ region.getRowFrom() +
* ","+region.getColumnFrom()+
* ","+region.getRowTo()+","+region.getColumnTo());
*/
regions.put(region, style);
return style;
}
/**
* returns the HSSFCellStyle for a cell if defined by region if there is
* not a definition it returns null. If you don't expect that then your
* code dies a horrible death.
* @return HSSFCellStyle
*/
HSSFCellStyle getCellStyleForRegion(int row, short col) {
Iterator iregions = regions.keySet().iterator();
while (iregions.hasNext()) {
Region region = ((Region)iregions.next());
// if (col == 1)
// getLogger().debug("breakpoint support");
if (region.contains(row, col)) {
//getLogger().debug("Returning style for " + row +"," + col);
return (HSSFCellStyle)regions.get(region);
}
}
//getLogger().debug("returning null for "+row+","+col);
return null;
}
private Row createRow(final int rowNo) {
return new Row(_sheet.createRow(rowNo), this);
}
private boolean isValidPoints(double points) {
return (points >= 0 && points <= ((Short.MAX_VALUE + 0.5) / 20));
}
private boolean isValidColumnPoints(double points) {
return (points >= 0 && points <= ((Short.MAX_VALUE + 0.5) / 48));
}
/*
* this method doesn't appear to be used private boolean
* isValidCharacters(double characters) { return ((characters >= 0) &&
* (characters <= ((Short.MAX_VALUE + 0.5) / 256)));
*/
/**
* Flag a certain region of cells to be merged
* @param region the region to create as merged
*/
void addMergedRegion(Region region) {
this._sheet.addMergedRegion(region);
}
/**
* assigns blank cells to regions where no cell is currently allocated.
* Meaning if there is a sheet with a cell defined at 1,1 and a style
* region from 0,0-1,1 then cells 0,0;0,1;1,0 will be defined as blank
* cells pointing to the style defined by the style region. If there is not
* a defined cell and no styleregion encompases the area, then no cell is
* defined.
*/
public void assignBlanksToRegions() {
Iterator iregions = regions.keySet().iterator();
while (iregions.hasNext()) {
Region region = ((Region)iregions.next());
//getLogger().debug("fixing region
// "+region.getRowFrom()+","+region.getColumnFrom()+"-"+
// region.getRowTo()+","+region.getColumnTo());
for (int rownum = region.getRowFrom();
rownum < region.getRowTo() + 1; rownum++) {
HSSFRow row = _sheet.getRow(rownum);
for (short colnum = region.getColumnFrom();
colnum < region.getColumnTo() + 1; colnum++) {
HSSFCellStyle style = (HSSFCellStyle)regions.get(region);
if (!isBlank(style)) {
//don't waste time with huge blocks of blankly styled
// cells
if (row == null) {
if (rownum > Short.MAX_VALUE) {
rownum = Short.MAX_VALUE;
}
row = _sheet.createRow(rownum);
}
HSSFCell cell = row.getCell(colnum);
if (cell == null) {
//getLogger().debug("creating blank cell at
// "+rownum + "," +colnum);
cell = row.createCell(colnum);
cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
cell.setCellStyle(
(HSSFCellStyle)regions.get(region));
}
}
}
}
}
}
private boolean isBlank(HSSFCellStyle style) {
HSSFFont font = null;
if (style.getFontIndex() > 0) {
font = (_workbook.getWorkbook().getFontAt(style.getFontIndex()));
}
if (style.getBorderBottom() == 0 && style.getBorderTop() == 0
&& style.getBorderRight() == 0 && style.getBorderLeft() == 0
&& style.getFillBackgroundColor() == HSSFColor.WHITE.index
&& style.getFillPattern() == 0 && (style.getFontIndex() == 0
|| ((font.getFontName().equals("Arial")
|| font.getFontName().equals("Helvetica"))
&& font.getFontHeightInPoints() > 8
&& font.getFontHeightInPoints() < 12))) {
return true;
}
return false;
}
} // end package scope class Sheet