001: /*
002: * ExcelLE.java
003: *
004: * Created on June 18, 2004, 4:43 PM
005: */
006:
007: package jimm.datavision.layout.excel;
008:
009: import jimm.datavision.*;
010: import jimm.datavision.field.Field;
011: import jimm.datavision.field.Format;
012: import jimm.datavision.field.ImageField;
013: import jimm.datavision.field.Rectangle;
014: import jimm.datavision.layout.LayoutEngine;
015: import org.apache.poi.hssf.usermodel.HSSFRichTextString;
016: import java.io.OutputStream;
017: import java.util.*;
018: import org.apache.poi.hssf.usermodel.*;
019: import java.awt.*;
020:
021: /**
022: *
023: * @author dbeeler
024: */
025: public class ExcelLE extends LayoutEngine {
026:
027: protected OutputStream outStream;
028:
029: private HSSFWorkbook wb;
030: private HSSFSheet s;
031: private RowContainer row;
032: private Section lastSection;
033: private FieldMap fm;
034:
035: int rowAt;
036: short colAt;
037: int fieldNum;
038: double pastPageUsed;
039: boolean showPageHeaders;
040: int pageNum;
041:
042: /** Creates a new instance of the Excel LayoutEngine.
043: *@param out This is a binary outputstream for receiving the generated Excel file
044: *@param showAllPageHeaders This is a flag that instructs the layoutengine to reprint all
045: * page headers sent by the report engine. Setting this to false will print
046: * the page header only the first time and then ignore the rest.
047: */
048: public ExcelLE(OutputStream out, boolean showAllPageHeaders) {
049: super (null);
050: fieldNum = 0;
051: outStream = out;
052: row = null;
053: lastSection = null;
054: pastPageUsed = -1;
055: showPageHeaders = showAllPageHeaders;
056: pageNum = 0;
057: }
058:
059: protected void doStart() {
060: /* Create our workbook and worksheet */
061: wb = new HSSFWorkbook();
062: s = wb.createSheet();
063: /* Start our field map helper class */
064: fm = new FieldMap(s.getDefaultColumnWidth());
065: }
066:
067: /* This is called when the report generation is complete. This outputs all the fields
068: * according to the final column arrangement as decided by the FieldMapper
069: */
070: private void dumpFieldMap() {
071: short i;
072:
073: int[] offsetSizes = new int[FieldMap.MAXCOL];
074: for (i = 0; i < FieldMap.MAXCOL - 1; i++)
075: offsetSizes[i] = (int) fm.getColOffset(i);
076:
077: /* Iterate throught the stored, mapped rows */
078: Iterator it = fm.reportRows.iterator();
079: rowAt = 0;
080: while (it.hasNext()) {
081: RowContainer rowCont = (RowContainer) it.next();
082: HSSFRow row = s.createRow(rowAt);
083: Iterator colit = rowCont.reportFields.iterator();
084: colAt = 0;
085: /* Iterate throught the stored, mapped columns */
086: while (colit.hasNext()) {
087: PermField tmpField = (PermField) colit.next();
088: int fieldLoc = (int) tmpField.getBounds().x;
089: int fieldEnd = (int) tmpField.getBounds().x
090: + (int) tmpField.getBounds().width;
091: for (i = 0; i < FieldMap.MAXCOL - 1; i++) {
092: if (offsetSizes[i] == fieldLoc) {
093: // Find ending cell
094: int endCell;
095: for (endCell = i + 1; endCell < FieldMap.MAXCOL - 1; endCell++) {
096: if (offsetSizes[endCell] > fieldEnd) {
097: break;
098: }
099: }
100: HSSFCell cell = row.createCell(i);
101: org.apache.poi.hssf.util.Region region;
102:
103: /* Merge cells if required */
104: --endCell;
105: if (endCell != i) {
106: region = new org.apache.poi.hssf.util.Region(
107: rowAt, (short) i, rowAt,
108: (short) endCell);
109: s.addMergedRegion(region);
110: }
111:
112: cell.setCellValue(new HSSFRichTextString(
113: tmpField.getStringValue()));
114:
115: /* Setup the correct cell formating */
116: HSSFFont tmpFont = wb.createFont();
117: String fontName = tmpField.getFormat()
118: .getFont().getFontName();
119: String useFontName = "Times New Roman";
120: // TODO: Add these as I find other font translations
121: if (fontName.startsWith("Times New Roman"))
122: useFontName = "Times New Roman";
123: tmpFont.setFontName(useFontName);
124: tmpFont.setColor((short) 0);
125: tmpFont.setFontHeightInPoints((short) tmpField
126: .getFormat().getFont().getSize());
127:
128: if (tmpField.getFormat().isBold())
129: tmpFont
130: .setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
131: if (tmpField.getFormat().isUnderline())
132: tmpFont.setUnderline(HSSFFont.U_SINGLE);
133: HSSFCellStyle hcs = wb.createCellStyle();
134: hcs.setFont(tmpFont);
135:
136: /* Set proper alignment */
137: if (tmpField.getFormat().getAlign() == Format.ALIGN_CENTER)
138: hcs
139: .setAlignment(HSSFCellStyle.ALIGN_CENTER);
140: if (tmpField.getFormat().getAlign() == Format.ALIGN_LEFT)
141: hcs.setAlignment(HSSFCellStyle.ALIGN_LEFT);
142: if (tmpField.getFormat().getAlign() == Format.ALIGN_RIGHT)
143: hcs.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
144:
145: /* Enabling wordwrap seems to break stuff at the moment */
146: //if(tmpField.getFormat().isWrap()) hcs.setWrapText(true);
147: cell.setCellStyle(hcs);
148:
149: break;
150: }
151: }
152: }
153: rowAt++;
154: }
155:
156: /* Set the appropriate column widths and convert pixels back into whatever Excel uses */
157: for (i = 0; i < FieldMap.MAXCOL - 1; i++)
158: s.setColumnWidth(i, (short) (fm.colWidths[i] * 38.46));
159:
160: /* Do some garbage collection as some of this stuff generates a lot of waste */
161: fm.delete();
162: fm = null;
163: Runtime.getRuntime().gc();
164:
165: }
166:
167: protected void doEnd() {
168: try {
169: dumpFieldMap();
170: wb.write(outStream);
171: } catch (Exception e) {
172: e.printStackTrace();
173: }
174: }
175:
176: protected void doStartPage() {
177: pageNum++;
178: }
179:
180: protected void doOutputField(Field field) {
181: Rectangle rect = null;
182: rect = field.getBounds();
183: boolean showRow = true;
184: if (!this .showPageHeaders) {
185: if ((this .currentSection.getArea().getArea() == SectionArea.PAGE_HEADER)
186: && (pageNum > 1))
187: showRow = false;
188: if ((this .currentSection.getArea().getArea() == SectionArea.PAGE_HEADER)
189: && (pageNum > 1))
190: showRow = false;
191: }
192:
193: if (showRow) {
194:
195: if (this .pastPageUsed != this .pageHeightUsed) {
196: pastPageUsed = this .pageHeightUsed;
197: row = fm.createRow();
198: }
199:
200: if (lastSection != currentSection) {
201: lastSection = currentSection;
202: row = fm.createRow();
203: }
204:
205: row.addField(field);
206: }
207: }
208:
209: protected void doOutputImage(ImageField imageField) {
210: /* TODO: Implement image export in POI-HSSF and then implement the image output
211: * in DataVision
212: */
213: }
214:
215: protected void doOutputLine(jimm.datavision.Line line) {
216: /* TODO: Just 'TODO' in general */
217: }
218:
219: }
|