001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.cocoon.components.elementprocessor.impl.poi.hssf.elements;
019:
020: import java.io.IOException;
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.Map;
024:
025: import org.apache.avalon.framework.logger.AbstractLogEnabled;
026:
027: import org.apache.poi.hssf.usermodel.HSSFCell;
028: import org.apache.poi.hssf.usermodel.HSSFCellStyle;
029: import org.apache.poi.hssf.usermodel.HSSFFont;
030: import org.apache.poi.hssf.usermodel.HSSFFooter;
031: import org.apache.poi.hssf.usermodel.HSSFHeader;
032: import org.apache.poi.hssf.usermodel.HSSFRow;
033: import org.apache.poi.hssf.usermodel.HSSFSheet;
034: import org.apache.poi.hssf.util.HSSFColor;
035: import org.apache.poi.hssf.util.Region;
036:
037: /**
038: * internal representation of a Sheet
039: *
040: * @author Marc Johnson (marc_johnson27591@hotmail.com)
041: * @author Andrew C. Oliver (acoliver2@users.sourceforge.net)
042: * @version CVS $Id: Sheet.java 433543 2006-08-22 06:22:54Z crossley $
043: */
044:
045: // package scope
046: class Sheet extends AbstractLogEnabled {
047:
048: private HSSFSheet _sheet;
049: private String _name;
050: private int _physical_index;
051: private Workbook _workbook;
052:
053: // keys are Shorts (row numbers), values are Row instances
054: private Map _rows;
055:
056: private Map regions;
057:
058: //optimization constant
059: private final static int ROWS_CAPACITY = 200;
060:
061: //optimization constant
062: private final static int REGION_CAPACITY = 20;
063:
064: /**
065: * Constructor Sheet
066: * @param workbook
067: */
068: Sheet(final Workbook workbook) {
069: _workbook = workbook;
070: _name = _workbook.getNextName();
071: _sheet = _workbook.createSheet(_name);
072: _physical_index = _workbook.getPhysicalIndex(_name);
073: _rows = new HashMap(ROWS_CAPACITY);
074: regions = new HashMap(REGION_CAPACITY);
075: }
076:
077: /**
078: * renameSheet
079: * @param new_name
080: */
081: void renameSheet(final String new_name) {
082: if (!_name.equals(new_name)) {
083: _workbook.renameSheet(_physical_index, new_name);
084: _name = new_name;
085: }
086: }
087:
088: /**
089: * set a column's width
090: * @param number the column number
091: * @param points
092: * @exception IOException if any arguments are illegal
093: */
094: void setColumnWidth(final int number, final double points)
095: throws IOException {
096: if (number < 0 || number > Short.MAX_VALUE) {
097: throw new IOException("column number " + number
098: + " is too large");
099: }
100: if (!isValidColumnPoints(points)) {
101: throw new IOException("points " + points
102: + " is out of range");
103: }
104: _sheet.setColumnWidth((short) number,
105: (short) ((points * 48) + .5));
106: }
107:
108: /**
109: * get the column width of a specified column
110: * @param number the column number
111: * @return column width in characters
112: */
113: short getColumnWidth(short number) {
114: return _sheet.getColumnWidth(number);
115: }
116:
117: /**
118: * set default column width
119: * @param width width, in points
120: * @exception IOException
121: */
122: void setDefaultColumnWidth(double width) throws IOException {
123: if (width < 0 || (width >= (4.8 * (0.5 + Short.MAX_VALUE)))) {
124: throw new IOException("Invalid width (" + width + ")");
125: } // 12 is being used as a "guessed" points for the font
126: _sheet.setDefaultColumnWidth((short) ((width / 4.8) + 0.5));
127: }
128:
129: /**
130: * @return default column width (in 1/256ths of a character width)
131: */
132: short getDefaultColumnWidth() {
133: return _sheet.getDefaultColumnWidth();
134: }
135:
136: /**
137: * set default row height
138: * @param height height, in points
139: * @exception IOException
140: */
141: void setDefaultRowHeight(double height) throws IOException {
142: if (!isValidPoints(height)) {
143: throw new IOException("Invalid height (" + height + ")");
144: }
145: _sheet.setDefaultRowHeight((short) ((height * 20) + .5));
146: }
147:
148: /**
149: * @return default row height
150: */
151: short getDefaultRowHeight() {
152: return _sheet.getDefaultRowHeight();
153: }
154:
155: /**
156: * @return name
157: */
158: String getName() {
159: return _name;
160: }
161:
162: /**
163: * @return index
164: */
165: int getIndex() {
166: return _physical_index;
167: }
168:
169: /**
170: * get a specified row
171: * @param rowNo the row number
172: * @return a Row object
173: * @exception IOException if rowNo is out of range
174: */
175: Row getRow(int rowNo) throws IOException {
176: if (rowNo < 0) {
177: throw new IOException("Illegal row number: " + rowNo);
178: }
179: Short key = new Short((short) rowNo);
180: Object o = _rows.get(key);
181: Row rval = null;
182:
183: if (o == null) {
184: rval = createRow(rowNo);
185: _rows.put(key, rval);
186: } else {
187: rval = (Row) o;
188: }
189: return rval;
190: }
191:
192: HSSFCellStyle addStyleRegion(Region region) {
193: HSSFCellStyle style = _workbook.createStyle();
194: regions.put(region, style);
195: return style;
196: }
197:
198: /**
199: * returns the HSSFCellStyle for a cell if defined by region if there is
200: * not a definition it returns null. If you don't expect that then your
201: * code dies a horrible death.
202: * @return HSSFCellStyle
203: */
204: HSSFCellStyle getCellStyleForRegion(int row, short col) {
205: Iterator iregions = regions.keySet().iterator();
206: while (iregions.hasNext()) {
207: Region region = ((Region) iregions.next());
208: if (region.contains(row, col)) {
209: return (HSSFCellStyle) regions.get(region);
210: }
211: }
212: return null;
213: }
214:
215: private Row createRow(final int rowNo) {
216: return new Row(_sheet.createRow(rowNo), this );
217: }
218:
219: private boolean isValidPoints(double points) {
220: return (points >= 0 && points <= ((Short.MAX_VALUE + 0.5) / 20));
221: }
222:
223: private boolean isValidColumnPoints(double points) {
224: return (points >= 0 && points <= ((Short.MAX_VALUE + 0.5) / 48));
225: }
226:
227: /*
228: * this method doesn't appear to be used private boolean
229: * isValidCharacters(double characters) { return ((characters >= 0) &&
230: * (characters <= ((Short.MAX_VALUE + 0.5) / 256)));
231: */
232:
233: /**
234: * Flag a certain region of cells to be merged
235: * @param region the region to create as merged
236: */
237: void addMergedRegion(Region region) {
238: this ._sheet.addMergedRegion(region);
239: }
240:
241: /**
242: * assigns blank cells to regions where no cell is currently allocated.
243: * Meaning if there is a sheet with a cell defined at 1,1 and a style
244: * region from 0,0-1,1 then cells 0,0;0,1;1,0 will be defined as blank
245: * cells pointing to the style defined by the style region. If there is not
246: * a defined cell and no styleregion encompases the area, then no cell is
247: * defined.
248: */
249: public void assignBlanksToRegions() {
250: Iterator iregions = regions.keySet().iterator();
251: while (iregions.hasNext()) {
252: Region region = ((Region) iregions.next());
253: for (int rownum = region.getRowFrom(); rownum < region
254: .getRowTo() + 1; rownum++) {
255: HSSFRow row = _sheet.getRow(rownum);
256: for (short colnum = region.getColumnFrom(); colnum < region
257: .getColumnTo() + 1; colnum++) {
258: HSSFCellStyle style = (HSSFCellStyle) regions
259: .get(region);
260: if (!isBlank(style)) {
261: //don't waste time with huge blocks of blankly styled cells
262: if (row == null) {
263: if (rownum > Short.MAX_VALUE) {
264: rownum = Short.MAX_VALUE;
265: }
266: row = _sheet.createRow(rownum);
267: }
268: HSSFCell cell = row.getCell(colnum);
269: if (cell == null) {
270: cell = row.createCell(colnum);
271: cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
272: cell.setCellStyle((HSSFCellStyle) regions
273: .get(region));
274: }
275: }
276: }
277: }
278: }
279: }
280:
281: private boolean isBlank(HSSFCellStyle style) {
282: HSSFFont font = null;
283: if (style.getFontIndex() > 0) {
284: font = (_workbook.getWorkbook().getFontAt(style
285: .getFontIndex()));
286: }
287: if (style.getBorderBottom() == 0
288: && style.getBorderTop() == 0
289: && style.getBorderRight() == 0
290: && style.getBorderLeft() == 0
291: && style.getFillBackgroundColor() == HSSFColor.WHITE.index
292: && style.getFillPattern() == 0
293: && (style.getFontIndex() == 0 || ((font.getFontName()
294: .equals("Arial") || font.getFontName().equals(
295: "Helvetica"))
296: && font.getFontHeightInPoints() > 8 && font
297: .getFontHeightInPoints() < 12))) {
298: return true;
299: }
300: return false;
301: }
302:
303: /**
304: * Set the paper size.
305: * @param paperSize the paper size.
306: */
307:
308: void setPaperSize(short paperSize) {
309: _sheet.getPrintSetup().setPaperSize(paperSize);
310: }
311:
312: /**
313: * Set whether to print in landscape
314: * @param ls landscape
315: */
316:
317: void setOrientation(boolean ls) {
318: _sheet.getPrintSetup().setLandscape(ls);
319: }
320:
321: /**
322: * Set whether or not the grid is printed for the worksheet
323: * @param gridLines boolean to turn on or off the printing of
324: * gridlines
325: */
326:
327: void setPrintGridLines(boolean gridLines) {
328: _sheet.setPrintGridlines(gridLines);
329: }
330:
331: /**
332: * Set whether or not the worksheet content is centered (horizontally)
333: * on the page when it is printed
334: */
335: void setHCenter(boolean hCenter) {
336: _sheet.setHorizontallyCenter(hCenter);
337: }
338:
339: /**
340: * Setwhether or not the worksheet content is centered (vertically)
341: * on the page when it is printed
342: */
343: void setVCenter(boolean vCenter) {
344: _sheet.setVerticallyCenter(vCenter);
345: }
346:
347: /**
348: * Setup whether or not printing is in monochrome (no color)
349: */
350: void setMonochrome(boolean noColor) {
351: _sheet.getPrintSetup().setNoColor(noColor);
352: }
353:
354: /**
355: * Setup whether or not the worksheet is printed in draft format
356: */
357: void setDraft(boolean draftMode) {
358: _sheet.getPrintSetup().setDraft(draftMode);
359: }
360:
361: /**
362: * Set text to be printed at the top of every page
363: */
364: void setHeader(String left, String middle, String right) {
365: HSSFHeader header = _sheet.getHeader();
366: header.setLeft(left);
367: header.setCenter(middle);
368: header.setRight(right);
369: }
370:
371: /**
372: * Set text to be printed at the bottom of every page
373: */
374: void setFooter(String left, String middle, String right) {
375: HSSFFooter footer = _sheet.getFooter();
376: footer.setLeft(left);
377: footer.setCenter(middle);
378: footer.setRight(right);
379: }
380:
381: /**
382: * Set the top margin of the page
383: */
384: void setTopMargin(double points) {
385: _sheet.setMargin(HSSFSheet.TopMargin, points);
386: }
387:
388: /**
389: * Set the left margin of the page
390: */
391: void setLeftMargin(double points) {
392: _sheet.setMargin(HSSFSheet.LeftMargin, points);
393: }
394:
395: /**
396: * Set the right margin of the page
397: */
398: void setRightMargin(double points) {
399: _sheet.setMargin(HSSFSheet.RightMargin, points);
400: }
401:
402: /**
403: * Set the bottom margin of the page
404: */
405: void setBottomMargin(double points) {
406: _sheet.setMargin(HSSFSheet.BottomMargin, points);
407: }
408:
409: /**
410: * Set the header margin of the page
411: */
412: void setHeaderMargin(double points) {
413: _sheet.getPrintSetup().setHeaderMargin(points);
414: }
415:
416: /**
417: * Set the header margin of the page
418: */
419: void setFooterMargin(double points) {
420: _sheet.getPrintSetup().setFooterMargin(points);
421: }
422:
423: } // end package scope class Sheet
|