1: <?php
2:
3: /**
4: * mc_table.php
5: *
6: * @category PDF
7: * @package PDF_MC
8: * @author Olivier <olivier@fpdf.org>
9: * @author Henri Schumacher <henri.hulski@gazeta.pl>
10: * @link http://fpdf.de/downloads/addons/3/
11: * @see FPDF
12: */
13:
14: require('fpdf.php');
15:
16: /**
17: * The PDF_MC_Table class extends FPDF for creating tables with MultiCells.
18: *
19: * The goal of this class is to build a table from MultiCells.
20: * As MultiCells go to the next line after being output, the base idea consists in saving the current position,
21: * printing the MultiCell and resetting the position to its right.
22: * There is a difficulty, however, if the table is too long: page breaks.
23: * Before outputting a row, it is necessary to know whether it will cause a break or not.
24: * If it does overflow, a manual page break must be done first.
25: * To do so, the height of the row must be known in advance; it is the maximum of the heights of the MultiCells it is made up of.
26: * To know the height of a MultiCell, the NbLines() method is used: it returns the number of lines a MultiCell will occupy.
27: *
28: * @category PDF
29: * @package PDF_MC
30: * @author Olivier <olivier@fpdf.org>
31: * @author Henri Schumacher <henri.hulski@gazeta.pl>
32: */
33: class PDF_MC_Table extends FPDF {
34:
35: /**
36: * The array of column widths
37: * @var array
38: * @access public
39: */
40: public $widths;
41:
42: /**
43: * The array of column alignments or one alignment for all columns
44: * @var array|string
45: * @access public
46: */
47: public $aligns;
48:
49: /**
50: * The cell height
51: * @var number
52: * @access public
53: */
54: public $cell_height = 6;
55:
56: /**
57: * True if the table row should be colored
58: * @var boolean
59: * @access public
60: */
61: public $fill = false;
62:
63: /**
64: * The page number
65: * @var integer
66: * @access public
67: */
68: public $table_page = 1;
69:
70: /**
71: * Set the array of column widths
72: *
73: * @param array $w column widths array
74: * @return void
75: * @access public
76: */
77: function SetWidths($w) {
78: $this->widths=$w;
79: }
80:
81: /**
82: * Set the array of column alignments or one alignment for all columns
83: *
84: * @param array|string $a column alignments array or one alignment for all columns
85: * @return void
86: * @access public
87: */
88: function SetAligns($a) {
89: $this->aligns=$a;
90: }
91:
92: /**
93: * Set the cell height
94: *
95: * @param number $ch cell height
96: * @return void
97: * @access public
98: */
99: function SetCellHeight($ch) {
100: $this->cell_height=$ch;
101: }
102:
103: /**
104: * Set if the row should be colored
105: *
106: * @param boolean $f true if the table row should be colored
107: * @return void
108: * @access public
109: */
110: function SetFill($f) {
111: $this->fill=$f;
112: }
113:
114: /**
115: * Print a row if no page break is needed
116: *
117: * @param array $data contains the row data
118: * @return boolean true if success, false if page break is needed
119: * @access public
120: */
121: function Row($data) {
122: // Calculate the height of the row
123: $nb=0;
124: for ($i=0;$i<count($data);$i++) {
125: $nb=max($nb,$this->NbLines($this->widths[$i],$data[$i]));
126: }
127: $h=$this->cell_height*$nb;
128: // Issue a page break first if needed and return so that you can add the table header again
129: if ($this->CheckPageBreak($h)) {
130: return false;
131: } else {
132: // Draw the cells of the row
133: $style = $this->fill ? 'DF' : 'D';
134: for ($i=0;$i<count($data);$i++) {
135: $w=$this->widths[$i];
136: $a='L';
137: if (isset($this->aligns)) {
138: $a=is_array($this->aligns) ? $this->aligns[$i] : $this->aligns;
139: }
140: // Save the current position
141: $x=$this->GetX();
142: $y=$this->GetY();
143: // Draw the border
144: $this->Rect($x,$y,$w,$h,$style);
145: // Print the text
146: $this->MultiCell($w,$this->cell_height,$data[$i],0,$a);
147: // Put the position to the right of the cell
148: $this->SetXY($x+$w,$y);
149: }
150: //Go to the next line
151: $this->Ln($h);
152: return true;
153: }
154: }
155:
156: /**
157: * Check if page break is needed
158: *
159: * @param number $h the height of the row
160: * @return boolean true if a page break is needed
161: * @access public
162: */
163: function CheckPageBreak($h)
164: {
165: //If the height h would cause an overflow, add a new page immediately
166: if ($this->GetY()+$h>$this->PageBreakTrigger) {
167: $this->AddPage($this->CurOrientation);
168: $this->table_page++;
169: return true;
170: } else {
171: return false;
172: }
173: }
174:
175: /**
176: * Computes the number of lines a MultiCell of width w will take
177: *
178: * @param number $w cell width
179: * @param string $txt cell text
180: * @return integer number of lines a MultiCell of width w will take
181: * @access public
182: */
183: function NbLines($w,$txt)
184: {
185: $cw=&$this->CurrentFont['cw'];
186: if ($w==0) {
187: $w=$this->w-$this->rMargin-$this->x;
188: }
189: $wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
190: $s=str_replace("\r",'',$txt);
191: $nb=strlen($s);
192: if ($nb>0 and $s[$nb-1]=="\n")
193: $nb--;
194: $sep=-1;
195: $i=0;
196: $j=0;
197: $l=0;
198: $nl=1;
199: while ($i<$nb) {
200: $c=$s[$i];
201: if ($c=="\n") {
202: $i++;
203: $sep=-1;
204: $j=$i;
205: $l=0;
206: $nl++;
207: continue;
208: }
209: if ($c==' ') {
210: $sep=$i;
211: }
212: $l+=$cw[$c];
213: if ($l>$wmax) {
214: if ($sep==-1) {
215: if ($i==$j) {
216: $i++;
217: }
218: } else {
219: $i=$sep+1;
220: }
221: $sep=-1;
222: $j=$i;
223: $l=0;
224: $nl++;
225: } else {
226: $i++;
227: }
228: }
229: return $nl;
230: }
231: }
232: