1 50 51 package com.lowagie.text.pdf; 52 53 import java.util.ArrayList ; 54 55 import com.lowagie.text.DocumentException; 56 import com.lowagie.text.Element; 57 import com.lowagie.text.ElementListener; 58 import com.lowagie.text.Image; 59 import com.lowagie.text.Phrase; 60 import com.lowagie.text.Rectangle; 61 import com.lowagie.text.pdf.events.PdfPTableEventForwarder; 62 63 72 73 public class PdfPTable implements Element{ 74 75 77 public static final int BASECANVAS = 0; 78 80 public static final int BACKGROUNDCANVAS = 1; 81 83 public static final int LINECANVAS = 2; 84 86 public static final int TEXTCANVAS = 3; 87 88 protected ArrayList rows = new ArrayList (); 89 protected float totalHeight = 0; 90 protected PdfPCell currentRow[]; 91 protected int currentRowIdx = 0; 92 protected PdfPCell defaultCell = new PdfPCell((Phrase)null); 93 protected float totalWidth = 0; 94 protected float relativeWidths[]; 95 protected float absoluteWidths[]; 96 protected PdfPTableEvent tableEvent; 97 98 99 protected int headerRows; 100 101 102 protected float widthPercentage = 80; 103 104 105 private int horizontalAlignment = Element.ALIGN_CENTER; 106 107 108 private boolean skipFirstHeader = false; 109 110 protected boolean isColspan = false; 111 112 protected int runDirection = PdfWriter.RUN_DIRECTION_DEFAULT; 113 114 117 private boolean lockedWidth = false; 118 119 122 private boolean splitRows = true; 123 124 125 protected float spacingBefore; 126 127 128 protected float spacingAfter; 129 130 133 private boolean extendLastRow; 134 135 138 private boolean headersInEvent; 139 140 143 private boolean splitLate = true; 144 145 149 private boolean keepTogether; 150 151 154 private int footerRows; 155 156 protected PdfPTable() { 157 } 158 159 162 public PdfPTable(float relativeWidths[]) { 163 if (relativeWidths == null) 164 throw new NullPointerException ("The widths array in PdfPTable constructor can not be null."); 165 if (relativeWidths.length == 0) 166 throw new IllegalArgumentException ("The widths array in PdfPTable constructor can not have zero length."); 167 this.relativeWidths = new float[relativeWidths.length]; 168 System.arraycopy(relativeWidths, 0, this.relativeWidths, 0, relativeWidths.length); 169 absoluteWidths = new float[relativeWidths.length]; 170 calculateWidths(); 171 currentRow = new PdfPCell[absoluteWidths.length]; 172 keepTogether = false; 173 } 174 175 178 public PdfPTable(int numColumns) { 179 if (numColumns <= 0) 180 throw new IllegalArgumentException ("The number of columns in PdfPTable constructor must be greater than zero."); 181 relativeWidths = new float[numColumns]; 182 for (int k = 0; k < numColumns; ++k) 183 relativeWidths[k] = 1; 184 absoluteWidths = new float[relativeWidths.length]; 185 calculateWidths(); 186 currentRow = new PdfPCell[absoluteWidths.length]; 187 keepTogether = false; 188 } 189 190 193 public PdfPTable(PdfPTable table) { 194 copyFormat(table); 195 for (int k = 0; k < currentRow.length; ++k) { 196 if (table.currentRow[k] == null) 197 break; 198 currentRow[k] = new PdfPCell(table.currentRow[k]); 199 } 200 for (int k = 0; k < table.rows.size(); ++k) { 201 PdfPRow row = (PdfPRow)(table.rows.get(k)); 202 if (row != null) 203 row = new PdfPRow(row); 204 rows.add(row); 205 } 206 } 207 208 213 public static PdfPTable shallowCopy(PdfPTable table) { 214 PdfPTable nt = new PdfPTable(); 215 nt.copyFormat(table); 216 return nt; 217 } 218 219 223 private void copyFormat(PdfPTable sourceTable) { 224 relativeWidths = new float[sourceTable.relativeWidths.length]; 225 absoluteWidths = new float[sourceTable.relativeWidths.length]; 226 System.arraycopy(sourceTable.relativeWidths, 0, relativeWidths, 0, relativeWidths.length); 227 System.arraycopy(sourceTable.absoluteWidths, 0, absoluteWidths, 0, relativeWidths.length); 228 totalWidth = sourceTable.totalWidth; 229 totalHeight = sourceTable.totalHeight; 230 currentRowIdx = 0; 231 tableEvent = sourceTable.tableEvent; 232 runDirection = sourceTable.runDirection; 233 defaultCell = new PdfPCell(sourceTable.defaultCell); 234 currentRow = new PdfPCell[sourceTable.currentRow.length]; 235 isColspan = sourceTable.isColspan; 236 splitRows = sourceTable.splitRows; 237 spacingAfter = sourceTable.spacingAfter; 238 spacingBefore = sourceTable.spacingBefore; 239 headerRows = sourceTable.headerRows; 240 footerRows = sourceTable.footerRows; 241 lockedWidth = sourceTable.lockedWidth; 242 extendLastRow = sourceTable.extendLastRow; 243 headersInEvent = sourceTable.headersInEvent; 244 widthPercentage = sourceTable.widthPercentage; 245 splitLate = sourceTable.splitLate; 246 skipFirstHeader = sourceTable.skipFirstHeader; 247 horizontalAlignment = sourceTable.horizontalAlignment; 248 keepTogether = sourceTable.keepTogether; 249 } 250 251 256 public void setWidths(float relativeWidths[]) throws DocumentException { 257 if (relativeWidths.length != this.relativeWidths.length) 258 throw new DocumentException("Wrong number of columns."); 259 this.relativeWidths = new float[relativeWidths.length]; 260 System.arraycopy(relativeWidths, 0, this.relativeWidths, 0, relativeWidths.length); 261 absoluteWidths = new float[relativeWidths.length]; 262 totalHeight = 0; 263 calculateWidths(); 264 calculateHeights(); 265 } 266 267 272 public void setWidths(int relativeWidths[]) throws DocumentException { 273 float tb[] = new float[relativeWidths.length]; 274 for (int k = 0; k < relativeWidths.length; ++k) 275 tb[k] = relativeWidths[k]; 276 setWidths(tb); 277 } 278 279 private void calculateWidths() { 280 if (totalWidth <= 0) 281 return; 282 float total = 0; 283 for (int k = 0; k < absoluteWidths.length; ++k) { 284 total += relativeWidths[k]; 285 } 286 for (int k = 0; k < absoluteWidths.length; ++k) { 287 absoluteWidths[k] = totalWidth * relativeWidths[k] / total; 288 } 289 } 290 291 294 public void setTotalWidth(float totalWidth) { 295 if (this.totalWidth == totalWidth) 296 return; 297 this.totalWidth = totalWidth; 298 totalHeight = 0; 299 calculateWidths(); 300 calculateHeights(); 301 } 302 303 308 public void setTotalWidth(float columnWidth[]) throws DocumentException { 309 if (columnWidth.length != this.relativeWidths.length) 310 throw new DocumentException("Wrong number of columns."); 311 totalWidth = 0; 312 for (int k = 0; k < columnWidth.length; ++k) 313 totalWidth += columnWidth[k]; 314 setWidths(columnWidth); 315 } 316 317 322 public void setWidthPercentage(float columnWidth[], Rectangle pageSize) throws DocumentException { 323 if (columnWidth.length != this.relativeWidths.length) 324 throw new IllegalArgumentException ("Wrong number of columns."); 325 float totalWidth = 0; 326 for (int k = 0; k < columnWidth.length; ++k) 327 totalWidth += columnWidth[k]; 328 widthPercentage = totalWidth / (pageSize.getRight() - pageSize.getLeft()) * 100f; 329 setWidths(columnWidth); 330 } 331 332 335 public float getTotalWidth() { 336 return totalWidth; 337 } 338 339 void calculateHeights() { 340 if (totalWidth <= 0) 341 return; 342 totalHeight = 0; 343 for (int k = 0; k < rows.size(); ++k) { 344 PdfPRow row = (PdfPRow)rows.get(k); 345 if (row != null) { 346 row.setWidths(absoluteWidths); 347 totalHeight += row.getMaxHeights(); 348 } 349 } 350 } 351 352 355 public void calculateHeightsFast() { 356 if (totalWidth <= 0) 357 return; 358 totalHeight = 0; 359 for (int k = 0; k < rows.size(); ++k) { 360 PdfPRow row = (PdfPRow)rows.get(k); 361 if (row != null) 362 totalHeight += row.getMaxHeights(); 363 } 364 } 365 366 371 public PdfPCell getDefaultCell() { 372 return defaultCell; 373 } 374 375 378 public void addCell(PdfPCell cell) { 379 PdfPCell ncell = new PdfPCell(cell); 380 int colspan = ncell.getColspan(); 381 colspan = Math.max(colspan, 1); 382 colspan = Math.min(colspan, currentRow.length - currentRowIdx); 383 ncell.setColspan(colspan); 384 if (colspan != 1) 385 isColspan = true; 386 int rdir = ncell.getRunDirection(); 387 if (rdir == PdfWriter.RUN_DIRECTION_DEFAULT) 388 ncell.setRunDirection(runDirection); 389 currentRow[currentRowIdx] = ncell; 390 currentRowIdx += colspan; 391 if (currentRowIdx >= currentRow.length) { 392 if (runDirection == PdfWriter.RUN_DIRECTION_RTL) { 393 PdfPCell rtlRow[] = new PdfPCell[absoluteWidths.length]; 394 int rev = currentRow.length; 395 for (int k = 0; k < currentRow.length; ++k) { 396 PdfPCell rcell = currentRow[k]; 397 int cspan = rcell.getColspan(); 398 rev -= cspan; 399 rtlRow[rev] = rcell; 400 k += cspan - 1; 401 } 402 currentRow = rtlRow; 403 } 404 PdfPRow row = new PdfPRow(currentRow); 405 if (totalWidth > 0) { 406 row.setWidths(absoluteWidths); 407 totalHeight += row.getMaxHeights(); 408 } 409 rows.add(row); 410 currentRow = new PdfPCell[absoluteWidths.length]; 411 currentRowIdx = 0; 412 } 413 } 414 415 418 public void addCell(String text) { 419 addCell(new Phrase(text)); 420 } 421 422 426 public void addCell(PdfPTable table) { 427 defaultCell.setTable(table); 428 addCell(defaultCell); 429 defaultCell.setTable(null); 430 } 431 432 436 public void addCell(Image image) { 437 defaultCell.setImage(image); 438 addCell(defaultCell); 439 defaultCell.setImage(null); 440 } 441 442 446 public void addCell(Phrase phrase) { 447 defaultCell.setPhrase(phrase); 448 addCell(defaultCell); 449 defaultCell.setPhrase(null); 450 } 451 452 466 public float writeSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte[] canvases) { 467 return writeSelectedRows(0, -1, rowStart, rowEnd, xPos, yPos, canvases); 468 } 469 470 490 public float writeSelectedRows(int colStart, int colEnd, int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte[] canvases) { 491 if (totalWidth <= 0) 492 throw new RuntimeException ("The table width must be greater than zero."); 493 int size = rows.size(); 494 if (rowEnd < 0) 495 rowEnd = size; 496 rowEnd = Math.min(rowEnd, size); 497 if (rowStart < 0) 498 rowStart = 0; 499 if (rowStart >= rowEnd) 500 return yPos; 501 if (colEnd < 0) 502 colEnd = absoluteWidths.length; 503 colEnd = Math.min(colEnd, absoluteWidths.length); 504 if (colStart < 0) 505 colStart = 0; 506 colStart = Math.min(colStart, absoluteWidths.length); 507 float yPosStart = yPos; 508 for (int k = rowStart; k < rowEnd; ++k) { 509 PdfPRow row = (PdfPRow)rows.get(k); 510 if (row != null) { 511 row.writeCells(colStart, colEnd, xPos, yPos, canvases); 512 yPos -= row.getMaxHeights(); 513 } 514 } 515 if (tableEvent != null && colStart == 0 && colEnd == absoluteWidths.length) { 516 float heights[] = new float[rowEnd - rowStart + 1]; 517 heights[0] = yPosStart; 518 for (int k = rowStart; k < rowEnd; ++k) { 519 PdfPRow row = (PdfPRow)rows.get(k); 520 float hr = 0; 521 if (row != null) 522 hr = row.getMaxHeights(); 523 heights[k - rowStart + 1] = heights[k - rowStart] - hr; 524 } 525 tableEvent.tableLayout(this, getEventWidths(xPos, rowStart, rowEnd, headersInEvent), heights, headersInEvent ? headerRows : 0, rowStart, canvases); 526 } 527 return yPos; 528 } 529 530 542 public float writeSelectedRows(int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas) { 543 return writeSelectedRows(0, -1, rowStart, rowEnd, xPos, yPos, canvas); 544 } 545 546 564 public float writeSelectedRows(int colStart, int colEnd, int rowStart, int rowEnd, float xPos, float yPos, PdfContentByte canvas) { 565 if (colEnd < 0) 566 colEnd = absoluteWidths.length; 567 colEnd = Math.min(colEnd, absoluteWidths.length); 568 if (colStart < 0) 569 colStart = 0; 570 colStart = Math.min(colStart, absoluteWidths.length); 571 if (colStart != 0 || colEnd != absoluteWidths.length) { 572 float w = 0; 573 for (int k = colStart; k < colEnd; ++k) 574 w += absoluteWidths[k]; 575 canvas.saveState(); 576 float lx = 0; 577 float rx = 0; 578 if (colStart == 0) 579 lx = 10000; 580 if (colEnd == absoluteWidths.length) 581 rx = 10000; 582 canvas.rectangle(xPos - lx, -10000, w + lx + rx, 20000); 583 canvas.clip(); 584 canvas.newPath(); 585 } 586 PdfContentByte[] canvases = beginWritingRows(canvas); 587 float y = writeSelectedRows(colStart, colEnd, rowStart, rowEnd, xPos, yPos, canvases); 588 endWritingRows(canvases); 589 if (colStart != 0 || colEnd != absoluteWidths.length) 590 canvas.restoreState(); 591 return y; 592 } 593 594 610 public static PdfContentByte[] beginWritingRows(PdfContentByte canvas) { 611 return new PdfContentByte[]{ 612 canvas, 613 canvas.getDuplicate(), 614 canvas.getDuplicate(), 615 canvas.getDuplicate(), 616 }; 617 } 618 619 622 public static void endWritingRows(PdfContentByte[] canvases) { 623 PdfContentByte canvas = canvases[BASECANVAS]; 624 canvas.saveState(); 625 canvas.add(canvases[BACKGROUNDCANVAS]); 626 canvas.restoreState(); 627 canvas.saveState(); 628 canvas.setLineCap(2); 629 canvas.resetRGBColorStroke(); 630 canvas.add(canvases[LINECANVAS]); 631 canvas.restoreState(); 632 canvas.add(canvases[TEXTCANVAS]); 633 } 634 635 638 public int size() { 639 return rows.size(); 640 } 641 642 645 public float getTotalHeight() { 646 return totalHeight; 647 } 648 649 653 public float getRowHeight(int idx) { 654 if (totalWidth <= 0 || idx < 0 || idx >= rows.size()) 655 return 0; 656 PdfPRow row = (PdfPRow)rows.get(idx); 657 if (row == null) 658 return 0; 659 return row.getMaxHeights(); 660 } 661 662 666 public float getHeaderHeight() { 667 float total = 0; 668 int size = Math.min(rows.size(), headerRows); 669 for (int k = 0; k < size; ++k) { 670 PdfPRow row = (PdfPRow)rows.get(k); 671 if (row != null) 672 total += row.getMaxHeights(); 673 } 674 return total; 675 } 676 677 681 public boolean deleteRow(int rowNumber) { 682 if (rowNumber < 0 || rowNumber >= rows.size()) { 683 return false; 684 } 685 if (totalWidth > 0) { 686 PdfPRow row = (PdfPRow)rows.get(rowNumber); 687 if (row != null) 688 totalHeight -= row.getMaxHeights(); 689 } 690 rows.remove(rowNumber); 691 return true; 692 } 693 694 697 public boolean deleteLastRow() { 698 return deleteRow(rows.size() - 1); 699 } 700 701 704 public void deleteBodyRows() { 705 ArrayList rows2 = new ArrayList (); 706 for (int k = 0; k < headerRows; ++k) 707 rows2.add(rows.get(k)); 708 rows = rows2; 709 totalHeight = 0; 710 if (totalWidth > 0) 711 totalHeight = getHeaderHeight(); 712 } 713 714 717 public int getHeaderRows() { 718 return headerRows; 719 } 720 721 726 public void setHeaderRows(int headerRows) { 727 if (headerRows < 0) 728 headerRows = 0; 729 this.headerRows = headerRows; 730 } 731 732 737 public ArrayList getChunks() { 738 return new ArrayList (); 739 } 740 741 746 public int type() { 747 return Element.PTABLE; 748 } 749 750 757 public boolean process(ElementListener listener) { 758 try { 759 return listener.add(this); 760 } 761 catch(DocumentException de) { 762 return false; 763 } 764 } 765 766 769 public float getWidthPercentage() { 770 return widthPercentage; 771 } 772 773 776 public void setWidthPercentage(float widthPercentage) { 777 this.widthPercentage = widthPercentage; 778 } 779 780 783 public int getHorizontalAlignment() { 784 return horizontalAlignment; 785 } 786 787 792 public void setHorizontalAlignment(int horizontalAlignment) { 793 this.horizontalAlignment = horizontalAlignment; 794 } 795 796 802 public PdfPRow getRow(int idx) { 803 return (PdfPRow)rows.get(idx); 804 } 805 806 810 public ArrayList getRows() { 811 return rows; 812 } 813 814 817 public void setTableEvent(PdfPTableEvent event) { 818 if (event == null) this.tableEvent = null; 819 else if (this.tableEvent == null) this.tableEvent = event; 820 else if (this.tableEvent instanceof PdfPTableEventForwarder) ((PdfPTableEventForwarder)this.tableEvent).addTableEvent(event); 821 else { 822 PdfPTableEventForwarder forward = new PdfPTableEventForwarder(); 823 forward.addTableEvent(this.tableEvent); 824 forward.addTableEvent(event); 825 this.tableEvent = forward; 826 } 827 } 828 829 832 public PdfPTableEvent getTableEvent() { 833 return tableEvent; 834 } 835 836 839 public float[] getAbsoluteWidths() { 840 return absoluteWidths; 841 } 842 843 float [][] getEventWidths(float xPos, int firstRow, int lastRow, boolean includeHeaders) { 844 if (includeHeaders) { 845 firstRow = Math.max(firstRow, headerRows); 846 lastRow = Math.max(lastRow, headerRows); 847 } 848 float widths[][] = new float[(includeHeaders ? headerRows : 0) + lastRow - firstRow][]; 849 if (isColspan) { 850 int n = 0; 851 if (includeHeaders) { 852 for (int k = 0; k < headerRows; ++k) { 853 PdfPRow row = (PdfPRow)rows.get(k); 854 if (row == null) 855 ++n; 856 else 857 widths[n++] = row.getEventWidth(xPos); 858 } 859 } 860 for (; firstRow < lastRow; ++firstRow) { 861 PdfPRow row = (PdfPRow)rows.get(firstRow); 862 if (row == null) 863 ++n; 864 else 865 widths[n++] = row.getEventWidth(xPos); 866 } 867 } 868 else { 869 float width[] = new float[absoluteWidths.length + 1]; 870 width[0] = xPos; 871 for (int k = 0; k < absoluteWidths.length; ++k) 872 width[k + 1] = width[k] + absoluteWidths[k]; 873 for (int k = 0; k < widths.length; ++k) 874 widths[k] = width; 875 } 876 return widths; 877 } 878 879 880 883 public boolean isSkipFirstHeader() { 884 return skipFirstHeader; 885 } 886 887 891 public void setSkipFirstHeader(boolean skipFirstHeader) { 892 this.skipFirstHeader = skipFirstHeader; 893 } 894 895 899 public void setRunDirection(int runDirection) { 900 if (runDirection < PdfWriter.RUN_DIRECTION_DEFAULT || runDirection > PdfWriter.RUN_DIRECTION_RTL) 901 throw new RuntimeException ("Invalid run direction: " + runDirection); 902 this.runDirection = runDirection; 903 } 904 905 909 public int getRunDirection() { 910 return runDirection; 911 } 912 913 917 public boolean isLockedWidth() { 918 return this.lockedWidth; 919 } 920 921 925 public void setLockedWidth(boolean lockedWidth) { 926 this.lockedWidth = lockedWidth; 927 } 928 929 933 public boolean isSplitRows() { 934 return this.splitRows; 935 } 936 937 943 public void setSplitRows(boolean splitRows) { 944 this.splitRows = splitRows; 945 } 946 947 952 953 public void setSpacingBefore(float spacing) { 954 this.spacingBefore = spacing; 955 } 956 957 962 963 public void setSpacingAfter(float spacing) { 964 this.spacingAfter = spacing; 965 } 966 967 972 973 public float spacingBefore() { 974 return spacingBefore; 975 } 976 977 982 983 public float spacingAfter() { 984 return spacingAfter; 985 } 986 987 991 public boolean isExtendLastRow() { 992 return this.extendLastRow; 993 } 994 995 1000 public void setExtendLastRow(boolean extendLastRow) { 1001 this.extendLastRow = extendLastRow; 1002 } 1003 1004 1008 public boolean isHeadersInEvent() { 1009 return this.headersInEvent; 1010 } 1011 1012 1016 public void setHeadersInEvent(boolean headersInEvent) { 1017 this.headersInEvent = headersInEvent; 1018 } 1019 1020 1024 public boolean isSplitLate() { 1025 return this.splitLate; 1026 } 1027 1028 1035 public void setSplitLate(boolean splitLate) { 1036 this.splitLate = splitLate; 1037 } 1038 1039 1046 public void setKeepTogether(boolean p_KeepTogether) { 1047 keepTogether = p_KeepTogether; 1048 } 1049 1050 public boolean getKeepTogether() { 1051 return keepTogether; 1052 } 1053 1054 1058 public int getFooterRows() { 1059 return this.footerRows; 1060 } 1061 1062 1076 public void setFooterRows(int footerRows) { 1077 if (footerRows < 0) 1078 footerRows = 0; 1079 this.footerRows = footerRows; 1080 } 1081 1082} | Popular Tags |