1 28 29 36 package net.sf.jasperreports.engine.export; 37 38 import java.awt.Color ; 39 import java.awt.Graphics2D ; 40 import java.awt.Rectangle ; 41 import java.awt.geom.Dimension2D ; 42 import java.awt.image.BufferedImage ; 43 import java.io.IOException ; 44 import java.io.OutputStream ; 45 import java.net.URL ; 46 import java.util.HashMap ; 47 import java.util.Map ; 48 49 import jxl.CellView; 50 import jxl.JXLException; 51 import jxl.SheetSettings; 52 import jxl.Workbook; 53 import jxl.biff.DisplayFormat; 54 import jxl.format.Alignment; 55 import jxl.format.BoldStyle; 56 import jxl.format.Border; 57 import jxl.format.BorderLineStyle; 58 import jxl.format.Colour; 59 import jxl.format.Orientation; 60 import jxl.format.PageOrientation; 61 import jxl.format.PaperSize; 62 import jxl.format.Pattern; 63 import jxl.format.UnderlineStyle; 64 import jxl.format.VerticalAlignment; 65 import jxl.write.Blank; 66 import jxl.write.DateTime; 67 import jxl.write.Label; 68 import jxl.write.Number; 69 import jxl.write.WritableCellFormat; 70 import jxl.write.WritableFont; 71 import jxl.write.WritableHyperlink; 72 import jxl.write.WritableImage; 73 import jxl.write.WritableSheet; 74 import jxl.write.WritableWorkbook; 75 import jxl.write.WriteException; 76 import jxl.write.biff.CellValue; 77 import jxl.write.biff.RowsExceededException; 78 import net.sf.jasperreports.engine.JRAlignment; 79 import net.sf.jasperreports.engine.JRBox; 80 import net.sf.jasperreports.engine.JRElement; 81 import net.sf.jasperreports.engine.JRException; 82 import net.sf.jasperreports.engine.JRFont; 83 import net.sf.jasperreports.engine.JRGraphicElement; 84 import net.sf.jasperreports.engine.JRHyperlink; 85 import net.sf.jasperreports.engine.JRImage; 86 import net.sf.jasperreports.engine.JRPrintElement; 87 import net.sf.jasperreports.engine.JRPrintFrame; 88 import net.sf.jasperreports.engine.JRPrintImage; 89 import net.sf.jasperreports.engine.JRPrintLine; 90 import net.sf.jasperreports.engine.JRPrintText; 91 import net.sf.jasperreports.engine.JRRenderable; 92 import net.sf.jasperreports.engine.JRReport; 93 import net.sf.jasperreports.engine.JRTextElement; 94 import net.sf.jasperreports.engine.JasperPrint; 95 import net.sf.jasperreports.engine.export.JRGridLayout.ExporterElements; 96 import net.sf.jasperreports.engine.export.data.BooleanTextValue; 97 import net.sf.jasperreports.engine.export.data.DateTextValue; 98 import net.sf.jasperreports.engine.export.data.NumberTextValue; 99 import net.sf.jasperreports.engine.export.data.StringTextValue; 100 import net.sf.jasperreports.engine.export.data.TextValue; 101 import net.sf.jasperreports.engine.export.data.TextValueHandler; 102 import net.sf.jasperreports.engine.util.JRImageLoader; 103 import net.sf.jasperreports.engine.util.JRStyledText; 104 105 import org.apache.commons.collections.ReferenceMap; 106 107 108 112 public class JExcelApiExporter extends JRXlsAbstractExporter 113 { 114 protected static final Colour WHITE = Colour.WHITE; 115 protected static final Colour BLACK = Colour.BLACK; 116 117 private static Map colorsCache = new ReferenceMap(); 118 119 120 private Map loadedCellStyles = new HashMap (); 121 122 private WritableWorkbook workbook = null; 123 124 private WritableSheet sheet = null; 125 126 private WritableCellFormat emptyCellStyle = null; 127 128 private Pattern backgroundMode = Pattern.SOLID; 129 130 private Map numberFormats; 131 private Map dateFormats; 132 133 public JExcelApiExporter() 134 { 135 numberFormats = new HashMap (); 136 dateFormats = new HashMap (); 137 } 138 139 protected void setBackground() 140 { 141 if (isWhitePageBackground) 142 { 143 this.backgroundMode = Pattern.SOLID; 144 } 145 else 146 { 147 this.backgroundMode = Pattern.NONE; 148 } 149 } 150 151 protected void openWorkbook(OutputStream os) throws JRException 152 { 153 try 154 { 155 workbook = Workbook.createWorkbook(os); 156 emptyCellStyle = new WritableCellFormat(); 157 emptyCellStyle.setBackground(WHITE, backgroundMode); 158 } 159 catch (IOException e) 160 { 161 throw new JRException("Error generating XLS report : " + jasperPrint.getName(), e); 162 } 163 catch (WriteException e) 164 { 165 throw new JRException("Error generating XLS report : " + jasperPrint.getName(), e); 166 } 167 } 168 169 protected void createSheet(String name) 170 { 171 sheet = workbook.createSheet(name, Integer.MAX_VALUE); 172 setSheetSettings(sheet); 173 } 174 175 protected void closeWorkbook(OutputStream os) throws JRException 176 { 177 try 178 { 179 workbook.write(); 180 workbook.close(); 181 } 182 catch (IOException e) 183 { 184 throw new JRException("Error generating XLS report : " + jasperPrint.getName(), e); 185 } 186 catch (WriteException e) 187 { 188 throw new JRException("Error generating XLS report : " + jasperPrint.getName(), e); 189 } 190 } 191 192 protected void setColumnWidth(short index, short width) 193 { 194 CellView cv = new CellView(); 195 cv.setSize(width); 196 sheet.setColumnView(index, cv); 197 } 198 199 protected void setRowHeight(int y, int lastRowHeight) throws JRException 200 { 201 try 202 { 203 sheet.setRowView(y, (lastRowHeight * 20)); } 205 catch (RowsExceededException e) 206 { 207 throw new JRException("Error generating XLS report : " + jasperPrint.getName(), e); 208 } 209 } 210 211 protected void setCell(int x, int y) 212 { 213 } 214 215 protected void addBlankCell(JRExporterGridCell gridCell, int colIndex, int rowIndex) throws JRException 216 { 217 try 218 { 219 Colour forecolor = BLACK; 220 if (gridCell.getForecolor() != null) 221 { 222 forecolor = getNearestColour(gridCell.getForecolor()); 223 } 224 225 Colour backcolor = WHITE; 226 if (gridCell.getBackcolor() != null) 227 { 228 backcolor = getNearestColour(gridCell.getBackcolor()); 229 } 230 231 Pattern mode = backgroundMode; 232 233 WritableFont cellFont = getLoadedFont(getDefaultFont(), forecolor.getValue()); 234 WritableCellFormat cellStyle = getLoadedCellStyle(mode, backcolor, 235 Alignment.LEFT.getValue(), VerticalAlignment.TOP.getValue(), Orientation.HORIZONTAL.getValue(), 236 cellFont, gridCell); 237 238 sheet.addCell(new Blank(colIndex, rowIndex, cellStyle)); 239 } 240 catch (RowsExceededException e) 241 { 242 throw new JRException("Error generating XLS report : " + jasperPrint.getName(), e); 243 } 244 catch (WriteException e) 245 { 246 throw new JRException("Error generating XLS report : " + jasperPrint.getName(), e); 247 } 248 } 249 250 protected void exportLine(JRPrintLine line, JRExporterGridCell gridCell, int x, int y) throws JRException 251 { 252 addMergeRegion(gridCell, x, y); 253 254 Colour forecolor2 = getNearestColour(line.getForecolor()); 255 WritableFont cellFont2 = this.getLoadedFont(getDefaultFont(), forecolor2.getValue()); 256 WritableCellFormat cellStyle2 = this.getLoadedCellStyle(Pattern.SOLID, forecolor2, Alignment.LEFT.getValue(), 257 VerticalAlignment.TOP.getValue(), Orientation.HORIZONTAL.getValue(), 258 cellFont2, gridCell); 259 260 Blank cell2 = new Blank(x, y, cellStyle2); 261 262 try 263 { 264 sheet.addCell(cell2); 265 } 266 catch (Exception e) 267 { 268 throw new JRException("Can't add cell.", e); 269 } 270 } 271 272 protected void exportRectangle(JRPrintElement element, JRExporterGridCell gridCell, int x, int y) throws JRException 273 { 274 addMergeRegion(gridCell, x, y); 275 276 Colour forecolor = getNearestColour(element.getForecolor()); 277 Colour backcolor = WHITE; 278 Pattern mode = this.backgroundMode; 279 280 if (element.getMode() == JRElement.MODE_OPAQUE) 281 { 282 mode = Pattern.SOLID; 283 backcolor = getNearestColour(element.getBackcolor()); 284 } 285 else if (gridCell.getBackcolor() != null) 286 { 287 mode = Pattern.SOLID; 288 backcolor = getNearestColour(gridCell.getBackcolor()); 289 } 290 291 WritableFont cellFont2 = this.getLoadedFont(getDefaultFont(), forecolor.getValue()); 292 WritableCellFormat cellStyle2 = this.getLoadedCellStyle(mode, backcolor, Alignment.LEFT.getValue(), 293 VerticalAlignment.TOP.getValue(), Orientation.HORIZONTAL.getValue(), 294 cellFont2, gridCell); 295 Blank cell2 = new Blank(x, y, cellStyle2); 296 297 try 298 { 299 sheet.addCell(cell2); 300 } 301 catch (Exception e) 302 { 303 throw new JRException("Can't add cell.", e); 304 } 305 } 306 307 protected void exportText(JRPrintText text, JRExporterGridCell gridCell, int x, int y) throws JRException 308 { 309 addMergeRegion(gridCell, x, y); 310 311 JRStyledText styledText = getStyledText(text); 312 313 if (styledText != null) 314 { 315 Colour forecolor = getNearestColour(text.getForecolor()); 316 WritableFont cellFont = this.getLoadedFont(text, forecolor.getValue()); 317 318 TextAlignHolder alignment = getTextAlignHolder(text); 319 int horizontalAlignment = getHorizontalAlignment(alignment); 320 int verticalAlignment = getVerticalAlignment(alignment); 321 int rotation = getRotation(alignment); 322 323 Pattern mode = this.backgroundMode; 324 Colour backcolor = WHITE; 325 326 if (text.getMode() == JRElement.MODE_OPAQUE) 327 { 328 mode = Pattern.SOLID; 329 backcolor = getNearestColour(text.getBackcolor()); 330 } 331 else if (gridCell.getBackcolor() != null) 332 { 333 mode = Pattern.SOLID; 334 backcolor = getNearestColour(gridCell.getBackcolor()); 335 } 336 337 StyleInfo baseStyle = new StyleInfo(mode, backcolor, 338 horizontalAlignment, verticalAlignment, 339 rotation, cellFont, 340 gridCell.getBox()); 341 342 try 343 { 344 String textStr = styledText.getText(); 345 346 switch (text.getHyperlinkType()) 347 { 348 case JRHyperlink.HYPERLINK_TYPE_REFERENCE: 349 { 350 if (text.getHyperlinkReference() != null) 351 { 352 URL url = new URL (text.getHyperlinkReference()); 353 WritableHyperlink hyperlink = new WritableHyperlink(x, y, x, y, url, textStr); 354 sheet.addHyperlink(hyperlink); 355 break; 356 } 357 } 358 359 case JRHyperlink.HYPERLINK_TYPE_NONE: 360 default: 361 { 362 addCell(x, y, text, textStr, baseStyle); 363 } 364 } 365 } 366 catch (Exception e) 367 { 368 throw new JRException("Can't add cell.", e); 369 } 370 } 371 } 372 373 protected void addCell(int x, int y, JRPrintText text, String textStr, StyleInfo baseStyle) throws WriteException, RowsExceededException, JRException 374 { 375 CellValue cellValue; 376 if (isDetectCellType) 377 { 378 cellValue = getDetectedCellValue(x, y, text, textStr, baseStyle); 379 } 380 else if (isAutoDetectCellType) 381 { 382 cellValue = getAutoDetectedCellValue(x, y, textStr, baseStyle); 383 } 384 else 385 { 386 cellValue = getLabelCell(x, y, textStr, baseStyle); 387 } 388 389 sheet.addCell(cellValue); 390 } 391 392 393 protected CellValue getDetectedCellValue(int x, int y, JRPrintText text, String textStr, StyleInfo baseStyle) throws JRException 394 { 395 TextValue textValue = getTextValue(text, textStr); 396 CellTextValueHandler handler = new CellTextValueHandler(x, y, baseStyle); 397 textValue.handle(handler); 398 return handler.getResult(); 399 } 400 401 protected class CellTextValueHandler implements TextValueHandler 402 { 403 private final int x; 404 private final int y; 405 private final StyleInfo baseStyle; 406 407 private CellValue result; 408 409 public CellTextValueHandler(int x, int y, StyleInfo baseStyle) 410 { 411 this.x = x; 412 this.y = y; 413 this.baseStyle = baseStyle; 414 } 415 416 public void handle(StringTextValue textValue) throws JRException 417 { 418 WritableCellFormat cellStyle = getLoadedCellStyle(baseStyle); 419 result = new Label(x, y, textValue.getText(), cellStyle); 420 } 421 422 public void handle(NumberTextValue textValue) throws JRException 423 { 424 if (textValue.getPattern() != null) 425 { 426 baseStyle.setDisplayFormat(getNumberFormat(textValue.getPattern())); 427 } 428 429 WritableCellFormat cellStyle = getLoadedCellStyle(baseStyle); 430 if (textValue.getValue() == null) 431 { 432 result = blank(cellStyle); 433 } 434 else 435 { 436 result = new Number (x, y, textValue.getValue().doubleValue(), cellStyle); 437 } 438 } 439 440 public void handle(DateTextValue textValue) throws JRException 441 { 442 baseStyle.setDisplayFormat(getDateFormat(textValue.getPattern())); 443 WritableCellFormat cellStyle = getLoadedCellStyle(baseStyle); 444 if (textValue.getValue() == null) 445 { 446 result = blank(cellStyle); 447 } 448 else 449 { 450 result = new DateTime(x, y, textValue.getValue(), cellStyle); 451 } 452 } 453 454 public void handle(BooleanTextValue textValue) throws JRException 455 { 456 WritableCellFormat cellStyle = getLoadedCellStyle(baseStyle); 457 if (textValue.getValue() == null) 458 { 459 result = blank(cellStyle); 460 } 461 else 462 { 463 result = new jxl.write.Boolean(x, y, textValue.getValue().booleanValue(), cellStyle); 464 } 465 } 466 467 protected Blank blank(WritableCellFormat cellStyle) 468 { 469 return new Blank(x, y, cellStyle); 470 } 471 472 public CellValue getResult() 473 { 474 return result; 475 } 476 } 477 478 protected jxl.write.NumberFormat getNumberFormat(String pattern) 479 { 480 jxl.write.NumberFormat cellFormat = (jxl.write.NumberFormat) numberFormats.get(pattern); 481 if (cellFormat == null) 482 { 483 cellFormat = new jxl.write.NumberFormat(pattern); 484 numberFormats.put(pattern, cellFormat); 485 } 486 return cellFormat; 487 } 488 489 protected jxl.write.DateFormat getDateFormat(String pattern) 490 { 491 jxl.write.DateFormat cellFormat = (jxl.write.DateFormat) dateFormats.get(pattern); 492 if (cellFormat == null) 493 { 494 cellFormat = new jxl.write.DateFormat(pattern); 495 dateFormats.put(pattern, cellFormat); 496 } 497 return cellFormat; 498 } 499 500 protected CellValue getAutoDetectedCellValue(int x, int y, String textStr, StyleInfo baseStyle) throws JRException 501 { 502 CellValue cellValue; 503 try 504 { 505 double d = Double.parseDouble(textStr); 506 WritableCellFormat cellStyle = getLoadedCellStyle(baseStyle); 507 cellValue = new Number (x, y, d, cellStyle); 508 } 509 catch (NumberFormatException nfe) 510 { 511 cellValue = getLabelCell(x, y, textStr, baseStyle); 512 } 513 return cellValue; 514 } 515 516 protected CellValue getLabelCell(int x, int y, String textStr, StyleInfo baseStyle) throws JRException 517 { 518 WritableCellFormat cellStyle = getLoadedCellStyle(baseStyle); 519 CellValue cellValue = new Label(x, y, textStr, cellStyle); 520 return cellValue; 521 } 522 523 protected void addMergeRegion(JRExporterGridCell gridCell, int x, int y) throws JRException 524 { 525 if (gridCell.colSpan > 1 || gridCell.rowSpan > 1) 526 { 527 try 528 { 529 sheet.mergeCells(x, y, (x + gridCell.colSpan - 1), (y + gridCell.rowSpan - 1)); 530 } 531 catch (JXLException e) 532 { 533 throw new JRException("Can't merge cells.", e); 534 } 535 } 536 } 537 538 private int getHorizontalAlignment(TextAlignHolder alignment) 539 { 540 switch (alignment.horizontalAlignment) 541 { 542 case JRAlignment.HORIZONTAL_ALIGN_RIGHT: 543 return Alignment.RIGHT.getValue(); 544 case JRAlignment.HORIZONTAL_ALIGN_CENTER: 545 return Alignment.CENTRE.getValue(); 546 case JRAlignment.HORIZONTAL_ALIGN_JUSTIFIED: 547 return Alignment.JUSTIFY.getValue(); 548 case JRAlignment.HORIZONTAL_ALIGN_LEFT: 549 default: 550 return Alignment.LEFT.getValue(); 551 } 552 } 553 554 private int getVerticalAlignment(TextAlignHolder alignment) 555 { 556 switch (alignment.verticalAlignment) 557 { 558 case JRAlignment.VERTICAL_ALIGN_BOTTOM: 559 return VerticalAlignment.BOTTOM.getValue(); 560 case JRAlignment.VERTICAL_ALIGN_MIDDLE: 561 return VerticalAlignment.CENTRE.getValue(); 562 case JRAlignment.VERTICAL_ALIGN_JUSTIFIED: 563 return VerticalAlignment.JUSTIFY.getValue(); 564 case JRAlignment.VERTICAL_ALIGN_TOP: 565 default: 566 return VerticalAlignment.TOP.getValue(); 567 } 568 } 569 570 private int getRotation(TextAlignHolder alignment) 571 { 572 switch (alignment.rotation) 573 { 574 case JRTextElement.ROTATION_LEFT: 575 return Orientation.PLUS_90.getValue(); 576 case JRTextElement.ROTATION_RIGHT: 577 return Orientation.MINUS_90.getValue(); 578 case JRTextElement.ROTATION_UPSIDE_DOWN: 579 case JRTextElement.ROTATION_NONE: 580 default: 581 return Orientation.HORIZONTAL.getValue(); 582 } 583 } 584 585 protected void exportImage(JRPrintImage element, JRExporterGridCell gridCell, int x, int y) throws JRException 586 { 587 addMergeRegion(gridCell, x, y); 588 589 try 592 { 593 JRRenderable renderer = element.getRenderer(); 594 595 int leftPadding = element.getLeftPadding(); 596 int topPadding = element.getTopPadding(); 597 int rightPadding = element.getRightPadding(); 598 int bottomPadding = element.getBottomPadding(); 599 600 int availableImageWidth = element.getWidth() - leftPadding - rightPadding; 601 availableImageWidth = availableImageWidth < 0 ? 0 : availableImageWidth; 602 603 int availableImageHeight = element.getHeight() - topPadding - bottomPadding; 604 availableImageHeight = availableImageHeight < 0 ? 0 : availableImageHeight; 605 606 607 if (availableImageWidth > 0 && availableImageHeight > 0 && renderer != null) 608 { 609 int normalWidth = availableImageWidth; 610 int normalHeight = availableImageHeight; 611 612 Dimension2D dimension = renderer.getDimension(); 613 if (dimension != null) 614 { 615 normalWidth = (int) dimension.getWidth(); 616 normalHeight = (int) dimension.getHeight(); 617 } 618 619 float xalignFactor = 0f; 620 switch (element.getHorizontalAlignment()) 621 { 622 case JRAlignment.HORIZONTAL_ALIGN_RIGHT: 623 { 624 xalignFactor = 1f; 625 break; 626 } 627 case JRAlignment.HORIZONTAL_ALIGN_CENTER: 628 { 629 xalignFactor = 0.5f; 630 break; 631 } 632 case JRAlignment.HORIZONTAL_ALIGN_LEFT: 633 default: 634 { 635 xalignFactor = 0f; 636 break; 637 } 638 } 639 640 float yalignFactor = 0f; 641 switch (element.getVerticalAlignment()) 642 { 643 case JRAlignment.VERTICAL_ALIGN_BOTTOM: 644 { 645 yalignFactor = 1f; 646 break; 647 } 648 case JRAlignment.VERTICAL_ALIGN_MIDDLE: 649 { 650 yalignFactor = 0.5f; 651 break; 652 } 653 case JRAlignment.VERTICAL_ALIGN_TOP: 654 default: 655 { 656 yalignFactor = 0f; 657 break; 658 } 659 } 660 661 BufferedImage bi = new BufferedImage (availableImageWidth, availableImageHeight, BufferedImage.TYPE_INT_ARGB); 662 Graphics2D grx = bi.createGraphics(); 663 if (JRElement.MODE_OPAQUE == element.getMode()) 664 { 665 grx.setColor(element.getBackcolor()); 666 grx.fillRect(0, 0, availableImageWidth, availableImageHeight); 667 } 668 669 switch (element.getScaleImage()) 670 { 671 case JRImage.SCALE_IMAGE_CLIP: 672 { 673 int xoffset = (int) (xalignFactor * (availableImageWidth - normalWidth)); 674 int yoffset = (int) (yalignFactor * (availableImageHeight - normalHeight)); 675 676 renderer.render(grx, new Rectangle (xoffset, yoffset, 677 normalWidth, normalHeight)); 678 679 break; 680 } 681 case JRImage.SCALE_IMAGE_FILL_FRAME: 682 { 683 renderer.render(grx, new Rectangle (0, 0, 684 availableImageWidth, availableImageHeight)); 685 686 break; 687 } 688 case JRImage.SCALE_IMAGE_RETAIN_SHAPE: 689 default: 690 { 691 if (element.getHeight() > 0) 692 { 693 double ratio = (double) normalWidth / (double) normalHeight; 694 695 if (ratio > (double) availableImageWidth / (double) availableImageHeight) 696 { 697 normalWidth = availableImageWidth; 698 normalHeight = (int) (availableImageWidth / ratio); 699 } 700 else 701 { 702 normalWidth = (int) (availableImageHeight * ratio); 703 normalHeight = availableImageHeight; 704 } 705 706 int xoffset = (int) (xalignFactor * (availableImageWidth - normalWidth)); 707 int yoffset = (int) (yalignFactor * (availableImageHeight - normalHeight)); 708 709 renderer.render(grx, new Rectangle (xoffset, yoffset, 710 normalWidth, normalHeight)); 711 } 712 713 break; 714 } 715 } 716 717 Pattern mode = this.backgroundMode; 718 Colour background = WHITE; 719 Colour forecolor = getNearestColour(element.getForecolor()); 720 721 if (element.getBorderColor() != null ){ 722 forecolor = getNearestColour(element.getBorderColor()); 723 } 724 725 WritableFont cellFont2 = this.getLoadedFont(getDefaultFont(), forecolor.getValue()); 726 727 if(element.getMode() == JRElement.MODE_OPAQUE ){ 728 mode = Pattern.SOLID; 729 background = getNearestColour(element.getBackcolor()); 730 } 731 732 WritableCellFormat cellStyle2 = this.getLoadedCellStyle(mode, background, Alignment.LEFT.getValue(), 733 VerticalAlignment.TOP.getValue(), Orientation.HORIZONTAL.getValue(), 734 cellFont2, gridCell); 735 736 737 sheet.addCell(new Blank(x, y, cellStyle2)); 738 WritableImage image = 739 new WritableImage( 740 x, 741 y, 742 gridCell.colSpan, 743 gridCell.rowSpan, 744 JRImageLoader.loadImageDataFromAWTImage(bi, JRRenderable.IMAGE_TYPE_PNG) 745 ); 746 747 748 sheet.addImage(image); 749 } 750 } 751 catch (Exception ex) 752 { 753 ex.printStackTrace(); 754 throw new JRException("The cell cannot be added", ex); 755 } 756 catch (Error err) 757 { 758 err.printStackTrace(); 759 throw new JRException("The cell cannot be added", err); 760 } 761 } 763 764 protected static Colour getNearestColour(Color awtColor) 765 { 766 Colour color = (Colour) colorsCache.get(awtColor); 767 768 if (color == null) 769 { 770 Colour[] colors = Colour.getAllColours(); 771 if ((colors != null) && (colors.length > 0)) 772 { 773 Colour crtColor = null; 774 int[] rgb = null; 775 int diff = 0; 776 int minDiff = 999; 777 778 for (int i = 0; i < colors.length; i++) 779 { 780 crtColor = colors[i]; 781 rgb = new int[3]; 782 rgb[0] = crtColor.getDefaultRGB().getRed(); 783 rgb[1] = crtColor.getDefaultRGB().getGreen(); 784 rgb[2] = crtColor.getDefaultRGB().getBlue(); 785 786 diff = Math.abs(rgb[0] - awtColor.getRed()) + Math.abs(rgb[1] - awtColor.getGreen()) + Math.abs(rgb[2] - awtColor.getBlue()); 787 788 if (diff < minDiff) 789 { 790 minDiff = diff; 791 color = crtColor; 792 } 793 } 794 } 795 796 colorsCache.put(awtColor, color); 797 } 798 799 return color; 800 } 801 802 803 829 830 private WritableFont getLoadedFont(JRFont font, int forecolor) throws JRException 831 { 832 WritableFont cellFont = null; 833 834 if (this.loadedFonts != null && this.loadedFonts.size() > 0) 835 { 836 for (int i = 0; i < this.loadedFonts.size(); i++) 837 { 838 WritableFont cf = (WritableFont) this.loadedFonts.get(i); 839 840 int fontSize = font.getFontSize(); 841 if (isFontSizeFixEnabled) 842 fontSize -= 1; 843 844 String fontName = font.getFontName(); 845 if (fontMap != null && fontMap.containsKey(fontName)) 846 { 847 fontName = (String ) fontMap.get(fontName); 848 } 849 850 if ((cf.getName().equals(fontName)) 851 && (cf.getColour().getValue() == forecolor) 852 && (cf.getPointSize() == fontSize) 853 && (cf.getUnderlineStyle() == UnderlineStyle.SINGLE ? (font.isUnderline()) : (!font.isUnderline())) 854 && (cf.isStruckout() == font.isStrikeThrough()) 855 && (cf.getBoldWeight() == BoldStyle.BOLD.getValue() ? (font.isBold()) : (!font.isBold())) 856 && (cf.isItalic() == font.isItalic())) 857 { 858 cellFont = cf; 859 break; 860 } 861 } 862 } 863 864 try 865 { 866 if (cellFont == null) 867 { 868 int fontSize = font.getFontSize(); 869 if (isFontSizeFixEnabled) 870 fontSize -= 1; 871 872 String fontName = font.getFontName(); 873 if (fontMap != null && fontMap.containsKey(fontName)) 874 { 875 fontName = (String ) fontMap.get(fontName); 876 } 877 878 cellFont = 879 new WritableFont( 880 WritableFont.createFont(fontName), 881 fontSize, 882 font.isBold() ? WritableFont.BOLD : WritableFont.NO_BOLD, 883 font.isItalic(), 884 font.isUnderline() ? UnderlineStyle.SINGLE : UnderlineStyle.NO_UNDERLINE, 885 Colour.getInternalColour(forecolor) 886 ); 887 cellFont.setStruckout(font.isStrikeThrough()); 888 889 this.loadedFonts.add(cellFont); 890 } 891 } 892 catch (Exception e) 893 { 894 throw new JRException("Can't get loaded fonts.", e); 895 } 896 897 return cellFont; 898 } 899 900 protected static class BoxStyle 901 { 902 protected final BorderLineStyle topBorder; 903 protected final BorderLineStyle bottomBorder; 904 protected final BorderLineStyle leftBorder; 905 protected final BorderLineStyle rightBorder; 906 protected final Colour topBorderColour; 907 protected final Colour bottomBorderColour; 908 protected final Colour leftBorderColour; 909 protected final Colour rightBorderColour; 910 private final int hash; 911 912 public BoxStyle(JRBox box) 913 { 914 if(box != null && box.getTopBorder() != JRGraphicElement.PEN_NONE) 915 { 916 topBorder = getBorderLineStyle(box.getTopBorder()); 917 topBorderColour = getNearestColour(box.getTopBorderColor()); 918 } 919 else 920 { 921 topBorder = BorderLineStyle.NONE; 922 topBorderColour = BLACK; 923 } 924 925 if(box != null && box.getBottomBorder() != JRGraphicElement.PEN_NONE) 926 { 927 bottomBorder = getBorderLineStyle(box.getBottomBorder()); 928 bottomBorderColour = getNearestColour(box.getBottomBorderColor()); 929 } 930 else 931 { 932 bottomBorder = BorderLineStyle.NONE; 933 bottomBorderColour = BLACK; 934 } 935 936 if(box != null && box.getLeftBorder()!= JRGraphicElement.PEN_NONE) 937 { 938 leftBorder = getBorderLineStyle(box.getLeftBorder()); 939 leftBorderColour = getNearestColour(box.getLeftBorderColor()); 940 } 941 else 942 { 943 leftBorder = BorderLineStyle.NONE; 944 leftBorderColour = BLACK; 945 } 946 947 if(box != null && box.getRightBorder() != JRGraphicElement.PEN_NONE) 948 { 949 rightBorder = getBorderLineStyle(box.getRightBorder()); 950 rightBorderColour = getNearestColour(box.getRightBorderColor()); 951 } 952 else 953 { 954 rightBorder = BorderLineStyle.NONE; 955 rightBorderColour = BLACK; 956 } 957 958 hash = computeHash(); 959 } 960 961 private int computeHash() 962 { 963 int hashCode = topBorder.hashCode(); 964 hashCode = 31*hashCode + topBorderColour.hashCode(); 965 hashCode = 31*hashCode + bottomBorder.hashCode(); 966 hashCode = 31*hashCode + bottomBorderColour.hashCode(); 967 hashCode = 31*hashCode + leftBorder.hashCode(); 968 hashCode = 31*hashCode + leftBorderColour.hashCode(); 969 hashCode = 31*hashCode + rightBorder.hashCode(); 970 hashCode = 31*hashCode + rightBorderColour.hashCode(); 971 return hashCode; 972 } 973 974 public int hashCode() 975 { 976 return hash; 977 } 978 979 public boolean equals(Object o) 980 { 981 BoxStyle b = (BoxStyle) o; 982 983 return 984 b.topBorder.equals(topBorder) && 985 b.topBorderColour.equals(topBorderColour) && 986 b.bottomBorder.equals(bottomBorder) && 987 b.bottomBorderColour.equals(bottomBorderColour) && 988 b.leftBorder.equals(leftBorder) && 989 b.leftBorderColour.equals(leftBorderColour) && 990 b.rightBorder.equals(rightBorder) && 991 b.rightBorderColour.equals(rightBorderColour); 992 } 993 994 public String toString() 995 { 996 return "(" + 997 topBorder.getValue() + "/" + topBorderColour.getValue() + "," + 998 bottomBorder.getValue() + "/" + bottomBorderColour.getValue() + "," + 999 leftBorder.getValue() + "/" + leftBorderColour.getValue() + "," + 1000 rightBorder.getValue() + "/" + rightBorderColour.getValue() + ")"; 1001 } 1002 } 1003 1004 protected static class StyleInfo 1005 { 1006 protected final Pattern mode; 1007 protected final Colour backcolor; 1008 protected final int horizontalAlignment; 1009 protected final int verticalAlignment; 1010 protected final int rotation; 1011 protected final WritableFont font; 1012 protected final BoxStyle box; 1013 private DisplayFormat displayFormat; 1014 private int hashCode; 1015 1016 protected StyleInfo(Pattern mode, Colour backcolor, int horizontalAlignment, int verticalAlignment, int rotation, WritableFont font, JRBox box) 1017 { 1018 this.mode = mode; 1019 this.backcolor = backcolor; 1020 this.horizontalAlignment = horizontalAlignment; 1021 this.verticalAlignment = verticalAlignment; 1022 this.rotation = rotation; 1023 this.font = font; 1024 this.box = new BoxStyle(box); 1025 1026 computeHash(); 1027 } 1028 1029 protected void computeHash() 1030 { 1031 int hash = this.mode.hashCode(); 1032 hash = 31*hash + this.backcolor.hashCode(); 1033 hash = 31*hash + this.horizontalAlignment; 1034 hash = 31*hash + this.verticalAlignment; 1035 hash = 31*hash + this.rotation; 1036 hash = 31*hash + this.font.hashCode(); 1037 hash = 31*hash + (this.box == null ? 0 : this.box.hashCode()); 1038 hash = 31*hash + (this.displayFormat == null ? 0 : this.displayFormat.hashCode()); 1039 1040 hashCode = hash; 1041 } 1042 1043 public int hashCode() 1044 { 1045 return hashCode; 1046 } 1047 1048 public boolean equals(Object o) 1049 { 1050 StyleInfo k = (StyleInfo) o; 1051 1052 return k.mode.equals(mode) && k.backcolor.equals(backcolor) && 1053 k.horizontalAlignment == horizontalAlignment && k.verticalAlignment == verticalAlignment && 1054 k.rotation == rotation && k.font.equals(font) && 1055 (k.box == null ? box == null : (box != null && k.box.equals(box))) && 1056 (k.displayFormat == null ? displayFormat == null : (displayFormat!= null && k.displayFormat.equals(displayFormat))); 1057 } 1058 1059 public DisplayFormat getDisplayFormat() 1060 { 1061 return displayFormat; 1062 } 1063 1064 public void setDisplayFormat(DisplayFormat displayFormat) 1065 { 1066 this.displayFormat = displayFormat; 1067 computeHash(); 1068 } 1069 1070 public String toString() 1071 { 1072 return "(" + 1073 mode + "," + backcolor + "," + 1074 horizontalAlignment + "," + verticalAlignment + "," + 1075 rotation + "," + font + "," + 1076 box + "," + displayFormat + ")"; 1077 } 1078 } 1079 1080 private WritableCellFormat getLoadedCellStyle(Pattern mode, Colour backcolor, int horizontalAlignment, 1081 int verticalAlignment, int rotation, WritableFont font, JRExporterGridCell gridCell) throws JRException 1082 { 1083 StyleInfo styleKey = new StyleInfo(mode, backcolor, horizontalAlignment, verticalAlignment, rotation, font, gridCell.getBox()); 1084 return getLoadedCellStyle(styleKey); 1085 } 1086 1087 1088 protected WritableCellFormat getLoadedCellStyle(StyleInfo styleKey) throws JRException 1089 { 1090 WritableCellFormat cellStyle = (WritableCellFormat) loadedCellStyles.get(styleKey); 1091 1092 if (cellStyle == null) 1093 { 1094 try 1095 { 1096 if (styleKey.getDisplayFormat() == null) 1097 { 1098 cellStyle = new WritableCellFormat(styleKey.font); 1099 } 1100 else 1101 { 1102 cellStyle = new WritableCellFormat(styleKey.font, styleKey.getDisplayFormat()); 1103 } 1104 cellStyle.setBackground(styleKey.backcolor, styleKey.mode); 1105 cellStyle.setAlignment(Alignment.getAlignment(styleKey.horizontalAlignment)); 1106 cellStyle.setVerticalAlignment(VerticalAlignment.getAlignment(styleKey.verticalAlignment)); 1107 cellStyle.setOrientation(Orientation.getOrientation(styleKey.rotation)); 1108 cellStyle.setWrap(true); 1109 1110 BoxStyle box = styleKey.box; 1111 cellStyle.setBorder(Border.TOP, box.topBorder, box.topBorderColour); 1112 cellStyle.setBorder(Border.BOTTOM, box.bottomBorder, box.bottomBorderColour); 1113 cellStyle.setBorder(Border.LEFT, box.leftBorder, box.leftBorderColour); 1114 cellStyle.setBorder(Border.RIGHT, box.rightBorder, box.rightBorderColour); 1115 } 1116 catch (Exception e) 1117 { 1118 throw new JRException("Error setting cellFormat-template.", e); 1119 } 1120 1121 loadedCellStyles.put(styleKey, cellStyle); 1122 } 1123 1124 return cellStyle; 1125 } 1126 1127 1130 protected static BorderLineStyle getBorderLineStyle(byte lineStyle) { 1131 BorderLineStyle retVal = null; 1132 switch(lineStyle) { 1133 case JRGraphicElement.PEN_THIN: 1134 retVal = BorderLineStyle.THIN; 1135 break; 1136 1137 case JRGraphicElement.PEN_1_POINT: 1138 case JRGraphicElement.PEN_2_POINT: 1139 retVal = BorderLineStyle.MEDIUM; 1140 break; 1141 1142 case JRGraphicElement.PEN_4_POINT: 1143 retVal = BorderLineStyle.THICK; 1144 break; 1145 1146 case JRGraphicElement.PEN_DOTTED: 1147 retVal = BorderLineStyle.DOTTED; 1148 break; 1149 1150 default: 1151 retVal = BorderLineStyle.NONE; 1152 } 1153 1154 return retVal; 1155 } 1156 1157 private final void setSheetSettings(WritableSheet sheet) 1158 { 1159 PageOrientation po; 1160 PaperSize ps; 1161 1162 if (jasperPrint.getOrientation() == JRReport.ORIENTATION_PORTRAIT) 1163 po = PageOrientation.PORTRAIT; 1164 else 1165 po = PageOrientation.LANDSCAPE; 1166 1167 if ((ps = getSuitablePaperSize(jasperPrint)) != null) 1168 sheet.setPageSetup(po, ps, 0, 0); 1169 else 1170 sheet.setPageSetup(po); 1171 1172 SheetSettings sheets = sheet.getSettings(); 1173 1174 sheets.setTopMargin(0.0); 1175 sheets.setLeftMargin(0.0); 1176 sheets.setRightMargin(0.0); 1177 sheets.setBottomMargin(0.0); 1178 1179 sheets.setHeaderMargin(0.0); 1180 sheets.setFooterMargin(0.0); 1181 } 1182 1183 private final PaperSize getSuitablePaperSize(JasperPrint jasP) 1184 { 1185 1186 if (jasP == null) 1187 return null; 1188 1189 long width = 0; 1190 long height = 0; 1191 PaperSize ps = null; 1192 1193 if ((jasP.getPageWidth() != 0) && (jasP.getPageHeight() != 0)) 1194 { 1195 1196 double dWidth = (jasP.getPageWidth() / 72.0); 1197 double dHeight = (jasP.getPageHeight() / 72.0); 1198 1199 height = Math.round(dHeight * 25.4); 1200 width = Math.round(dWidth * 25.4); 1201 1202 for (int i = 3; i < 6; i++) 1205 { 1206 int w = calculateWidthForDinAN(i); 1207 int h = calculateHeightForDinAN(i); 1208 1209 if (((w == width) && (h == height)) || ((h == width) && (w == height))) 1210 { 1211 if (i == 3) 1212 ps = PaperSize.A3; 1213 else if (i == 4) 1214 ps = PaperSize.A4; 1215 else if (i == 5) 1216 ps = PaperSize.A5; 1217 break; 1218 } 1219 } 1220 1221 if (ps == null) 1223 { 1224 if (((width == 216) && (height == 279)) || ((width == 279) && (height == 216))) 1226 { 1227 ps = PaperSize.LETTER; 1228 } 1229 if (((width == 216) && (height == 356)) || ((width == 356) && (height == 216))) 1231 { 1232 ps = PaperSize.LEGAL; 1233 } 1234 1237 } 1240 } 1241 return ps; 1242 } 1243 1244 1245 public static TextAlignHolder getTextAlignHolder(JRPrintText textElement) 1246 { 1247 short horizontalAlignment; 1248 short verticalAlignment; 1249 short rotation = textElement.getRotation(); 1250 1251 switch (textElement.getRotation()) 1252 { 1253 case JRTextElement.ROTATION_LEFT : 1254 { 1255 switch (textElement.getHorizontalAlignment()) 1256 { 1257 case JRAlignment.HORIZONTAL_ALIGN_LEFT : 1258 { 1259 verticalAlignment = JRAlignment.VERTICAL_ALIGN_BOTTOM; 1260 break; 1261 } 1262 case JRAlignment.HORIZONTAL_ALIGN_CENTER : 1263 { 1264 verticalAlignment = JRAlignment.VERTICAL_ALIGN_MIDDLE; 1265 break; 1266 } 1267 case JRAlignment.HORIZONTAL_ALIGN_RIGHT : 1268 { 1269 verticalAlignment = JRAlignment.VERTICAL_ALIGN_TOP; 1270 break; 1271 } 1272 case JRAlignment.HORIZONTAL_ALIGN_JUSTIFIED : 1273 { 1274 verticalAlignment = JRAlignment.VERTICAL_ALIGN_JUSTIFIED; 1275 break; 1276 } 1277 default : 1278 { 1279 verticalAlignment = JRAlignment.VERTICAL_ALIGN_BOTTOM; 1280 } 1281 } 1282 1283 switch (textElement.getVerticalAlignment()) 1284 { 1285 case JRAlignment.VERTICAL_ALIGN_TOP : 1286 { 1287 horizontalAlignment = JRAlignment.HORIZONTAL_ALIGN_LEFT; 1288 break; 1289 } 1290 case JRAlignment.VERTICAL_ALIGN_MIDDLE : 1291 { 1292 horizontalAlignment = JRAlignment.HORIZONTAL_ALIGN_CENTER; 1293 break; 1294 } 1295 case JRAlignment.VERTICAL_ALIGN_BOTTOM : 1296 { 1297 horizontalAlignment = JRAlignment.HORIZONTAL_ALIGN_RIGHT; 1298 break; 1299 } 1300 default : 1301 { 1302 horizontalAlignment = JRAlignment.HORIZONTAL_ALIGN_LEFT; 1303 } 1304 } 1305 1306 break; 1307 } 1308 case JRTextElement.ROTATION_RIGHT : 1309 { 1310 switch (textElement.getHorizontalAlignment()) 1311 { 1312 case JRAlignment.HORIZONTAL_ALIGN_LEFT : 1313 { 1314 verticalAlignment = JRAlignment.VERTICAL_ALIGN_TOP; 1315 break; 1316 } 1317 case JRAlignment.HORIZONTAL_ALIGN_CENTER : 1318 { 1319 verticalAlignment = JRAlignment.VERTICAL_ALIGN_MIDDLE; 1320 break; 1321 } 1322 case JRAlignment.HORIZONTAL_ALIGN_RIGHT : 1323 { 1324 verticalAlignment = JRAlignment.VERTICAL_ALIGN_BOTTOM; 1325 break; 1326 } 1327 case JRAlignment.HORIZONTAL_ALIGN_JUSTIFIED : 1328 { 1329 verticalAlignment = JRAlignment.VERTICAL_ALIGN_JUSTIFIED; 1330 break; 1331 } 1332 default : 1333 { 1334 verticalAlignment = JRAlignment.VERTICAL_ALIGN_TOP; 1335 } 1336 } 1337 1338 switch (textElement.getVerticalAlignment()) 1339 { 1340 case JRAlignment.VERTICAL_ALIGN_TOP : 1341 { 1342 horizontalAlignment = JRAlignment.HORIZONTAL_ALIGN_RIGHT; 1343 break; 1344 } 1345 case JRAlignment.VERTICAL_ALIGN_MIDDLE : 1346 { 1347 horizontalAlignment = JRAlignment.HORIZONTAL_ALIGN_CENTER; 1348 break; 1349 } 1350 case JRAlignment.VERTICAL_ALIGN_BOTTOM : 1351 { 1352 horizontalAlignment = JRAlignment.HORIZONTAL_ALIGN_LEFT; 1353 break; 1354 } 1355 default : 1356 { 1357 horizontalAlignment = JRAlignment.HORIZONTAL_ALIGN_RIGHT; 1358 } 1359 } 1360 1361 break; 1362 } 1363 case JRTextElement.ROTATION_UPSIDE_DOWN: 1364 case JRTextElement.ROTATION_NONE : 1365 default : 1366 { 1367 horizontalAlignment = textElement.getHorizontalAlignment(); 1368 verticalAlignment = textElement.getVerticalAlignment(); 1369 } 1370 } 1371 1372 return new TextAlignHolder(horizontalAlignment, verticalAlignment, rotation); 1373 } 1374 1375 1376 1377 1380 private final int calculateWidthForDinAN(int n) 1381 { 1382 return (int) (Math.pow(2.0, (-0.25 - (n / 2.0))) * 1000.0); 1383 } 1384 1385 private final int calculateHeightForDinAN(int n) 1386 { 1387 return (int) (Math.pow(2.0, (0.25 - (n / 2.0))) * 1000.0); 1388 } 1389 1390 private final int calculateWidthForDinBN(int n) 1391 { 1392 return (int) (Math.pow(2.0, -(n / 2.0)) * 1000.0); 1393 } 1394 1395 private final int calculateHeightForDinBN(int n) 1396 { 1397 return (int) (Math.pow(2.0, (0.5 - (n / 2.0))) * 1000.0); 1398 } 1399 1400 private final int calculateWidthForDinCN(int n) 1401 { 1402 return (int) (Math.pow(2.0, (-0.125 - (n / 2.0))) * 1000.0); 1403 } 1404 1405 private final int calculateHeightForDinCN(int n) 1406 { 1407 return (int) (Math.pow(2.0, (0.375 - (n / 2.0))) * 1000.0); 1408 } 1409 1410 protected ExporterElements getExporterElements() 1411 { 1412 return JRGridLayout.UNIVERSAL_EXPORTER; 1413 } 1414 1415 protected void exportFrame(JRPrintFrame frame, JRExporterGridCell gridCell, int x, int y) throws JRException 1416 { 1417 addMergeRegion(gridCell, x, y); 1418 1419 Colour forecolor = getNearestColour(frame.getForecolor()); 1420 Colour backcolor = WHITE; 1421 Pattern mode = backgroundMode; 1422 1423 if (frame.getMode() == JRElement.MODE_OPAQUE) 1424 { 1425 mode = Pattern.SOLID; 1426 backcolor = getNearestColour(frame.getBackcolor()); 1427 } 1428 1429 WritableFont cellFont = getLoadedFont(getDefaultFont(), forecolor.getValue()); 1430 WritableCellFormat cellStyle = getLoadedCellStyle(mode, backcolor, 1431 Alignment.LEFT.getValue(), VerticalAlignment.TOP.getValue(), Orientation.HORIZONTAL.getValue(), 1432 cellFont, gridCell); 1433 1434 Blank cell = new Blank(x, y, cellStyle); 1435 try 1436 { 1437 sheet.addCell(cell); 1438 } 1439 catch (JXLException e) 1440 { 1441 throw new JRException("Can't add cell.", e); 1442 } 1443 } 1444} 1445 1446 | Popular Tags |