1 28 29 36 37 package net.sf.jasperreports.engine.export; 38 39 import java.awt.Color ; 40 import java.awt.Dimension ; 41 import java.awt.Rectangle ; 42 import java.awt.font.TextAttribute ; 43 import java.awt.geom.Dimension2D ; 44 import java.io.File ; 45 import java.io.FileOutputStream ; 46 import java.io.IOException ; 47 import java.io.OutputStream ; 48 import java.io.OutputStreamWriter ; 49 import java.io.StringWriter ; 50 import java.io.Writer ; 51 import java.text.AttributedCharacterIterator ; 52 import java.util.ArrayList ; 53 import java.util.HashMap ; 54 import java.util.Iterator ; 55 import java.util.LinkedList ; 56 import java.util.List ; 57 import java.util.Map ; 58 59 import net.sf.jasperreports.engine.JRAbstractExporter; 60 import net.sf.jasperreports.engine.JRAlignment; 61 import net.sf.jasperreports.engine.JRBox; 62 import net.sf.jasperreports.engine.JRElement; 63 import net.sf.jasperreports.engine.JRException; 64 import net.sf.jasperreports.engine.JRExporterParameter; 65 import net.sf.jasperreports.engine.JRGraphicElement; 66 import net.sf.jasperreports.engine.JRHyperlink; 67 import net.sf.jasperreports.engine.JRImage; 68 import net.sf.jasperreports.engine.JRImageMapRenderer; 69 import net.sf.jasperreports.engine.JRImageRenderer; 70 import net.sf.jasperreports.engine.JRPrintElement; 71 import net.sf.jasperreports.engine.JRPrintElementIndex; 72 import net.sf.jasperreports.engine.JRPrintEllipse; 73 import net.sf.jasperreports.engine.JRPrintFrame; 74 import net.sf.jasperreports.engine.JRPrintHyperlink; 75 import net.sf.jasperreports.engine.JRPrintImage; 76 import net.sf.jasperreports.engine.JRPrintImageArea; 77 import net.sf.jasperreports.engine.JRPrintImageAreaHyperlink; 78 import net.sf.jasperreports.engine.JRPrintLine; 79 import net.sf.jasperreports.engine.JRPrintPage; 80 import net.sf.jasperreports.engine.JRPrintRectangle; 81 import net.sf.jasperreports.engine.JRPrintText; 82 import net.sf.jasperreports.engine.JRRenderable; 83 import net.sf.jasperreports.engine.JRRuntimeException; 84 import net.sf.jasperreports.engine.JRTextElement; 85 import net.sf.jasperreports.engine.JRWrappingSvgRenderer; 86 import net.sf.jasperreports.engine.JasperPrint; 87 import net.sf.jasperreports.engine.util.JRStringUtil; 88 import net.sf.jasperreports.engine.util.JRStyledText; 89 import net.sf.jasperreports.engine.util.Pair; 90 91 92 102 public class JRHtmlExporter extends JRAbstractExporter 103 { 104 105 108 protected static final String JR_PAGE_ANCHOR_PREFIX = "JR_PAGE_ANCHOR_"; 109 110 113 protected static final String CSS_TEXT_ALIGN_LEFT = "left"; 114 protected static final String CSS_TEXT_ALIGN_RIGHT = "right"; 115 protected static final String CSS_TEXT_ALIGN_CENTER = "center"; 116 protected static final String CSS_TEXT_ALIGN_JUSTIFY = "justify"; 117 118 121 protected static final String HTML_VERTICAL_ALIGN_TOP = "top"; 122 protected static final String HTML_VERTICAL_ALIGN_MIDDLE = "middle"; 123 protected static final String HTML_VERTICAL_ALIGN_BOTTOM = "bottom"; 124 125 public static final String IMAGE_NAME_PREFIX = "img_"; 126 protected static final int IMAGE_NAME_PREFIX_LEGTH = IMAGE_NAME_PREFIX.length(); 127 128 131 protected Writer writer = null; 132 protected JRExportProgressMonitor progressMonitor = null; 133 protected Map rendererToImagePathMap = null; 134 protected Map imageMaps; 135 protected Map imageNameToImageDataMap = null; 136 protected List imagesToProcess = null; 137 protected boolean isPxImageLoaded = false; 138 139 protected int reportIndex = 0; 140 protected int pageIndex = 0; 141 142 145 protected File imagesDir = null; 146 protected String imagesURI = null; 147 protected boolean isOutputImagesToDir = false; 148 protected boolean isRemoveEmptySpace = false; 149 protected boolean isWhitePageBackground = true; 150 protected String encoding = null; 151 protected String sizeUnit = null; 152 153 156 protected String htmlHeader = null; 157 protected String betweenPagesHtml = null; 158 protected String htmlFooter = null; 159 160 protected StringProvider emptyCellStringProvider = null; 161 162 163 166 protected static final int colorMask = Integer.parseInt("FFFFFF", 16); 167 168 protected boolean isWrapBreakWord = false; 169 170 protected Map fontMap = null; 171 172 private LinkedList backcolorStack; 173 private Color backcolor; 174 175 protected JRHyperlinkProducerFactory hyperlinkProducerFactory; 176 177 178 public JRHtmlExporter() 179 { 180 backcolorStack = new LinkedList (); 181 backcolor = null; 182 } 183 184 185 188 public void exportReport() throws JRException 189 { 190 progressMonitor = (JRExportProgressMonitor)parameters.get(JRExporterParameter.PROGRESS_MONITOR); 191 192 193 setOffset(); 194 195 try 196 { 197 198 setExportContext(); 199 200 201 setInput(); 202 203 204 if (!isModeBatch) 205 { 206 setPageRange(); 207 } 208 209 htmlHeader = (String )parameters.get(JRHtmlExporterParameter.HTML_HEADER); 210 betweenPagesHtml = (String )parameters.get(JRHtmlExporterParameter.BETWEEN_PAGES_HTML); 211 htmlFooter = (String )parameters.get(JRHtmlExporterParameter.HTML_FOOTER); 212 213 imagesDir = (File )parameters.get(JRHtmlExporterParameter.IMAGES_DIR); 214 if (imagesDir == null) 215 { 216 String dir = (String )parameters.get(JRHtmlExporterParameter.IMAGES_DIR_NAME); 217 if (dir != null) 218 { 219 imagesDir = new File (dir); 220 } 221 } 222 223 Boolean isRemoveEmptySpaceParameter = (Boolean )parameters.get(JRHtmlExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS); 224 if (isRemoveEmptySpaceParameter != null) 225 { 226 isRemoveEmptySpace = isRemoveEmptySpaceParameter.booleanValue(); 227 } 228 229 Boolean isWhitePageBackgroundParameter = (Boolean )parameters.get(JRHtmlExporterParameter.IS_WHITE_PAGE_BACKGROUND); 230 if (isWhitePageBackgroundParameter != null) 231 { 232 isWhitePageBackground = isWhitePageBackgroundParameter.booleanValue(); 233 } 234 235 Boolean isOutputImagesToDirParameter = (Boolean )parameters.get(JRHtmlExporterParameter.IS_OUTPUT_IMAGES_TO_DIR); 236 if (isOutputImagesToDirParameter != null) 237 { 238 isOutputImagesToDir = isOutputImagesToDirParameter.booleanValue(); 239 } 240 241 String uri = (String )parameters.get(JRHtmlExporterParameter.IMAGES_URI); 242 if (uri != null) 243 { 244 imagesURI = uri; 245 } 246 247 encoding = (String )parameters.get(JRExporterParameter.CHARACTER_ENCODING); 248 if (encoding == null) 249 { 250 encoding = "UTF-8"; 251 } 252 253 rendererToImagePathMap = new HashMap (); 254 imageMaps = new HashMap (); 255 imagesToProcess = new ArrayList (); 256 isPxImageLoaded = false; 257 258 imageNameToImageDataMap = (Map )parameters.get(JRHtmlExporterParameter.IMAGES_MAP); 260 266 Boolean isWrapBreakWordParameter = (Boolean )parameters.get(JRHtmlExporterParameter.IS_WRAP_BREAK_WORD); 267 if (isWrapBreakWordParameter != null) 268 { 269 isWrapBreakWord = isWrapBreakWordParameter.booleanValue(); 270 } 271 272 sizeUnit = (String )parameters.get(JRHtmlExporterParameter.SIZE_UNIT); 273 if (sizeUnit == null) 274 { 275 sizeUnit = JRHtmlExporterParameter.SIZE_UNIT_PIXEL; 276 } 277 278 Boolean isUsingImagesToAlignParameter = (Boolean )parameters.get(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN); 279 if (isUsingImagesToAlignParameter == null) 280 { 281 isUsingImagesToAlignParameter = Boolean.TRUE; 282 } 283 284 if (isUsingImagesToAlignParameter.booleanValue()) 285 { 286 emptyCellStringProvider = 287 new StringProvider() 288 { 289 public String getStringForCollapsedTD(Object value, int width, int height, String sizeUnit) 290 { 291 return "><img alt=\"\" SRC=\"" + value + "px\" style=\"width: " + width + sizeUnit + "; height: " + height + sizeUnit + ";\"/>"; 292 } 293 public String getStringForEmptyTD(Object value) 294 { 295 return "<img alt=\"\" SRC=\"" + value + "px\" border=\"0\"/>"; 296 } 297 }; 298 299 loadPxImage(); 300 } 301 else 302 { 303 emptyCellStringProvider = 304 new StringProvider() 305 { 306 public String getStringForCollapsedTD(Object value, int width, int height, String sizeUnit) 307 { 308 return " style=\"width: " + width + sizeUnit + "; height: " + height + sizeUnit + ";\">"; 309 } 310 public String getStringForEmptyTD(Object value) 311 { 312 return ""; 313 } 314 }; 315 } 316 317 318 fontMap = (Map ) parameters.get(JRExporterParameter.FONT_MAP); 319 320 setHyperlinkProducerFactory(); 321 322 StringBuffer sb = (StringBuffer )parameters.get(JRExporterParameter.OUTPUT_STRING_BUFFER); 323 if (sb != null) 324 { 325 try 326 { 327 writer = new StringWriter (); 328 exportReportToWriter(); 329 sb.append(writer.toString()); 330 } 331 catch (IOException e) 332 { 333 throw new JRException("Error writing to StringBuffer writer : " + jasperPrint.getName(), e); 334 } 335 finally 336 { 337 if (writer != null) 338 { 339 try 340 { 341 writer.close(); 342 } 343 catch(IOException e) 344 { 345 } 346 } 347 } 348 } 349 else 350 { 351 writer = (Writer )parameters.get(JRExporterParameter.OUTPUT_WRITER); 352 if (writer != null) 353 { 354 try 355 { 356 exportReportToWriter(); 357 } 358 catch (IOException e) 359 { 360 throw new JRException("Error writing to writer : " + jasperPrint.getName(), e); 361 } 362 } 363 else 364 { 365 OutputStream os = (OutputStream )parameters.get(JRExporterParameter.OUTPUT_STREAM); 366 if (os != null) 367 { 368 try 369 { 370 writer = new OutputStreamWriter (os, encoding); 371 exportReportToWriter(); 372 } 373 catch (IOException e) 374 { 375 throw new JRException("Error writing to OutputStream writer : " + jasperPrint.getName(), e); 376 } 377 } 378 else 379 { 380 File destFile = (File )parameters.get(JRExporterParameter.OUTPUT_FILE); 381 if (destFile == null) 382 { 383 String fileName = (String )parameters.get(JRExporterParameter.OUTPUT_FILE_NAME); 384 if (fileName != null) 385 { 386 destFile = new File (fileName); 387 } 388 else 389 { 390 throw new JRException("No output specified for the exporter."); 391 } 392 } 393 394 try 395 { 396 os = new FileOutputStream (destFile); 397 writer = new OutputStreamWriter (os, encoding); 398 } 399 catch (IOException e) 400 { 401 throw new JRException("Error creating to file writer : " + jasperPrint.getName(), e); 402 } 403 404 if (imagesDir == null) 405 { 406 imagesDir = new File (destFile.getParent(), destFile.getName() + "_files"); 407 } 408 409 if (isOutputImagesToDirParameter == null) 410 { 411 isOutputImagesToDir = true; 412 } 413 414 if (imagesURI == null) 415 { 416 imagesURI = imagesDir.getName() + "/"; 417 } 418 419 try 420 { 421 exportReportToWriter(); 422 } 423 catch (IOException e) 424 { 425 throw new JRException("Error writing to file writer : " + jasperPrint.getName(), e); 426 } 427 finally 428 { 429 if (writer != null) 430 { 431 try 432 { 433 writer.close(); 434 } 435 catch(IOException e) 436 { 437 } 438 } 439 } 440 } 441 } 442 } 443 444 if (isOutputImagesToDir) 445 { 446 if (imagesDir == null) 447 { 448 throw new JRException("The images directory was not specified for the exporter."); 449 } 450 451 if (isPxImageLoaded || (imagesToProcess != null && imagesToProcess.size() > 0)) 452 { 453 if (!imagesDir.exists()) 454 { 455 imagesDir.mkdir(); 456 } 457 458 if (isPxImageLoaded) 459 { 460 JRRenderable pxRenderer = 461 JRImageRenderer.getInstance( 462 "net/sf/jasperreports/engine/images/pixel.GIF", 463 JRImage.ON_ERROR_TYPE_ERROR 464 ); 465 byte[] imageData = pxRenderer.getImageData(); 466 467 File imageFile = new File (imagesDir, "px"); 468 FileOutputStream fos = null; 469 470 try 471 { 472 fos = new FileOutputStream (imageFile); 473 fos.write(imageData, 0, imageData.length); 474 } 475 catch (IOException e) 476 { 477 throw new JRException("Error writing to image file : " + imageFile, e); 478 } 479 finally 480 { 481 if (fos != null) 482 { 483 try 484 { 485 fos.close(); 486 } 487 catch(IOException e) 488 { 489 } 490 } 491 } 492 } 493 494 for(Iterator it = imagesToProcess.iterator(); it.hasNext();) 495 { 496 JRPrintElementIndex imageIndex = (JRPrintElementIndex)it.next(); 497 498 JRPrintImage image = getImage(jasperPrintList, imageIndex); 499 JRRenderable renderer = image.getRenderer(); 500 if (renderer.getType() == JRRenderable.TYPE_SVG) 501 { 502 renderer = 503 new JRWrappingSvgRenderer( 504 renderer, 505 new Dimension (image.getWidth(), image.getHeight()), 506 JRElement.MODE_OPAQUE == image.getMode() ? image.getBackcolor() : null 507 ); 508 } 509 510 byte[] imageData = renderer.getImageData(); 511 512 File imageFile = new File (imagesDir, getImageName(imageIndex)); 513 FileOutputStream fos = null; 514 515 try 516 { 517 fos = new FileOutputStream (imageFile); 518 fos.write(imageData, 0, imageData.length); 519 } 520 catch (IOException e) 521 { 522 throw new JRException("Error writing to image file : " + imageFile, e); 523 } 524 finally 525 { 526 if (fos != null) 527 { 528 try 529 { 530 fos.close(); 531 } 532 catch(IOException e) 533 { 534 } 535 } 536 } 537 } 538 } 539 } 540 } 541 finally 542 { 543 resetExportContext(); 544 } 545 } 546 547 548 protected void setHyperlinkProducerFactory() 549 { 550 hyperlinkProducerFactory = (JRHyperlinkProducerFactory) parameters.get(JRHtmlExporterParameter.HYPERLINK_PRODUCER_FACTORY); 551 } 552 553 554 public static JRPrintImage getImage(List jasperPrintList, String imageName) 555 { 556 return getImage(jasperPrintList, getPrintElementIndex(imageName)); 557 } 558 559 560 public static JRPrintImage getImage(List jasperPrintList, JRPrintElementIndex imageIndex) 561 { 562 JasperPrint report = (JasperPrint)jasperPrintList.get(imageIndex.getReportIndex()); 563 JRPrintPage page = (JRPrintPage)report.getPages().get(imageIndex.getPageIndex()); 564 565 Integer [] elementIndexes = imageIndex.getElementIndexes(); 566 Object element = page.getElements().get(elementIndexes[0].intValue()); 567 568 for (int i = 1; i < elementIndexes.length; ++i) 569 { 570 JRPrintFrame frame = (JRPrintFrame) element; 571 element = frame.getElements().get(elementIndexes[i].intValue()); 572 } 573 574 return (JRPrintImage) element; 575 } 576 577 578 581 protected void exportReportToWriter() throws JRException, IOException 582 { 583 if (htmlHeader == null) 584 { 585 writer.write("<html>\n"); 589 writer.write("<head>\n"); 590 writer.write(" <title></title>\n"); 591 writer.write(" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=" + encoding + "\"/>\n"); 592 writer.write(" <style type=\"text/css\">\n"); 593 writer.write(" a {text-decoration: none}\n"); 594 writer.write(" </style>\n"); 595 writer.write("</head>\n"); 596 writer.write("<body text=\"#000000\" link=\"#000000\" alink=\"#000000\" vlink=\"#000000\">\n"); 597 writer.write("<table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n"); 598 writer.write("<tr><td width=\"50%\"> </td><td align=\"center\">\n"); 599 writer.write("\n"); 600 } 601 else 602 { 603 writer.write(htmlHeader); 604 } 605 606 for(reportIndex = 0; reportIndex < jasperPrintList.size(); reportIndex++) 607 { 608 jasperPrint = (JasperPrint)jasperPrintList.get(reportIndex); 609 610 List pages = jasperPrint.getPages(); 611 if (pages != null && pages.size() > 0) 612 { 613 if (isModeBatch) 614 { 615 startPageIndex = 0; 616 endPageIndex = pages.size() - 1; 617 } 618 619 JRPrintPage page = null; 620 for(pageIndex = startPageIndex; pageIndex <= endPageIndex; pageIndex++) 621 { 622 if (Thread.currentThread().isInterrupted()) 623 { 624 throw new JRException("Current thread interrupted."); 625 } 626 627 page = (JRPrintPage)pages.get(pageIndex); 628 629 writer.write("<a name=\"" + JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + (pageIndex + 1) + "\"/>\n"); 630 631 632 exportPage(page); 633 634 if (reportIndex < jasperPrintList.size() - 1 || pageIndex < endPageIndex) 635 { 636 if (betweenPagesHtml == null) 637 { 638 writer.write("<br/>\n<br/>\n"); 639 } 640 else 641 { 642 writer.write(betweenPagesHtml); 643 } 644 } 645 646 writer.write("\n"); 647 } 648 } 649 } 650 651 if (htmlFooter == null) 652 { 653 writer.write("</td><td width=\"50%\"> </td></tr>\n"); 654 writer.write("</table>\n"); 655 writer.write("</body>\n"); 656 writer.write("</html>\n"); 657 } 658 else 659 { 660 writer.write(htmlFooter); 661 } 662 663 writer.flush(); 664 } 665 666 667 670 protected void exportPage(JRPrintPage page) throws JRException, IOException 671 { 672 JRGridLayout layout = getPageGridLayout(page); 673 exportGrid(layout, isWhitePageBackground); 674 675 if (progressMonitor != null) 676 { 677 progressMonitor.afterPageExport(); 678 } 679 } 680 681 682 685 protected void exportGrid(JRGridLayout gridLayout, boolean whitePageBackground) throws IOException , JRException 686 { 687 List xCuts = gridLayout.getXCuts(); 688 JRExporterGridCell[][] grid = gridLayout.getGrid(); 689 boolean[] isRowNotEmpty = gridLayout.getIsRowNotEmpty(); 690 691 writer.write("<table style=\"width: " + gridLayout.getWidth() + sizeUnit + "\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\""); 692 if (whitePageBackground) 693 { 694 writer.write(" bgcolor=\"white\""); 695 } 696 writer.write(">\n"); 697 698 if (whitePageBackground) 699 { 700 setBackcolor(Color.white); 701 } 702 703 writer.write("<tr>\n"); 704 int width = 0; 705 for(int i = 1; i < xCuts.size(); i++) 706 { 707 width = ((Integer )xCuts.get(i)).intValue() - ((Integer )xCuts.get(i - 1)).intValue(); 708 writer.write(" <td" + emptyCellStringProvider.getStringForCollapsedTD(imagesURI, width, 1, sizeUnit) + "</td>\n"); 709 } 710 writer.write("</tr>\n"); 711 712 JRPrintElement element = null; 713 for(int y = 0; y < grid.length; y++) 714 { 715 if (isRowNotEmpty[y] || !isRemoveEmptySpace) 716 { 717 JRExporterGridCell[] gridRow = grid[y]; 718 719 int emptyCellColSpan = 0; 720 int emptyCellWidth = 0; 721 int rowHeight = JRGridLayout.getRowHeight(gridRow); 722 723 boolean hasEmptyCell = hasEmptyCell(gridRow); 724 725 writer.write("<tr valign=\"top\""); 726 if (!hasEmptyCell) 727 { 728 writer.write(" style=\"height:" + rowHeight + sizeUnit + "\""); 729 } 730 writer.write(">\n"); 731 732 for(int x = 0; x < gridRow.length; x++) 733 { 734 JRExporterGridCell gridCell = gridRow[x]; 735 if(gridCell.element != null) 736 { 737 if (emptyCellColSpan > 0) 738 { 739 writeEmptyCell(emptyCellColSpan, emptyCellWidth, rowHeight); 740 emptyCellColSpan = 0; 741 emptyCellWidth = 0; 742 } 743 744 element = gridCell.element; 745 746 if (element instanceof JRPrintLine) 747 { 748 exportLine((JRPrintLine)element, gridCell); 749 } 750 else if (element instanceof JRPrintRectangle) 751 { 752 exportRectangle(element, gridCell); 753 } 754 else if (element instanceof JRPrintEllipse) 755 { 756 exportRectangle(element, gridCell); 757 } 758 else if (element instanceof JRPrintImage) 759 { 760 exportImage((JRPrintImage)element, gridCell); 761 } 762 else if (element instanceof JRPrintText) 763 { 764 exportText((JRPrintText)element, gridCell); 765 } 766 else if (element instanceof JRPrintFrame) 767 { 768 exportFrame((JRPrintFrame) element, gridCell); 769 } 770 771 x += gridCell.colSpan - 1; 772 } 773 else 774 { 775 emptyCellColSpan++; 776 emptyCellWidth += gridCell.width; 777 } 778 } 779 780 if (emptyCellColSpan > 0) 781 { 782 writeEmptyCell(emptyCellColSpan, emptyCellWidth, rowHeight); 783 } 784 785 writer.write("</tr>\n"); 786 } 787 } 788 789 if (whitePageBackground) 790 { 791 restoreBackcolor(); 792 } 793 794 writer.write("</table>\n"); 795 } 796 797 798 private boolean hasEmptyCell(JRExporterGridCell[] gridRow) 799 { 800 if (gridRow[0].element == null) { 802 return true; 803 } 804 805 boolean hasEmptyCell = false; 806 for(int x = 1; x < gridRow.length; x++) 807 { 808 if (gridRow[x].element == null) 809 { 810 hasEmptyCell = true; 811 break; 812 } 813 } 814 815 return hasEmptyCell; 816 } 817 818 819 private void writeEmptyCell(int emptyCellColSpan, int emptyCellWidth, int rowHeight) throws IOException 820 { 821 writer.write(" <td"); 822 if (emptyCellColSpan > 1) 823 { 824 writer.write(" colspan=\"" + emptyCellColSpan + "\""); 825 } 826 writer.write(emptyCellStringProvider.getStringForCollapsedTD(imagesURI, emptyCellWidth, rowHeight, sizeUnit) + "</td>\n"); 827 } 828 829 830 833 protected void exportLine(JRPrintLine line, JRExporterGridCell gridCell) throws IOException 834 { 835 writeCellTDStart(gridCell); 836 837 if ( 838 line.getForecolor().getRGB() != Color.white.getRGB() 839 ) 840 { 841 writer.write(" bgcolor=\"#"); 842 String hexa = Integer.toHexString(line.getForecolor().getRGB() & colorMask).toUpperCase(); 843 hexa = ("000000" + hexa).substring(hexa.length()); 844 writer.write(hexa); 845 writer.write("\""); 846 } 847 848 writer.write(">"); 849 850 writer.write(emptyCellStringProvider.getStringForEmptyTD(imagesURI)); 851 852 writer.write("</td>\n"); 853 } 854 855 856 859 protected void writeCellTDStart(JRExporterGridCell gridCell) throws IOException 860 { 861 writer.write(" <td"); 862 if (gridCell.colSpan > 1) 863 { 864 writer.write(" colspan=\"" + gridCell.colSpan +"\""); 865 } 866 if (gridCell.rowSpan > 1) 867 { 868 writer.write(" rowspan=\"" + gridCell.rowSpan + "\""); 869 } 870 } 871 872 873 876 protected void exportRectangle(JRPrintElement element, JRExporterGridCell gridCell) throws IOException 877 { 878 writeCellTDStart(gridCell); 879 880 if ( 881 (backcolor == null || element.getBackcolor().getRGB() != backcolor.getRGB()) 882 && element.getMode() == JRElement.MODE_OPAQUE 883 ) 884 { 885 writer.write(" bgcolor=\"#"); 886 String hexa = Integer.toHexString(element.getBackcolor().getRGB() & colorMask).toUpperCase(); 887 hexa = ("000000" + hexa).substring(hexa.length()); 888 writer.write(hexa); 889 writer.write("\""); 890 } 891 892 writer.write(">"); 893 894 writer.write(emptyCellStringProvider.getStringForEmptyTD(imagesURI)); 895 896 writer.write("</td>\n"); 897 } 898 899 900 903 protected void exportStyledText(JRStyledText styledText) throws IOException 904 { 905 String text = styledText.getText(); 906 907 int runLimit = 0; 908 909 AttributedCharacterIterator iterator = styledText.getAttributedString().getIterator(); 910 911 while(runLimit < styledText.length() && (runLimit = iterator.getRunLimit()) <= styledText.length()) 912 { 913 exportStyledTextRun(iterator.getAttributes(), text.substring(iterator.getIndex(), runLimit)); 914 915 iterator.setIndex(runLimit); 916 } 917 } 918 919 920 923 protected void exportStyledTextRun(Map attributes, String text) throws IOException 924 { 925 String fontFamily; 926 String fontFamilyAttr = (String )attributes.get(TextAttribute.FAMILY); 927 if (fontMap != null && fontMap.containsKey(fontFamilyAttr)) 928 { 929 fontFamily = (String ) fontMap.get(fontFamilyAttr); 930 } 931 else 932 { 933 fontFamily = fontFamilyAttr; 934 } 935 writer.write("<span style=\"font-family: "); 936 writer.write(fontFamily); 937 writer.write("; "); 938 939 Color forecolor = (Color )attributes.get(TextAttribute.FOREGROUND); 940 if (!Color.black.equals(forecolor)) 941 { 942 writer.write("color: #"); 943 String hexa = Integer.toHexString(forecolor.getRGB() & colorMask).toUpperCase(); 944 hexa = ("000000" + hexa).substring(hexa.length()); 945 writer.write(hexa); 946 writer.write("; "); 947 } 948 949 Color runBackcolor = (Color )attributes.get(TextAttribute.BACKGROUND); 950 if (runBackcolor != null) 951 { 952 writer.write("background-color: #"); 953 String hexa = Integer.toHexString(runBackcolor.getRGB() & colorMask).toUpperCase(); 954 hexa = ("000000" + hexa).substring(hexa.length()); 955 writer.write(hexa); 956 writer.write("; "); 957 } 958 959 writer.write("font-size: "); 960 writer.write(String.valueOf(attributes.get(TextAttribute.SIZE))); 961 writer.write(sizeUnit); 962 writer.write(";"); 963 964 972 973 if (TextAttribute.WEIGHT_BOLD.equals(attributes.get(TextAttribute.WEIGHT))) 974 { 975 writer.write(" font-weight: bold;"); 976 } 977 if (TextAttribute.POSTURE_OBLIQUE.equals(attributes.get(TextAttribute.POSTURE))) 978 { 979 writer.write(" font-style: italic;"); 980 } 981 if (TextAttribute.UNDERLINE_ON.equals(attributes.get(TextAttribute.UNDERLINE))) 982 { 983 writer.write(" text-decoration: underline;"); 984 } 985 if (TextAttribute.STRIKETHROUGH_ON.equals(attributes.get(TextAttribute.STRIKETHROUGH))) 986 { 987 writer.write(" text-decoration: line-through;"); 988 } 989 990 if (TextAttribute.SUPERSCRIPT_SUPER.equals(attributes.get(TextAttribute.SUPERSCRIPT))) 991 { 992 writer.write(" vertical-align: super;"); 993 } 994 else if (TextAttribute.SUPERSCRIPT_SUB.equals(attributes.get(TextAttribute.SUPERSCRIPT))) 995 { 996 writer.write(" vertical-align: sub;"); 997 } 998 999 writer.write("\">"); 1000 1001 writer.write( 1002 JRStringUtil.htmlEncode(text) 1003 ); 1004 1005 writer.write("</span>"); 1006 } 1007 1008 1009 1012 protected void exportText(JRPrintText text, JRExporterGridCell gridCell) throws IOException 1013 { 1014 JRStyledText styledText = getStyledText(text); 1015 1016 int textLength = 0; 1017 1018 if (styledText != null) 1019 { 1020 textLength = styledText.length(); 1021 } 1022 1023 writeCellTDStart(gridCell); 1024 1025 String verticalAlignment = HTML_VERTICAL_ALIGN_TOP; 1026 1027 switch (text.getVerticalAlignment()) 1028 { 1029 case JRAlignment.VERTICAL_ALIGN_BOTTOM : 1030 { 1031 verticalAlignment = HTML_VERTICAL_ALIGN_BOTTOM; 1032 break; 1033 } 1034 case JRAlignment.VERTICAL_ALIGN_MIDDLE : 1035 { 1036 verticalAlignment = HTML_VERTICAL_ALIGN_MIDDLE; 1037 break; 1038 } 1039 case JRAlignment.VERTICAL_ALIGN_TOP : 1040 default : 1041 { 1042 verticalAlignment = HTML_VERTICAL_ALIGN_TOP; 1043 } 1044 } 1045 1046 if (!verticalAlignment.equals(HTML_VERTICAL_ALIGN_TOP)) 1047 { 1048 writer.write(" valign=\""); 1049 writer.write(verticalAlignment); 1050 writer.write("\""); 1051 } 1052 1053 if (text.getRunDirection() == JRPrintText.RUN_DIRECTION_RTL) 1054 { 1055 writer.write(" dir=\"rtl\""); 1056 } 1057 1058 StringBuffer styleBuffer = new StringBuffer (); 1059 appendBackcolorStyle(text, styleBuffer); 1060 appendBorderStyle(text, text, styleBuffer); 1061 1062 String horizontalAlignment = CSS_TEXT_ALIGN_LEFT; 1063 1064 if (textLength > 0) 1065 { 1066 switch (text.getHorizontalAlignment()) 1067 { 1068 case JRAlignment.HORIZONTAL_ALIGN_RIGHT : 1069 { 1070 horizontalAlignment = CSS_TEXT_ALIGN_RIGHT; 1071 break; 1072 } 1073 case JRAlignment.HORIZONTAL_ALIGN_CENTER : 1074 { 1075 horizontalAlignment = CSS_TEXT_ALIGN_CENTER; 1076 break; 1077 } 1078 case JRAlignment.HORIZONTAL_ALIGN_JUSTIFIED : 1079 { 1080 horizontalAlignment = CSS_TEXT_ALIGN_JUSTIFY; 1081 break; 1082 } 1083 case JRAlignment.HORIZONTAL_ALIGN_LEFT : 1084 default : 1085 { 1086 horizontalAlignment = CSS_TEXT_ALIGN_LEFT; 1087 } 1088 } 1089 1090 if ( 1091 (text.getRunDirection() == JRPrintText.RUN_DIRECTION_LTR 1092 && !horizontalAlignment.equals(CSS_TEXT_ALIGN_LEFT)) 1093 || (text.getRunDirection() == JRPrintText.RUN_DIRECTION_RTL 1094 && !horizontalAlignment.equals(CSS_TEXT_ALIGN_RIGHT)) 1095 ) 1096 { 1097 styleBuffer.append("text-align: "); 1098 styleBuffer.append(horizontalAlignment); 1099 styleBuffer.append(";"); 1100 } 1101 } 1102 1103 if (isWrapBreakWord) 1104 { 1105 styleBuffer.append("width: " + gridCell.width + sizeUnit + "; "); 1106 styleBuffer.append("word-wrap: break-word; "); 1107 } 1108 1109 if (text.getLineSpacing() != JRTextElement.LINE_SPACING_SINGLE) 1110 { 1111 styleBuffer.append("line-height: " + text.getLineSpacingFactor() + "; "); 1112 } 1113 1114 if (styleBuffer.length() > 0) 1115 { 1116 writer.write(" style=\""); 1117 writer.write(styleBuffer.toString()); 1118 writer.write("\""); 1119 } 1120 1121 writer.write(">"); 1122 1123 if (text.getAnchorName() != null) 1124 { 1125 writer.write("<a name=\""); 1126 writer.write(text.getAnchorName()); 1127 writer.write("\"/>"); 1128 } 1129 1130 boolean startedHyperlink = startHyperlink(text); 1131 1132 if (textLength > 0) 1133 { 1134 exportStyledText(styledText); 1135 } 1136 else 1137 { 1138 writer.write(emptyCellStringProvider.getStringForEmptyTD(imagesURI)); 1139 } 1140 1141 if (startedHyperlink) 1142 { 1143 endHyperlink(); 1144 } 1145 1146 writer.write("</td>\n"); 1147 } 1148 1149 1150 protected boolean startHyperlink(JRPrintHyperlink link) throws IOException 1151 { 1152 String href = getHyperlinkURL(link); 1153 1154 if (href != null) 1155 { 1156 writer.write("<a HREF=\""); 1157 writer.write(href); 1158 writer.write("\""); 1159 1160 String target = getHyperlinkTarget(link); 1161 if (target != null) 1162 { 1163 writer.write(" target=\""); 1164 writer.write(target); 1165 writer.write("\""); 1166 } 1167 1168 if (link.getHyperlinkTooltip() != null) 1169 { 1170 writer.write(" title=\""); 1171 writer.write(JRStringUtil.xmlEncode(link.getHyperlinkTooltip())); 1172 writer.write("\""); 1173 } 1174 1175 writer.write(">"); 1176 } 1177 1178 return href != null; 1179 } 1180 1181 1182 protected String getHyperlinkTarget(JRPrintHyperlink link) 1183 { 1184 String target = null; 1185 switch(link.getHyperlinkTarget()) 1186 { 1187 case JRHyperlink.HYPERLINK_TARGET_BLANK : 1188 { 1189 target = "_blank"; 1190 break; 1191 } 1192 case JRHyperlink.HYPERLINK_TARGET_SELF : 1193 default : 1194 { 1195 break; 1196 } 1197 } 1198 return target; 1199 } 1200 1201 1202 protected String getHyperlinkURL(JRPrintHyperlink link) 1203 { 1204 String href = null; 1205 switch(link.getHyperlinkType()) 1206 { 1207 case JRHyperlink.HYPERLINK_TYPE_REFERENCE : 1208 { 1209 if (link.getHyperlinkReference() != null) 1210 { 1211 href = link.getHyperlinkReference(); 1212 } 1213 break; 1214 } 1215 case JRHyperlink.HYPERLINK_TYPE_LOCAL_ANCHOR : 1216 { 1217 if (link.getHyperlinkAnchor() != null) 1218 { 1219 href = "#" + link.getHyperlinkAnchor(); 1220 } 1221 break; 1222 } 1223 case JRHyperlink.HYPERLINK_TYPE_LOCAL_PAGE : 1224 { 1225 if (link.getHyperlinkPage() != null) 1226 { 1227 href = "#" + JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + link.getHyperlinkPage().toString(); 1228 } 1229 break; 1230 } 1231 case JRHyperlink.HYPERLINK_TYPE_REMOTE_ANCHOR : 1232 { 1233 if ( 1234 link.getHyperlinkReference() != null && 1235 link.getHyperlinkAnchor() != null 1236 ) 1237 { 1238 href = link.getHyperlinkReference() + "#" + link.getHyperlinkAnchor(); 1239 } 1240 break; 1241 } 1242 case JRHyperlink.HYPERLINK_TYPE_REMOTE_PAGE : 1243 { 1244 if ( 1245 link.getHyperlinkReference() != null && 1246 link.getHyperlinkPage() != null 1247 ) 1248 { 1249 href = link.getHyperlinkReference() + "#" + JR_PAGE_ANCHOR_PREFIX + "0_" + link.getHyperlinkPage().toString(); 1250 } 1251 break; 1252 } 1253 case JRHyperlink.HYPERLINK_TYPE_CUSTOM : 1254 { 1255 if (hyperlinkProducerFactory != null) 1256 { 1257 href = hyperlinkProducerFactory.produceHyperlink(link); 1258 } 1259 } 1260 case JRHyperlink.HYPERLINK_TYPE_NONE : 1261 default : 1262 { 1263 break; 1264 } 1265 } 1266 return href; 1267 } 1268 1269 1270 protected void endHyperlink() throws IOException 1271 { 1272 writer.write("</a>"); 1273 } 1274 1275 1276 protected void appendBorderStyle(JRPrintElement element, JRBox box, StringBuffer styleBuffer) 1277 { 1278 if (box != null) 1279 { 1280 appendBorder( 1281 styleBuffer, 1282 box.getTopBorder(), 1283 box.getTopBorderColor() == null ? element.getForecolor() : box.getTopBorderColor(), 1284 box.getTopPadding(), 1285 "top" 1286 ); 1287 appendBorder( 1288 styleBuffer, 1289 box.getLeftBorder(), 1290 box.getLeftBorderColor() == null ? element.getForecolor() : box.getLeftBorderColor(), 1291 box.getLeftPadding(), 1292 "left" 1293 ); 1294 appendBorder( 1295 styleBuffer, 1296 box.getBottomBorder(), 1297 box.getBottomBorderColor() == null ? element.getForecolor() : box.getBottomBorderColor(), 1298 box.getBottomPadding(), 1299 "bottom" 1300 ); 1301 appendBorder( 1302 styleBuffer, 1303 box.getRightBorder(), 1304 box.getRightBorderColor() == null ? element.getForecolor() : box.getRightBorderColor(), 1305 box.getRightPadding(), 1306 "right" 1307 ); 1308 } 1309 } 1310 1311 1312 protected Color appendBackcolorStyle(JRPrintElement element, StringBuffer styleBuffer) 1313 { 1314 if (element.getMode() == JRElement.MODE_OPAQUE && (backcolor == null || element.getBackcolor().getRGB() != backcolor.getRGB())) 1315 { 1316 styleBuffer.append("background-color: #"); 1317 String hexa = Integer.toHexString(element.getBackcolor().getRGB() & colorMask).toUpperCase(); 1318 hexa = ("000000" + hexa).substring(hexa.length()); 1319 styleBuffer.append(hexa); 1320 styleBuffer.append("; "); 1321 1322 return element.getBackcolor(); 1323 } 1324 1325 return null; 1326 } 1327 1328 1329 1332 protected void exportImage(JRPrintImage image, JRExporterGridCell gridCell) throws JRException, IOException 1333 { 1334 writeCellTDStart(gridCell); 1335 1336 String horizontalAlignment = CSS_TEXT_ALIGN_LEFT; 1337 1338 switch (image.getHorizontalAlignment()) 1339 { 1340 case JRAlignment.HORIZONTAL_ALIGN_RIGHT : 1341 { 1342 horizontalAlignment = CSS_TEXT_ALIGN_RIGHT; 1343 break; 1344 } 1345 case JRAlignment.HORIZONTAL_ALIGN_CENTER : 1346 { 1347 horizontalAlignment = CSS_TEXT_ALIGN_CENTER; 1348 break; 1349 } 1350 case JRAlignment.HORIZONTAL_ALIGN_LEFT : 1351 default : 1352 { 1353 horizontalAlignment = CSS_TEXT_ALIGN_LEFT; 1354 } 1355 } 1356 1357 if (!horizontalAlignment.equals(CSS_TEXT_ALIGN_LEFT)) 1358 { 1359 writer.write(" align=\""); 1360 writer.write(horizontalAlignment); 1361 writer.write("\""); 1362 } 1363 1364 String verticalAlignment = HTML_VERTICAL_ALIGN_TOP; 1365 1366 switch (image.getVerticalAlignment()) 1367 { 1368 case JRAlignment.VERTICAL_ALIGN_BOTTOM : 1369 { 1370 verticalAlignment = HTML_VERTICAL_ALIGN_BOTTOM; 1371 break; 1372 } 1373 case JRAlignment.VERTICAL_ALIGN_MIDDLE : 1374 { 1375 verticalAlignment = HTML_VERTICAL_ALIGN_MIDDLE; 1376 break; 1377 } 1378 case JRAlignment.VERTICAL_ALIGN_TOP : 1379 default : 1380 { 1381 verticalAlignment = HTML_VERTICAL_ALIGN_TOP; 1382 } 1383 } 1384 1385 if (!verticalAlignment.equals(HTML_VERTICAL_ALIGN_TOP)) 1386 { 1387 writer.write(" valign=\""); 1388 writer.write(verticalAlignment); 1389 writer.write("\""); 1390 } 1391 1392 StringBuffer styleBuffer = new StringBuffer (); 1393 appendBackcolorStyle(image, styleBuffer); 1394 appendBorderStyle(image, image, styleBuffer); 1395 1396 if (styleBuffer.length() > 0) 1397 { 1398 writer.write(" style=\""); 1399 writer.write(styleBuffer.toString()); 1400 writer.write("\""); 1401 } 1402 1403 writer.write(">"); 1404 1405 if (image.getAnchorName() != null) 1406 { 1407 writer.write("<a name=\""); 1408 writer.write(image.getAnchorName()); 1409 writer.write("\"/>"); 1410 } 1411 1412 JRRenderable renderer = image.getRenderer(); 1413 JRRenderable originalRenderer = renderer; 1414 boolean imageMapRenderer = renderer != null && renderer instanceof JRImageMapRenderer; 1415 1416 boolean startedHyperlink = !imageMapRenderer && startHyperlink(image); 1417 1418 writer.write("<img"); 1419 1420 String imagePath = null; 1421 String imageMapName = null; 1422 List imageMapAreas = null; 1423 1424 byte scaleImage = image.getScaleImage(); 1425 if (renderer != null) 1426 { 1427 if (renderer.getType() == JRRenderable.TYPE_IMAGE && rendererToImagePathMap.containsKey(renderer.getId())) 1428 { 1429 imagePath = (String )rendererToImagePathMap.get(renderer.getId()); 1430 } 1431 else 1432 { 1433 if (image.isLazy()) 1434 { 1435 imagePath = ((JRImageRenderer)renderer).getImageLocation(); 1436 } 1437 else 1438 { 1439 JRPrintElementIndex imageIndex = getElementIndex(gridCell); 1440 imagesToProcess.add(imageIndex); 1441 1442 String imageName = getImageName(imageIndex); 1443 imagePath = imagesURI + imageName; 1444 1445 if (imageNameToImageDataMap != null) 1447 { 1448 if (renderer.getType() == JRRenderable.TYPE_SVG) 1449 { 1450 renderer = 1451 new JRWrappingSvgRenderer( 1452 renderer, 1453 new Dimension (image.getWidth(), image.getHeight()), 1454 JRElement.MODE_OPAQUE == image.getMode() ? image.getBackcolor() : null 1455 ); 1456 } 1457 imageNameToImageDataMap.put(imageName, renderer.getImageData()); 1458 } 1459 } 1461 1462 rendererToImagePathMap.put(renderer.getId(), imagePath); 1463 } 1464 1465 if (imageMapRenderer) 1466 { 1467 Rectangle renderingArea = new Rectangle (image.getWidth(), image.getHeight()); 1468 1469 if (renderer.getType() == JRRenderable.TYPE_IMAGE) 1470 { 1471 imageMapName = (String ) imageMaps.get(new Pair(renderer.getId(), renderingArea)); 1472 } 1473 1474 if (imageMapName == null) 1475 { 1476 imageMapName = "map_" + getElementIndex(gridCell).toString(); 1477 imageMapAreas = ((JRImageMapRenderer) originalRenderer).getImageAreaHyperlinks(renderingArea); 1478 1479 if (renderer.getType() == JRRenderable.TYPE_IMAGE) 1480 { 1481 imageMaps.put(new Pair(renderer.getId(), renderingArea), imageMapName); 1482 } 1483 } 1484 } 1485 } 1486 else 1487 { 1488 loadPxImage(); 1489 imagePath = imagesURI + "px"; 1490 scaleImage = JRImage.SCALE_IMAGE_FILL_FRAME; 1491 } 1492 1493 writer.write(" SRC=\""); 1494 if (imagePath != null) 1495 writer.write(imagePath); 1496 writer.write("\""); 1497 1498 int borderWidth = 0; 1499 switch (image.getPen()) 1500 { 1501 case JRGraphicElement.PEN_DOTTED : 1502 { 1503 borderWidth = 1; 1504 break; 1505 } 1506 case JRGraphicElement.PEN_4_POINT : 1507 { 1508 borderWidth = 4; 1509 break; 1510 } 1511 case JRGraphicElement.PEN_2_POINT : 1512 { 1513 borderWidth = 2; 1514 break; 1515 } 1516 case JRGraphicElement.PEN_NONE : 1517 { 1518 borderWidth = 0; 1519 break; 1520 } 1521 case JRGraphicElement.PEN_THIN : 1522 { 1523 borderWidth = 1; 1524 break; 1525 } 1526 case JRGraphicElement.PEN_1_POINT : 1527 default : 1528 { 1529 borderWidth = 1; 1530 break; 1531 } 1532 } 1533 1534 writer.write(" border=\""); 1535 writer.write(String.valueOf(borderWidth)); 1536 writer.write("\""); 1537 1538 int imageWidth = image.getWidth() - image.getLeftPadding() - image.getRightPadding(); 1539 if (imageWidth < 0) 1540 { 1541 imageWidth = 0; 1542 } 1543 1544 int imageHeight = image.getHeight() - image.getTopPadding() - image.getBottomPadding(); 1545 if (imageHeight < 0) 1546 { 1547 imageHeight = 0; 1548 } 1549 1550 switch (scaleImage) 1551 { 1552 case JRImage.SCALE_IMAGE_FILL_FRAME : 1553 { 1554 writer.write(" style=\"width: "); 1555 writer.write(String.valueOf(imageWidth)); 1556 writer.write(sizeUnit); 1557 writer.write("; height: "); 1558 writer.write(String.valueOf(imageHeight)); 1559 writer.write(sizeUnit); 1560 writer.write("\""); 1561 1562 break; 1563 } 1564 case JRImage.SCALE_IMAGE_CLIP : case JRImage.SCALE_IMAGE_RETAIN_SHAPE : 1566 default : 1567 { 1568 double normalWidth = imageWidth; 1569 double normalHeight = imageHeight; 1570 1571 if (!image.isLazy()) 1572 { 1573 Dimension2D dimension = renderer.getDimension(); 1574 if (dimension != null) 1575 { 1576 normalWidth = dimension.getWidth(); 1577 normalHeight = dimension.getHeight(); 1578 } 1579 } 1580 1581 if (imageHeight > 0) 1582 { 1583 double ratio = normalWidth / normalHeight; 1584 1585 if( ratio > (double)imageWidth / (double)imageHeight ) 1586 { 1587 writer.write(" style=\"width: "); 1588 writer.write(String.valueOf(imageWidth)); 1589 writer.write(sizeUnit); 1590 writer.write("\""); 1591 } 1592 else 1593 { 1594 writer.write(" style=\"height: "); 1595 writer.write(String.valueOf(imageHeight)); 1596 writer.write(sizeUnit); 1597 writer.write("\""); 1598 } 1599 } 1600 } 1601 } 1602 1603 if (imageMapName != null) 1604 { 1605 writer.write(" usemap=\"#" + imageMapName + "\""); 1606 } 1607 1608 writer.write(" alt=\"\"/>"); 1609 1610 if (startedHyperlink) 1611 { 1612 endHyperlink(); 1613 } 1614 1615 if (imageMapAreas != null) 1616 { 1617 writer.write("\n"); 1618 writeImageMap(imageMapName, image, imageMapAreas); 1619 } 1620 1621 writer.write("</td>\n"); 1622 } 1623 1624 1625 protected JRPrintElementIndex getElementIndex(JRExporterGridCell gridCell) 1626 { 1627 JRPrintElementIndex imageIndex = 1628 new JRPrintElementIndex( 1629 reportIndex, 1630 pageIndex, 1631 gridCell.elementIndex 1632 ); 1633 return imageIndex; 1634 } 1635 1636 1637 protected void writeImageMap(String imageMapName, JRPrintHyperlink mainHyperlink, List imageMapAreas) throws IOException 1638 { 1639 writer.write("<map name=\"" + imageMapName + "\">\n"); 1640 1641 for (Iterator it = imageMapAreas.iterator(); it.hasNext();) 1642 { 1643 JRPrintImageAreaHyperlink areaHyperlink = (JRPrintImageAreaHyperlink) it.next(); 1644 JRPrintImageArea area = areaHyperlink.getArea(); 1645 1646 writer.write(" <area shape=\"" + JRPrintImageArea.getHtmlShape(area.getShape()) + "\""); 1647 writeImageAreaCoordinates(area); 1648 writeImageAreaHyperlink(areaHyperlink.getHyperlink()); 1649 writer.write("/>\n"); 1650 } 1651 1652 if (mainHyperlink.getHyperlinkType() != JRHyperlink.HYPERLINK_TYPE_NONE) 1653 { 1654 writer.write(" <area shape=\"default\""); 1655 writeImageAreaHyperlink(mainHyperlink); 1656 writer.write("/>\n"); 1657 } 1658 1659 writer.write("</map>\n"); 1660 } 1661 1662 1663 protected void writeImageAreaCoordinates(JRPrintImageArea area) throws IOException 1664 { 1665 int[] coords = area.getCoordinates(); 1666 if (coords != null && coords.length > 0) 1667 { 1668 StringBuffer coordsEnum = new StringBuffer (coords.length * 4); 1669 coordsEnum.append(coords[0]); 1670 for (int i = 1; i < coords.length; i++) 1671 { 1672 coordsEnum.append(','); 1673 coordsEnum.append(coords[i]); 1674 } 1675 1676 writer.write(" coords=\"" + coordsEnum + "\""); 1677 } 1678 } 1679 1680 1681 protected void writeImageAreaHyperlink(JRPrintHyperlink hyperlink) throws IOException 1682 { 1683 String href = getHyperlinkURL(hyperlink); 1684 if (href == null) 1685 { 1686 writer.write(" nohref=\"nohref\""); 1687 } 1688 else 1689 { 1690 writer.write(" HREF=\"" + href + "\""); 1691 1692 String target = getHyperlinkTarget(hyperlink); 1693 if (target != null) 1694 { 1695 writer.write(" target=\""); 1696 writer.write(target); 1697 writer.write("\""); 1698 } 1699 } 1700 1701 if (hyperlink.getHyperlinkTooltip() != null) 1702 { 1703 writer.write(" title=\""); 1704 writer.write(JRStringUtil.xmlEncode(hyperlink.getHyperlinkTooltip())); 1705 writer.write("\""); 1706 } 1707 } 1708 1709 1710 protected JRGridLayout getPageGridLayout(JRPrintPage page) 1711 { 1712 JRGridLayout layout = new JRGridLayout(page.getElements(), null, 1713 jasperPrint.getPageWidth(), jasperPrint.getPageHeight(), 1714 globalOffsetX, globalOffsetY, JRGridLayout.UNIVERSAL_EXPORTER, false, true, true, null); 1715 return layout; 1716 } 1717 1718 1719 1722 protected void loadPxImage() throws JRException 1723 { 1724 isPxImageLoaded = true; 1725 if (imageNameToImageDataMap != null && !imageNameToImageDataMap.containsKey("px")) 1727 { 1728 JRRenderable pxRenderer = 1729 JRImageRenderer.getInstance( 1730 "net/sf/jasperreports/engine/images/pixel.GIF", 1731 JRImage.ON_ERROR_TYPE_ERROR 1732 ); 1733 rendererToImagePathMap.put(pxRenderer.getId(), imagesURI + "px"); 1734 imageNameToImageDataMap.put("px", pxRenderer.getImageData()); 1735 } 1736 } 1738 1739 1740 1743 protected static interface StringProvider 1744 { 1745 1746 1749 public String getStringForCollapsedTD(Object value, int width, int height, String sizeUnit); 1750 1751 1754 public String getStringForEmptyTD(Object value); 1755 1756 } 1757 1758 1759 1762 private void appendBorder(StringBuffer sb, byte pen, Color borderColor, int padding, String side) 1763 { 1764 String borderStyle = null; 1765 String borderWidth = null; 1766 1767 switch (pen) 1768 { 1769 case JRGraphicElement.PEN_DOTTED : 1770 { 1771 borderStyle = "dashed"; 1772 borderWidth = "1"; 1773 break; 1774 } 1775 case JRGraphicElement.PEN_4_POINT : 1776 { 1777 borderStyle = "solid"; 1778 borderWidth = "4"; 1779 break; 1780 } 1781 case JRGraphicElement.PEN_2_POINT : 1782 { 1783 borderStyle = "solid"; 1784 borderWidth = "2"; 1785 break; 1786 } 1787 case JRGraphicElement.PEN_THIN : 1788 { 1789 borderStyle = "solid"; 1790 borderWidth = "1"; 1791 break; 1792 } 1793 case JRGraphicElement.PEN_NONE : 1794 { 1795 break; 1796 } 1797 case JRGraphicElement.PEN_1_POINT : 1798 default : 1799 { 1800 borderStyle = "solid"; 1801 borderWidth = "1"; 1802 break; 1803 } 1804 } 1805 1806 if (borderWidth != null) 1807 { 1808 sb.append("border-"); 1809 sb.append(side); 1810 sb.append("-style: "); 1811 sb.append(borderStyle); 1812 sb.append("; "); 1813 1814 sb.append("border-"); 1815 sb.append(side); 1816 sb.append("-width: "); 1817 sb.append(borderWidth); 1818 sb.append(sizeUnit); 1819 sb.append("; "); 1820 1821 sb.append("border-"); 1822 sb.append(side); 1823 sb.append("-color: #"); 1824 String hexa = Integer.toHexString(borderColor.getRGB() & colorMask).toUpperCase(); 1825 hexa = ("000000" + hexa).substring(hexa.length()); 1826 sb.append(hexa); 1827 sb.append("; "); 1828 } 1829 1830 if (padding > 0) 1831 { 1832 sb.append("padding-"); 1833 sb.append(side); 1834 sb.append(": "); 1835 sb.append(padding); 1836 sb.append(sizeUnit); 1837 sb.append("; "); 1838 } 1839 } 1840 1841 1842 1845 public static String getImageName(JRPrintElementIndex printElementIndex) 1846 { 1847 return IMAGE_NAME_PREFIX + printElementIndex.toString(); 1848 } 1849 1850 1851 1854 public static JRPrintElementIndex getPrintElementIndex(String imageName) 1855 { 1856 if (!imageName.startsWith(IMAGE_NAME_PREFIX)) 1857 { 1858 throw new JRRuntimeException("Invalid image name: " + imageName); 1859 } 1860 1861 return JRPrintElementIndex.parsePrintElementIndex(imageName.substring(IMAGE_NAME_PREFIX_LEGTH)); 1862 } 1863 1864 1865 protected void exportFrame(JRPrintFrame frame, JRExporterGridCell gridCell) throws IOException , JRException 1866 { 1867 writeCellTDStart(gridCell); 1868 1869 StringBuffer styleBuffer = new StringBuffer (); 1870 Color frameBackcolor = appendBackcolorStyle(frame, styleBuffer); 1871 appendBorderStyle(frame, frame, styleBuffer); 1872 1873 if (styleBuffer.length() > 0) 1874 { 1875 writer.write(" style=\""); 1876 writer.write(styleBuffer.toString()); 1877 writer.write("\""); 1878 } 1879 1880 writer.write(">\n"); 1881 1882 if (frameBackcolor != null) 1883 { 1884 setBackcolor(frameBackcolor); 1885 } 1886 try 1887 { 1888 JRGridLayout layout = new JRGridLayout(frame.getElements(), null, frame.getWidth(), frame.getHeight(), 0, 0, JRGridLayout.UNIVERSAL_EXPORTER, false, true, true, gridCell.elementIndex); 1889 exportGrid(layout, false); 1890 } 1891 finally 1892 { 1893 if (frameBackcolor != null) 1894 { 1895 restoreBackcolor(); 1896 } 1897 } 1898 1899 writer.write("</td>\n"); 1900 } 1901 1902 1903 protected void setBackcolor(Color color) 1904 { 1905 backcolorStack.addLast(backcolor); 1906 1907 backcolor = color; 1908 } 1909 1910 1911 protected void restoreBackcolor() 1912 { 1913 backcolor = (Color ) backcolorStack.removeLast(); 1914 } 1915 1916} 1917 1918 | Popular Tags |