001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028:
029: /*
030: * Contributors:
031: * Wolfgang - javabreak@users.sourceforge.net
032: * Mario Daepp - mdaepp@users.sourceforge.net
033: */
034: package net.sf.jasperreports.engine.export;
035:
036: import java.awt.Color;
037: import java.io.IOException;
038: import java.io.OutputStream;
039: import java.util.Collection;
040: import java.util.HashMap;
041: import java.util.Iterator;
042: import java.util.Map;
043:
044: import net.sf.jasperreports.engine.JRAlignment;
045: import net.sf.jasperreports.engine.JRBox;
046: import net.sf.jasperreports.engine.JRElement;
047: import net.sf.jasperreports.engine.JRException;
048: import net.sf.jasperreports.engine.JRFont;
049: import net.sf.jasperreports.engine.JRGraphicElement;
050: import net.sf.jasperreports.engine.JRPrintElement;
051: import net.sf.jasperreports.engine.JRPrintFrame;
052: import net.sf.jasperreports.engine.JRPrintImage;
053: import net.sf.jasperreports.engine.JRPrintLine;
054: import net.sf.jasperreports.engine.JRPrintText;
055: import net.sf.jasperreports.engine.JRTextElement;
056: import net.sf.jasperreports.engine.export.data.BooleanTextValue;
057: import net.sf.jasperreports.engine.export.data.DateTextValue;
058: import net.sf.jasperreports.engine.export.data.NumberTextValue;
059: import net.sf.jasperreports.engine.export.data.StringTextValue;
060: import net.sf.jasperreports.engine.export.data.TextValue;
061: import net.sf.jasperreports.engine.export.data.TextValueHandler;
062: import net.sf.jasperreports.engine.util.JRStringUtil;
063: import net.sf.jasperreports.engine.util.JRStyledText;
064:
065: import org.apache.commons.collections.ReferenceMap;
066: import org.apache.poi.hssf.usermodel.HSSFCell;
067: import org.apache.poi.hssf.usermodel.HSSFCellStyle;
068: import org.apache.poi.hssf.usermodel.HSSFDataFormat;
069: import org.apache.poi.hssf.usermodel.HSSFFont;
070: import org.apache.poi.hssf.usermodel.HSSFRow;
071: import org.apache.poi.hssf.usermodel.HSSFSheet;
072: import org.apache.poi.hssf.usermodel.HSSFWorkbook;
073: import org.apache.poi.hssf.util.HSSFColor;
074: import org.apache.poi.hssf.util.Region;
075:
076: /**
077: * Exports a JasperReports document to XLS format. It has binary output type and exports the document to
078: * a grid-based layout.
079: * <p>
080: * Since classic AWT fonts can be sometimes very different from system fonts (which are used by XLS viewers),
081: * a font mapping feature was added. By using the {@link net.sf.jasperreports.engine.JRExporterParameter#FONT_MAP} parameter, a logical
082: * font like "sansserif" can be mapped to a system specific font, like "Comic Sans MS". Both map keys and values are strings.
083: * @author Teodor Danciu (teodord@users.sourceforge.net)
084: * @version $Id: JRXlsExporter.java 1830 2007-08-24 14:44:17Z teodord $
085: */
086: public class JRXlsExporter extends JRXlsAbstractExporter {
087:
088: private static Map hssfColorsCache = new ReferenceMap();
089:
090: protected Map loadedCellStyles = new HashMap();
091:
092: /**
093: *
094: */
095: protected HSSFWorkbook workbook = null;
096: protected HSSFSheet sheet = null;
097: protected HSSFRow row = null;
098: protected HSSFCell cell = null;
099: protected HSSFCellStyle emptyCellStyle = null;
100:
101: /**
102: *
103: */
104: protected short whiteIndex = (new HSSFColor.WHITE()).getIndex();
105: protected short blackIndex = (new HSSFColor.BLACK()).getIndex();
106:
107: protected short backgroundMode = HSSFCellStyle.SOLID_FOREGROUND;
108:
109: protected HSSFDataFormat dataFormat = null;
110: protected Map formatPatternsMap = null;
111:
112: protected void setParameters() {
113: super .setParameters();
114:
115: formatPatternsMap = (Map) getParameter(JRXlsExporterParameter.FORMAT_PATTERNS_MAP);
116: }
117:
118: protected void setBackground() {
119: if (!isWhitePageBackground) {
120: backgroundMode = HSSFCellStyle.NO_FILL;
121: }
122: }
123:
124: protected void openWorkbook(OutputStream os) {
125: workbook = new HSSFWorkbook();
126: emptyCellStyle = workbook.createCellStyle();
127: emptyCellStyle.setFillForegroundColor((new HSSFColor.WHITE())
128: .getIndex());
129: emptyCellStyle.setFillPattern(backgroundMode);
130: dataFormat = workbook.createDataFormat();
131: }
132:
133: protected void createSheet(String name) {
134: sheet = workbook.createSheet(name);
135: }
136:
137: protected void closeWorkbook(OutputStream os) throws JRException {
138: try {
139: workbook.write(os);
140: } catch (IOException e) {
141: throw new JRException("Error generating XLS report : "
142: + jasperPrint.getName(), e);
143: }
144: }
145:
146: protected void setColumnWidth(short index, short width) {
147: sheet.setColumnWidth(index, width);
148: }
149:
150: protected void setRowHeight(int rowIndex, int lastRowHeight) {
151: row = sheet.getRow(rowIndex);
152: if (row == null) {
153: row = sheet.createRow(rowIndex);
154: }
155:
156: row.setHeightInPoints(lastRowHeight);
157: }
158:
159: protected void setCell(int colIndex, int rowIndex) {
160: HSSFCell emptyCell = row.getCell((short) colIndex);
161: if (emptyCell == null) {
162: emptyCell = row.createCell((short) colIndex);
163: emptyCell.setCellStyle(emptyCellStyle);
164: }
165: }
166:
167: protected void addBlankCell(JRExporterGridCell gridCell,
168: int colIndex, int rowIndex) {
169: cell = row.createCell((short) colIndex);
170:
171: short mode = backgroundMode;
172: short backcolor = whiteIndex;
173: if (gridCell.getCellBackcolor() != null) {
174: mode = HSSFCellStyle.SOLID_FOREGROUND;
175: backcolor = getNearestColor(gridCell.getCellBackcolor())
176: .getIndex();
177: }
178:
179: short forecolor = blackIndex;
180: if (gridCell.getForecolor() != null) {
181: forecolor = getNearestColor(gridCell.getForecolor())
182: .getIndex();
183: }
184:
185: HSSFCellStyle cellStyle = getLoadedCellStyle(mode, backcolor,
186: HSSFCellStyle.ALIGN_LEFT, HSSFCellStyle.VERTICAL_TOP,
187: (short) 0, getLoadedFont(getDefaultFont(), forecolor),
188: gridCell);
189:
190: cell.setCellStyle(cellStyle);
191: }
192:
193: /**
194: *
195: */
196: protected void exportLine(JRPrintLine line,
197: JRExporterGridCell gridCell, int colIndex, int rowIndex) {
198: short forecolor = getNearestColor(line.getForecolor())
199: .getIndex();
200:
201: HSSFCellStyle cellStyle = getLoadedCellStyle(
202: HSSFCellStyle.SOLID_FOREGROUND, forecolor,
203: HSSFCellStyle.ALIGN_LEFT, HSSFCellStyle.VERTICAL_TOP,
204: (short) 0, getLoadedFont(getDefaultFont(), forecolor),
205: gridCell);
206:
207: createMergeRegion(gridCell, colIndex, rowIndex, cellStyle);
208:
209: cell = row.createCell((short) colIndex);
210: //cell.setEncoding(HSSFCell.ENCODING_UTF_16);
211: //cell.setCellValue("");
212: cell.setCellStyle(cellStyle);
213: }
214:
215: /**
216: *
217: */
218: protected void exportRectangle(JRPrintElement element,
219: JRExporterGridCell gridCell, int colIndex, int rowIndex) {
220: short forecolor = getNearestColor(element.getForecolor())
221: .getIndex();
222:
223: short mode = backgroundMode;
224: short backcolor = whiteIndex;
225: if (gridCell.getCellBackcolor() != null) {
226: mode = HSSFCellStyle.SOLID_FOREGROUND;
227: backcolor = getNearestColor(gridCell.getCellBackcolor())
228: .getIndex();
229: }
230:
231: HSSFCellStyle cellStyle = getLoadedCellStyle(mode, backcolor,
232: HSSFCellStyle.ALIGN_LEFT, HSSFCellStyle.VERTICAL_TOP,
233: (short) 0, getLoadedFont(getDefaultFont(), forecolor),
234: gridCell);
235:
236: createMergeRegion(gridCell, colIndex, rowIndex, cellStyle);
237:
238: cell = row.createCell((short) colIndex);
239: //cell.setEncoding(HSSFCell.ENCODING_UTF_16);
240: //cell.setCellValue("");
241: cell.setCellStyle(cellStyle);
242: }
243:
244: protected void exportText(JRPrintText textElement,
245: JRExporterGridCell gridCell, int colIndex, int rowIndex)
246: throws JRException {
247: JRStyledText styledText = getStyledText(textElement);
248:
249: if (styledText == null) {
250: return;
251: }
252:
253: short forecolor = getNearestColor(textElement.getForecolor())
254: .getIndex();
255:
256: TextAlignHolder textAlignHolder = getTextAlignHolder(textElement);
257: short horizontalAlignment = getHorizontalAlignment(textAlignHolder);
258: short verticalAlignment = getVerticalAlignment(textAlignHolder);
259: short rotation = getRotation(textAlignHolder);
260:
261: short mode = backgroundMode;
262: short backcolor = whiteIndex;
263: if (gridCell.getCellBackcolor() != null) {
264: mode = HSSFCellStyle.SOLID_FOREGROUND;
265: backcolor = getNearestColor(gridCell.getCellBackcolor())
266: .getIndex();
267: }
268:
269: StyleInfo baseStyle = getStyleInfo(mode, backcolor,
270: horizontalAlignment, verticalAlignment, rotation,
271: getLoadedFont(textElement, forecolor), gridCell);
272:
273: createTextCell(textElement, gridCell, colIndex, rowIndex,
274: styledText, baseStyle);
275: }
276:
277: protected void createTextCell(JRPrintText textElement,
278: final JRExporterGridCell gridCell, final int colIndex,
279: final int rowIndex, JRStyledText styledText,
280: final StyleInfo baseStyle) throws JRException {
281: String textStr = styledText.getText();
282: if (isDetectCellType) {
283: TextValue value = getTextValue(textElement, textStr);
284: value.handle(new TextValueHandler() {
285: public void handle(StringTextValue textValue) {
286: HSSFCellStyle cellStyle = initCreateCell(gridCell,
287: colIndex, rowIndex, baseStyle);
288: setStringCellValue(textValue.getText());
289: endCreateCell(cellStyle);
290: }
291:
292: public void handle(NumberTextValue textValue) {
293: if (textValue.getPattern() != null) {
294: baseStyle
295: .setDataFormat(dataFormat
296: .getFormat(getConvertedPattern(textValue
297: .getPattern())));
298: }
299:
300: HSSFCellStyle cellStyle = initCreateCell(gridCell,
301: colIndex, rowIndex, baseStyle);
302: if (textValue.getValue() == null) {
303: cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
304: } else {
305: cell.setCellValue(textValue.getValue()
306: .doubleValue());
307: }
308: endCreateCell(cellStyle);
309: }
310:
311: public void handle(DateTextValue textValue) {
312: baseStyle.setDataFormat(dataFormat
313: .getFormat(getConvertedPattern(textValue
314: .getPattern())));
315: HSSFCellStyle cellStyle = initCreateCell(gridCell,
316: colIndex, rowIndex, baseStyle);
317: if (textValue.getValue() == null) {
318: cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
319: } else {
320: cell.setCellValue(textValue.getValue());
321: }
322: endCreateCell(cellStyle);
323: }
324:
325: public void handle(BooleanTextValue textValue) {
326: HSSFCellStyle cellStyle = initCreateCell(gridCell,
327: colIndex, rowIndex, baseStyle);
328: if (textValue.getValue() == null) {
329: cell.setCellType(HSSFCell.CELL_TYPE_BLANK);
330: } else {
331: cell.setCellValue(textValue.getValue()
332: .booleanValue());
333: }
334: endCreateCell(cellStyle);
335: }
336:
337: /**
338: * This method is intended to modify a given format pattern so to include
339: * only the accepted proprietary format characters. The resulted pattern
340: * will possibly truncate the original pattern
341: * @param pattern
342: * @return pattern converted to accepted proprietary formats
343: */
344: private String getConvertedPattern(String pattern) {
345: if (formatPatternsMap != null
346: && formatPatternsMap.containsKey(pattern)) {
347: return (String) formatPatternsMap.get(pattern);
348: }
349: return pattern;
350: }
351:
352: });
353: } else if (isAutoDetectCellType) {
354: HSSFCellStyle cellStyle = initCreateCell(gridCell,
355: colIndex, rowIndex, baseStyle);
356: try {
357: cell.setCellValue(Double.parseDouble(textStr));
358: } catch (NumberFormatException e) {
359: setStringCellValue(textStr);
360: }
361: endCreateCell(cellStyle);
362: } else {
363: HSSFCellStyle cellStyle = initCreateCell(gridCell,
364: colIndex, rowIndex, baseStyle);
365: setStringCellValue(textStr);
366: endCreateCell(cellStyle);
367: }
368: }
369:
370: protected HSSFCellStyle initCreateCell(JRExporterGridCell gridCell,
371: int colIndex, int rowIndex, StyleInfo baseStyle) {
372: HSSFCellStyle cellStyle = getLoadedCellStyle(baseStyle);
373: createMergeRegion(gridCell, colIndex, rowIndex, cellStyle);
374: cell = row.createCell((short) colIndex);
375: cell.setEncoding(HSSFCell.ENCODING_UTF_16);
376: return cellStyle;
377: }
378:
379: protected void endCreateCell(HSSFCellStyle cellStyle) {
380: cell.setCellStyle(cellStyle);
381: }
382:
383: protected final void setStringCellValue(String textStr) {
384: cell.setCellValue(JRStringUtil.replaceDosEOL(textStr));
385: }
386:
387: protected void createMergeRegion(JRExporterGridCell gridCell,
388: int colIndex, int rowIndex, HSSFCellStyle cellStyle) {
389: if (gridCell.getColSpan() > 1 || gridCell.getRowSpan() > 1) {
390: if (isCollapseRowSpan) {
391: sheet.addMergedRegion(new Region(rowIndex,
392: (short) colIndex, rowIndex, (short) (colIndex
393: + gridCell.getColSpan() - 1)));
394: } else {
395: sheet
396: .addMergedRegion(new Region(rowIndex,
397: (short) colIndex, (rowIndex
398: + gridCell.getRowSpan() - 1),
399: (short) (colIndex
400: + gridCell.getColSpan() - 1)));
401: }
402:
403: for (int i = 0; i < gridCell.getRowSpan(); i++) {
404: HSSFRow spanRow = sheet.getRow(rowIndex + i);
405: if (spanRow == null) {
406: spanRow = sheet.createRow(rowIndex + i);
407: }
408: for (int j = 0; j < gridCell.getColSpan(); j++) {
409: HSSFCell spanCell = spanRow
410: .getCell((short) (colIndex + j));
411: if (spanCell == null) {
412: spanCell = spanRow
413: .createCell((short) (colIndex + j));
414: }
415: //spanCell.setCellStyle(cellStyle);
416: }
417: }
418: }
419: }
420:
421: private short getHorizontalAlignment(TextAlignHolder alignment) {
422: switch (alignment.horizontalAlignment) {
423: case JRAlignment.HORIZONTAL_ALIGN_RIGHT:
424: return HSSFCellStyle.ALIGN_RIGHT;
425: case JRAlignment.HORIZONTAL_ALIGN_CENTER:
426: return HSSFCellStyle.ALIGN_CENTER;
427: case JRAlignment.HORIZONTAL_ALIGN_JUSTIFIED:
428: return HSSFCellStyle.ALIGN_JUSTIFY;
429: case JRAlignment.HORIZONTAL_ALIGN_LEFT:
430: default:
431: return HSSFCellStyle.ALIGN_LEFT;
432: }
433: }
434:
435: private short getVerticalAlignment(TextAlignHolder alignment) {
436: switch (alignment.verticalAlignment) {
437: case JRAlignment.VERTICAL_ALIGN_BOTTOM:
438: return HSSFCellStyle.VERTICAL_BOTTOM;
439: case JRAlignment.VERTICAL_ALIGN_MIDDLE:
440: return HSSFCellStyle.VERTICAL_CENTER;
441: case JRAlignment.VERTICAL_ALIGN_JUSTIFIED:
442: return HSSFCellStyle.VERTICAL_JUSTIFY;
443: case JRAlignment.VERTICAL_ALIGN_TOP:
444: default:
445: return HSSFCellStyle.VERTICAL_TOP;
446: }
447: }
448:
449: private short getRotation(TextAlignHolder alignment) {
450: switch (alignment.rotation) {
451: case JRTextElement.ROTATION_LEFT:
452: return 90;
453: case JRTextElement.ROTATION_RIGHT:
454: return -90;
455: case JRTextElement.ROTATION_UPSIDE_DOWN:
456: case JRTextElement.ROTATION_NONE:
457: default:
458: return 0;
459: }
460: }
461:
462: /**
463: *
464: */
465: protected static HSSFColor getNearestColor(Color awtColor) {
466: HSSFColor color = (HSSFColor) hssfColorsCache.get(awtColor);
467:
468: if (color == null) {
469: Map triplets = HSSFColor.getTripletHash();
470: if (triplets != null) {
471: Collection keys = triplets.keySet();
472: if (keys != null && keys.size() > 0) {
473: Object key = null;
474: HSSFColor crtColor = null;
475: short[] rgb = null;
476: int diff = 0;
477: int minDiff = 999;
478: for (Iterator it = keys.iterator(); it.hasNext();) {
479: key = it.next();
480:
481: crtColor = (HSSFColor) triplets.get(key);
482: rgb = crtColor.getTriplet();
483:
484: diff = Math.abs(rgb[0] - awtColor.getRed())
485: + Math
486: .abs(rgb[1]
487: - awtColor.getGreen())
488: + Math.abs(rgb[2] - awtColor.getBlue());
489:
490: if (diff < minDiff) {
491: minDiff = diff;
492: color = crtColor;
493: }
494: }
495: }
496: }
497:
498: hssfColorsCache.put(awtColor, color);
499: }
500:
501: return color;
502: }
503:
504: /**
505: *
506: */
507: protected HSSFFont getLoadedFont(JRFont font, short forecolor) {
508: HSSFFont cellFont = null;
509:
510: String fontName = font.getFontName();
511: if (fontMap != null && fontMap.containsKey(fontName)) {
512: fontName = (String) fontMap.get(fontName);
513: }
514:
515: for (int i = 0; i < loadedFonts.size(); i++) {
516: HSSFFont cf = (HSSFFont) loadedFonts.get(i);
517:
518: short fontSize = (short) font.getFontSize();
519: if (isFontSizeFixEnabled)
520: fontSize -= 1;
521:
522: if (cf.getFontName().equals(fontName)
523: && (cf.getColor() == forecolor)
524: && (cf.getFontHeightInPoints() == fontSize)
525: && ((cf.getUnderline() == HSSFFont.U_SINGLE) ? (font
526: .isUnderline())
527: : (!font.isUnderline()))
528: && (cf.getStrikeout() == font.isStrikeThrough())
529: && ((cf.getBoldweight() == HSSFFont.BOLDWEIGHT_BOLD) ? (font
530: .isBold())
531: : (!font.isBold()))
532: && (cf.getItalic() == font.isItalic())) {
533: cellFont = cf;
534: break;
535: }
536: }
537:
538: if (cellFont == null) {
539: cellFont = workbook.createFont();
540:
541: cellFont.setFontName(fontName);
542: cellFont.setColor(forecolor);
543:
544: short fontSize = (short) font.getFontSize();
545: if (isFontSizeFixEnabled)
546: fontSize -= 1;
547:
548: cellFont.setFontHeightInPoints(fontSize);
549:
550: if (font.isUnderline()) {
551: cellFont.setUnderline(HSSFFont.U_SINGLE);
552: }
553: if (font.isStrikeThrough()) {
554: cellFont.setStrikeout(true);
555: }
556: if (font.isBold()) {
557: cellFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
558: }
559: if (font.isItalic()) {
560: cellFont.setItalic(true);
561: }
562:
563: loadedFonts.add(cellFont);
564: }
565:
566: return cellFont;
567: }
568:
569: protected HSSFCellStyle getLoadedCellStyle(StyleInfo style) {
570: HSSFCellStyle cellStyle = (HSSFCellStyle) loadedCellStyles
571: .get(style);
572: if (cellStyle == null) {
573: cellStyle = workbook.createCellStyle();
574: cellStyle.setFillForegroundColor(style.backcolor);
575: cellStyle.setFillPattern(style.mode);
576: cellStyle.setAlignment(style.horizontalAlignment);
577: cellStyle.setVerticalAlignment(style.verticalAlignment);
578: cellStyle.setRotation(style.rotation);
579: cellStyle.setFont(style.font);
580: cellStyle.setWrapText(true);
581:
582: if (style.hasDataFormat()) {
583: cellStyle.setDataFormat(style.getDataFormat());
584: }
585:
586: if (!isIgnoreCellBorder) {
587: BoxStyle box = style.box;
588: cellStyle.setBorderTop(box.topBorder);
589: cellStyle.setTopBorderColor(box.topBorderColour);
590: cellStyle.setBorderLeft(box.leftBorder);
591: cellStyle.setLeftBorderColor(box.leftBorderColour);
592: cellStyle.setBorderBottom(box.bottomBorder);
593: cellStyle.setBottomBorderColor(box.bottomBorderColour);
594: cellStyle.setBorderRight(box.rightBorder);
595: cellStyle.setRightBorderColor(box.rightBorderColour);
596: }
597:
598: loadedCellStyles.put(style, cellStyle);
599: }
600: return cellStyle;
601: }
602:
603: protected HSSFCellStyle getLoadedCellStyle(short mode,
604: short backcolor, short horizontalAlignment,
605: short verticalAlignment, short rotation, HSSFFont font,
606: JRExporterGridCell gridCell) {
607: StyleInfo style = getStyleInfo(mode, backcolor,
608: horizontalAlignment, verticalAlignment, rotation, font,
609: gridCell);
610: return getLoadedCellStyle(style);
611: }
612:
613: protected StyleInfo getStyleInfo(short mode, short backcolor,
614: short horizontalAlignment, short verticalAlignment,
615: short rotation, HSSFFont font, JRExporterGridCell gridCell) {
616: short gridForecolor = gridCell.getForecolor() == null ? blackIndex
617: : getNearestColor(gridCell.getForecolor()).getIndex();
618: BoxStyle boxStyle = new BoxStyle(gridCell.getBox(), backcolor,
619: gridForecolor);
620: StyleInfo style = new StyleInfo(mode, backcolor,
621: horizontalAlignment, verticalAlignment, rotation, font,
622: boxStyle);
623: return style;
624: }
625:
626: /**
627: *
628: */
629: protected static short getBorder(byte pen) {
630: short border = HSSFCellStyle.BORDER_NONE;
631:
632: switch (pen) {
633: case JRGraphicElement.PEN_DOTTED: {
634: border = HSSFCellStyle.BORDER_DASHED;
635: break;
636: }
637: case JRGraphicElement.PEN_4_POINT: {
638: border = HSSFCellStyle.BORDER_THICK;
639: break;
640: }
641: case JRGraphicElement.PEN_2_POINT: {
642: border = HSSFCellStyle.BORDER_THICK;
643: break;
644: }
645: case JRGraphicElement.PEN_THIN: {
646: border = HSSFCellStyle.BORDER_THIN;
647: break;
648: }
649: case JRGraphicElement.PEN_NONE: {
650: border = HSSFCellStyle.BORDER_NONE;
651: break;
652: }
653: case JRGraphicElement.PEN_1_POINT:
654: default: {
655: border = HSSFCellStyle.BORDER_MEDIUM;
656: break;
657: }
658: }
659:
660: return border;
661: }
662:
663: protected void exportImage(JRPrintImage image,
664: JRExporterGridCell gridCell, int colIndex, int rowIndex) {
665: //nothing
666: }
667:
668: protected void exportFrame(JRPrintFrame frame,
669: JRExporterGridCell gridCell, int x, int y) {
670: short mode = backgroundMode;
671: short backcolor = whiteIndex;
672: if (frame.getMode() == JRElement.MODE_OPAQUE) {
673: mode = HSSFCellStyle.SOLID_FOREGROUND;
674: backcolor = getNearestColor(frame.getBackcolor())
675: .getIndex();
676: }
677:
678: short forecolor = getNearestColor(frame.getForecolor())
679: .getIndex();
680:
681: HSSFCellStyle cellStyle = getLoadedCellStyle(mode, backcolor,
682: HSSFCellStyle.ALIGN_LEFT, HSSFCellStyle.VERTICAL_TOP,
683: (short) 0, getLoadedFont(getDefaultFont(), forecolor),
684: gridCell);
685:
686: createMergeRegion(gridCell, x, y, cellStyle);
687:
688: cell = row.createCell((short) x);
689: cell.setCellStyle(cellStyle);
690: }
691:
692: protected ExporterNature getNature() {
693: if (isIgnoreGraphics) {
694: return JRXlsTextOnlyExporterNature.getInstance();
695: } else {
696: return JRXlsExporterNature.getInstance();
697: }
698: }
699:
700: protected static class BoxStyle {
701: protected final short topBorder;
702: protected final short bottomBorder;
703: protected final short leftBorder;
704: protected final short rightBorder;
705: protected final short topBorderColour;
706: protected final short bottomBorderColour;
707: protected final short leftBorderColour;
708: protected final short rightBorderColour;
709: private final int hash;
710:
711: public BoxStyle(JRBox box, short backcolor, short forecolor) {
712: if (box != null
713: && box.getTopBorder() != JRGraphicElement.PEN_NONE) {
714: topBorder = getBorder(box.getTopBorder());
715: topBorderColour = box.getTopBorderColor() == null ? forecolor
716: : getNearestColor(box.getTopBorderColor())
717: .getIndex();
718: } else {
719: topBorder = HSSFCellStyle.BORDER_NONE;
720: topBorderColour = backcolor;
721: }
722:
723: if (box != null
724: && box.getBottomBorder() != JRGraphicElement.PEN_NONE) {
725: bottomBorder = getBorder(box.getBottomBorder());
726: bottomBorderColour = box.getBottomBorderColor() == null ? forecolor
727: : getNearestColor(box.getBottomBorderColor())
728: .getIndex();
729: } else {
730: bottomBorder = HSSFCellStyle.BORDER_NONE;
731: bottomBorderColour = backcolor;
732: }
733:
734: if (box != null
735: && box.getLeftBorder() != JRGraphicElement.PEN_NONE) {
736: leftBorder = getBorder(box.getLeftBorder());
737: leftBorderColour = box.getLeftBorderColor() == null ? forecolor
738: : getNearestColor(box.getLeftBorderColor())
739: .getIndex();
740: } else {
741: leftBorder = HSSFCellStyle.BORDER_NONE;
742: leftBorderColour = backcolor;
743: }
744:
745: if (box != null
746: && box.getRightBorder() != JRGraphicElement.PEN_NONE) {
747: rightBorder = getBorder(box.getRightBorder());
748: rightBorderColour = box.getRightBorderColor() == null ? forecolor
749: : getNearestColor(box.getRightBorderColor())
750: .getIndex();
751: } else {
752: rightBorder = HSSFCellStyle.BORDER_NONE;
753: rightBorderColour = backcolor;
754: }
755:
756: hash = computeHash();
757: }
758:
759: private int computeHash() {
760: int hashCode = topBorder;
761: hashCode = 31 * hashCode + topBorderColour;
762: hashCode = 31 * hashCode + bottomBorder;
763: hashCode = 31 * hashCode + bottomBorderColour;
764: hashCode = 31 * hashCode + leftBorder;
765: hashCode = 31 * hashCode + leftBorderColour;
766: hashCode = 31 * hashCode + rightBorder;
767: hashCode = 31 * hashCode + rightBorderColour;
768: return hashCode;
769: }
770:
771: public int hashCode() {
772: return hash;
773: }
774:
775: public boolean equals(Object o) {
776: BoxStyle b = (BoxStyle) o;
777:
778: return b.topBorder == topBorder
779: && b.topBorderColour == topBorderColour
780: && b.bottomBorder == bottomBorder
781: && b.bottomBorderColour == bottomBorderColour
782: && b.leftBorder == leftBorder
783: && b.leftBorderColour == leftBorderColour
784: && b.rightBorder == rightBorder
785: && b.rightBorderColour == rightBorderColour;
786: }
787:
788: public String toString() {
789: return "(" + topBorder + "/" + topBorderColour + ","
790: + bottomBorder + "/" + bottomBorderColour + ","
791: + leftBorder + "/" + leftBorderColour + ","
792: + rightBorder + "/" + rightBorderColour + ")";
793: }
794: }
795:
796: protected static class StyleInfo {
797: protected final short mode;
798: protected final short backcolor;
799: protected final short horizontalAlignment;
800: protected final short verticalAlignment;
801: protected final short rotation;
802: protected final HSSFFont font;
803: protected final BoxStyle box;
804: private short dataFormat = -1;
805: private int hashCode;
806:
807: public StyleInfo(short mode, short backcolor,
808: short horizontalAlignment, short verticalAlignment,
809: short rotation, HSSFFont font, BoxStyle box) {
810: this .mode = mode;
811: this .backcolor = backcolor;
812: this .horizontalAlignment = horizontalAlignment;
813: this .verticalAlignment = verticalAlignment;
814: this .rotation = rotation;
815: this .font = font;
816: this .box = box;
817:
818: hashCode = computeHash();
819: }
820:
821: protected int computeHash() {
822: int hash = mode;
823: hash = 31 * hash + backcolor;
824: hash = 31 * hash + horizontalAlignment;
825: hash = 31 * hash + verticalAlignment;
826: hash = 31 * hash + rotation;
827: hash = 31 * hash + (font == null ? 0 : font.getIndex());
828: hash = 31 * hash + (box == null ? 0 : box.hashCode());
829: hash = 31 * hash + dataFormat;
830: return hash;
831: }
832:
833: public void setDataFormat(short dataFormat) {
834: this .dataFormat = dataFormat;
835: hashCode = computeHash();
836: }
837:
838: public boolean hasDataFormat() {
839: return dataFormat != -1;
840: }
841:
842: public short getDataFormat() {
843: return dataFormat;
844: }
845:
846: public int hashCode() {
847: return hashCode;
848: }
849:
850: public boolean equals(Object o) {
851: StyleInfo s = (StyleInfo) o;
852:
853: return s.mode == mode
854: && s.backcolor == backcolor
855: && s.horizontalAlignment == horizontalAlignment
856: && s.verticalAlignment == verticalAlignment
857: && s.rotation == rotation
858: && (s.font == null ? font == null
859: : (font != null && s.font.getIndex() == font
860: .getIndex()))
861: && (s.box == null ? box == null
862: : (box != null && s.box.equals(box)))
863: && s.rotation == rotation;
864: }
865:
866: public String toString() {
867: return "(" + mode + "," + backcolor + ","
868: + horizontalAlignment + "," + verticalAlignment
869: + "," + rotation + "," + font + "," + box + ","
870: + dataFormat + ")";
871: }
872: }
873: }
|