001: package org.drools.decisiontable.parser.xls;
002:
003: /*
004: * Copyright 2005 JBoss Inc
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.io.IOException;
020: import java.io.InputStream;
021: import java.util.ArrayList;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026: import java.util.Set;
027:
028: import jxl.Cell;
029: import jxl.Range;
030: import jxl.Sheet;
031: import jxl.Workbook;
032: import jxl.read.biff.BiffException;
033:
034: import org.drools.decisiontable.parser.DecisionTableParseException;
035: import org.drools.decisiontable.parser.DecisionTableParser;
036: import org.drools.decisiontable.parser.SheetListener;
037:
038: /**
039: * @author <a href="mailto:michael.neale@gmail.com"> Michael Neale </a>
040: * Parse an excel spreadsheet, pusing cell info into the SheetListener interface.
041: */
042: public class ExcelParser implements DecisionTableParser {
043:
044: public static final String DEFAULT_RULESHEET_NAME = "Decision Tables";
045: private Map _listners = new HashMap();
046: private boolean _useFirstSheet;
047:
048: /**
049: * Define a map of sheet name to listner handlers.
050: *
051: * @param sheetListners
052: * map of String to SheetListener
053: */
054: public ExcelParser(final Map sheetListners) {
055: this ._listners = sheetListners;
056: }
057:
058: public ExcelParser(final List sheetListners) {
059: this ._listners.put(ExcelParser.DEFAULT_RULESHEET_NAME,
060: sheetListners);
061: this ._useFirstSheet = true;
062: }
063:
064: public ExcelParser(final SheetListener listener) {
065: List listeners = new ArrayList();
066: listeners.add(listener);
067: this ._listners.put(ExcelParser.DEFAULT_RULESHEET_NAME,
068: listeners);
069: this ._useFirstSheet = true;
070: }
071:
072: public void parseFile(InputStream inStream) {
073: try {
074: Workbook workbook = Workbook.getWorkbook(inStream);
075:
076: if (_useFirstSheet) {
077: Sheet sheet = workbook.getSheet(0);
078: processSheet(sheet, (List) _listners
079: .get(DEFAULT_RULESHEET_NAME));
080: } else {
081: Set sheetNames = _listners.keySet();
082: for (Iterator iter = sheetNames.iterator(); iter
083: .hasNext();) {
084: String sheetName = (String) iter.next();
085: Sheet sheet = workbook.getSheet(sheetName);
086: processSheet(sheet, (List) _listners.get(sheetName));
087:
088: }
089: }
090: } catch (BiffException e) {
091: throw new DecisionTableParseException(
092: "An error occured opening the workbook. ", e);
093:
094: } catch (IOException e) {
095: throw new DecisionTableParseException(
096: "Failed to open Excel stream, "
097: + "please check that the content is xls97 format.",
098: e);
099: }
100:
101: }
102:
103: private void processSheet(Sheet sheet, List listeners) {
104: int maxRows = sheet.getRows();
105:
106: Range[] mergedRanges = sheet.getMergedCells();
107:
108: for (int i = 0; i < maxRows; i++) {
109: Cell[] row = sheet.getRow(i);
110: newRow(listeners, i, row.length);
111: for (int cellNum = 0; cellNum < row.length; cellNum++) {
112: Cell cell = row[cellNum];
113:
114: Range merged = getRangeIfMerged(cell, mergedRanges);
115:
116: if (merged != null) {
117: Cell topLeft = merged.getTopLeft();
118: newCell(listeners, i, cellNum, topLeft
119: .getContents(), topLeft.getColumn());
120: } else {
121: newCell(listeners, i, cellNum, cell.getContents(),
122: SheetListener.NON_MERGED);
123: }
124: }
125: }
126: finishSheet(listeners);
127: }
128:
129: Range getRangeIfMerged(Cell cell, Range[] mergedRanges) {
130: for (int i = 0; i < mergedRanges.length; i++) {
131: Range r = mergedRanges[i];
132: Cell topLeft = r.getTopLeft();
133: Cell bottomRight = r.getBottomRight();
134: if (cell.getRow() >= topLeft.getRow()
135: && cell.getRow() <= bottomRight.getRow()
136: && cell.getColumn() >= topLeft.getColumn()
137: && cell.getColumn() <= bottomRight.getColumn()) {
138: return r;
139: }
140: }
141: return null;
142: }
143:
144: static String removeTrailingZero(String stringVal) {
145: if (stringVal.endsWith(".0")) {
146: stringVal = stringVal.substring(0, stringVal.length() - 2);
147: }
148: return stringVal;
149: }
150:
151: private void finishSheet(List listeners) {
152: for (Iterator it = listeners.iterator(); it.hasNext();) {
153: SheetListener listener = (SheetListener) it.next();
154: listener.finishSheet();
155: }
156: }
157:
158: private void newRow(List listeners, int row, int cols) {
159: for (Iterator it = listeners.iterator(); it.hasNext();) {
160: SheetListener listener = (SheetListener) it.next();
161: listener.newRow(row, cols);
162: }
163: }
164:
165: public void newCell(List listeners, int row, int column,
166: String value, int mergedColStart) {
167: for (Iterator it = listeners.iterator(); it.hasNext();) {
168: SheetListener listener = (SheetListener) it.next();
169: listener.newCell(row, column, value, mergedColStart);
170: }
171: }
172:
173: }
|