250 |
kaklik |
1 |
<?php |
|
|
2 |
/* $Id: pdf.php,v 1.3 2006/01/17 17:03:02 cybot_tm Exp $ */ |
|
|
3 |
// vim: expandtab sw=4 ts=4 sts=4: |
|
|
4 |
|
|
|
5 |
/** |
|
|
6 |
* Produce a PDF report (export) from a query |
|
|
7 |
*/ |
|
|
8 |
|
|
|
9 |
|
|
|
10 |
define('FPDF_FONTPATH', './libraries/fpdf/font/'); |
|
|
11 |
//if ($charset == 'utf-8') { |
|
|
12 |
define('PMA_PDF_FONT', 'FreeSans'); |
|
|
13 |
require_once('./libraries/fpdf/ufpdf.php'); |
|
|
14 |
class PMA_FPDF extends UFPDF |
|
|
15 |
{ |
|
|
16 |
}; |
|
|
17 |
//} else { |
|
|
18 |
// define('PMA_PDF_FONT', 'Arial'); |
|
|
19 |
// require_once('./libraries/fpdf/fpdf.php'); |
|
|
20 |
// class PMA_FPDF extends FPDF { |
|
|
21 |
// }; |
|
|
22 |
//} |
|
|
23 |
|
|
|
24 |
|
|
|
25 |
// Adapted from a LGPL script by Philip Clarke |
|
|
26 |
|
|
|
27 |
class PMA_PDF extends PMA_FPDF |
|
|
28 |
{ |
|
|
29 |
var $tablewidths; |
|
|
30 |
var $headerset; |
|
|
31 |
var $footerset; |
|
|
32 |
|
|
|
33 |
// overloading of a fpdf function: |
|
|
34 |
function _beginpage($orientation) |
|
|
35 |
{ |
|
|
36 |
$this->page++; |
|
|
37 |
// solved the problem of overwriting a page, if it already exists |
|
|
38 |
if (!isset($this->pages[$this->page])) { |
|
|
39 |
$this->pages[$this->page] = ''; |
|
|
40 |
} |
|
|
41 |
$this->state = 2; |
|
|
42 |
$this->x = $this->lMargin; |
|
|
43 |
$this->y = $this->tMargin; |
|
|
44 |
$this->lasth = 0; |
|
|
45 |
$this->FontFamily = ''; |
|
|
46 |
|
|
|
47 |
//Page orientation |
|
|
48 |
if (!$orientation) { |
|
|
49 |
$orientation = $this->DefOrientation; |
|
|
50 |
} else { |
|
|
51 |
$orientation = strtoupper($orientation{0}); |
|
|
52 |
if ($orientation != $this->DefOrientation) { |
|
|
53 |
$this->OrientationChanges[$this->page] = true; |
|
|
54 |
} |
|
|
55 |
} |
|
|
56 |
if ($orientation != $this->CurOrientation) { |
|
|
57 |
//Change orientation |
|
|
58 |
if ($orientation == 'P') { |
|
|
59 |
$this->wPt = $this->fwPt; |
|
|
60 |
$this->hPt = $this->fhPt; |
|
|
61 |
$this->w = $this->fw; |
|
|
62 |
$this->h = $this->fh; |
|
|
63 |
} else { |
|
|
64 |
$this->wPt = $this->fhPt; |
|
|
65 |
$this->hPt = $this->fwPt; |
|
|
66 |
$this->w = $this->fh; |
|
|
67 |
$this->h = $this->fw; |
|
|
68 |
} |
|
|
69 |
$this->PageBreakTrigger = $this->h - $this->bMargin; |
|
|
70 |
$this->CurOrientation = $orientation; |
|
|
71 |
} |
|
|
72 |
} |
|
|
73 |
|
|
|
74 |
function Header() |
|
|
75 |
{ |
|
|
76 |
global $maxY; |
|
|
77 |
|
|
|
78 |
// Check if header for this page already exists |
|
|
79 |
if (!isset($this->headerset[$this->page])) { |
|
|
80 |
$fullwidth = 0; |
|
|
81 |
foreach ($this->tablewidths as $width) { |
|
|
82 |
$fullwidth += $width; |
|
|
83 |
} |
|
|
84 |
$this->SetY(($this->tMargin) - ($this->FontSizePt/$this->k)*2); |
|
|
85 |
$this->cellFontSize = $this->FontSizePt ; |
|
|
86 |
$this->SetFont(PMA_PDF_FONT, '', ($this->titleFontSize ? $this->titleFontSize : $this->FontSizePt)); |
|
|
87 |
$this->Cell(0, $this->FontSizePt, $this->titleText, 0, 1, 'C'); |
|
|
88 |
$l = ($this->lMargin); |
|
|
89 |
$this->SetFont(PMA_PDF_FONT, '', $this->cellFontSize); |
|
|
90 |
foreach ($this->colTitles as $col => $txt) { |
|
|
91 |
$this->SetXY($l, ($this->tMargin)); |
|
|
92 |
$this->MultiCell($this->tablewidths[$col], $this->FontSizePt, $txt); |
|
|
93 |
$l += $this->tablewidths[$col] ; |
|
|
94 |
$maxY = ($maxY < $this->getY()) ? $this->getY() : $maxY ; |
|
|
95 |
} |
|
|
96 |
$this->SetXY($this->lMargin, $this->tMargin); |
|
|
97 |
$this->setFillColor(200, 200, 200); |
|
|
98 |
$l = ($this->lMargin); |
|
|
99 |
foreach ($this->colTitles as $col => $txt) { |
|
|
100 |
$this->SetXY($l, $this->tMargin); |
|
|
101 |
$this->cell($this->tablewidths[$col], $maxY-($this->tMargin), '', 1, 0, 'L', 1); |
|
|
102 |
$this->SetXY($l, $this->tMargin); |
|
|
103 |
$this->MultiCell($this->tablewidths[$col], $this->FontSizePt, $txt, 0, 'C'); |
|
|
104 |
$l += $this->tablewidths[$col]; |
|
|
105 |
} |
|
|
106 |
$this->setFillColor(255, 255, 255); |
|
|
107 |
// set headerset |
|
|
108 |
$this->headerset[$this->page] = 1; |
|
|
109 |
} |
|
|
110 |
|
|
|
111 |
$this->SetY($maxY); |
|
|
112 |
} |
|
|
113 |
|
|
|
114 |
function Footer() |
|
|
115 |
{ |
|
|
116 |
// Check if footer for this page already exists |
|
|
117 |
if (!isset($this->footerset[$this->page])) { |
|
|
118 |
$this->SetY(-15); |
|
|
119 |
//Page number |
|
|
120 |
$this->Cell(0, 10, $GLOBALS['strPageNumber'] .' '.$this->PageNo() .'/{nb}', 'T', 0, 'C'); |
|
|
121 |
|
|
|
122 |
// set footerset |
|
|
123 |
$this->footerset[$this->page] = 1; |
|
|
124 |
} |
|
|
125 |
} |
|
|
126 |
|
|
|
127 |
function morepagestable($lineheight=8) |
|
|
128 |
{ |
|
|
129 |
// some things to set and 'remember' |
|
|
130 |
$l = $this->lMargin; |
|
|
131 |
$startheight = $h = $this->GetY(); |
|
|
132 |
$startpage = $currpage = $this->page; |
|
|
133 |
|
|
|
134 |
// calculate the whole width |
|
|
135 |
$fullwidth = 0; |
|
|
136 |
foreach ($this->tablewidths as $width) { |
|
|
137 |
$fullwidth += $width; |
|
|
138 |
} |
|
|
139 |
|
|
|
140 |
// Now let's start to write the table |
|
|
141 |
$row = 0; |
|
|
142 |
$tmpheight = array(); |
|
|
143 |
$maxpage = 0; |
|
|
144 |
|
|
|
145 |
while ($data = PMA_DBI_fetch_row($this->results)) { |
|
|
146 |
$this->page = $currpage; |
|
|
147 |
// write the horizontal borders |
|
|
148 |
$this->Line($l, $h, $fullwidth+$l, $h); |
|
|
149 |
// write the content and remember the height of the highest col |
|
|
150 |
foreach ($data as $col => $txt) { |
|
|
151 |
$this->page = $currpage; |
|
|
152 |
$this->SetXY($l, $h); |
|
|
153 |
$this->MultiCell($this->tablewidths[$col], $lineheight, $txt, 0, $this->colAlign[$col]); |
|
|
154 |
|
|
|
155 |
$l += $this->tablewidths[$col]; |
|
|
156 |
|
|
|
157 |
if (!isset($tmpheight[$row.'-'.$this->page])) { |
|
|
158 |
$tmpheight[$row.'-'.$this->page] = 0; |
|
|
159 |
} |
|
|
160 |
if ($tmpheight[$row.'-'.$this->page] < $this->GetY()) { |
|
|
161 |
$tmpheight[$row.'-'.$this->page] = $this->GetY(); |
|
|
162 |
} |
|
|
163 |
if ($this->page > $maxpage) { |
|
|
164 |
$maxpage = $this->page; |
|
|
165 |
} |
|
|
166 |
unset($data[$col]); |
|
|
167 |
} |
|
|
168 |
|
|
|
169 |
// get the height we were in the last used page |
|
|
170 |
$h = $tmpheight[$row.'-'.$maxpage]; |
|
|
171 |
// set the "pointer" to the left margin |
|
|
172 |
$l = $this->lMargin; |
|
|
173 |
// set the $currpage to the last page |
|
|
174 |
$currpage = $maxpage; |
|
|
175 |
unset($data[$row]); |
|
|
176 |
$row++; |
|
|
177 |
} |
|
|
178 |
// draw the borders |
|
|
179 |
// we start adding a horizontal line on the last page |
|
|
180 |
$this->page = $maxpage; |
|
|
181 |
$this->Line($l, $h, $fullwidth+$l, $h); |
|
|
182 |
// now we start at the top of the document and walk down |
|
|
183 |
for ($i = $startpage; $i <= $maxpage; $i++) { |
|
|
184 |
$this->page = $i; |
|
|
185 |
$l = $this->lMargin; |
|
|
186 |
$t = ($i == $startpage) ? $startheight : $this->tMargin; |
|
|
187 |
$lh = ($i == $maxpage) ? $h : $this->h-$this->bMargin; |
|
|
188 |
$this->Line($l, $t, $l, $lh); |
|
|
189 |
foreach ($this->tablewidths as $width) { |
|
|
190 |
$l += $width; |
|
|
191 |
$this->Line($l, $t, $l, $lh); |
|
|
192 |
} |
|
|
193 |
} |
|
|
194 |
// set it to the last page, if not it'll cause some problems |
|
|
195 |
$this->page = $maxpage; |
|
|
196 |
} |
|
|
197 |
|
|
|
198 |
|
|
|
199 |
function mysql_report($query, $attr = array()) |
|
|
200 |
{ |
|
|
201 |
foreach ($attr as $key => $val){ |
|
|
202 |
$this->$key = $val ; |
|
|
203 |
} |
|
|
204 |
|
|
|
205 |
// Pass 1 for column widths |
|
|
206 |
// TODO: force here a LIMIT to speed up pass 1 ? |
|
|
207 |
$this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED); |
|
|
208 |
$this->numFields = PMA_DBI_num_fields($this->results); |
|
|
209 |
$this->fields = PMA_DBI_get_fields_meta($this->results); |
|
|
210 |
|
|
|
211 |
// if column widths not set |
|
|
212 |
if (!isset($this->tablewidths)){ |
|
|
213 |
|
|
|
214 |
// starting col width |
|
|
215 |
$this->sColWidth = ($this->w - $this->lMargin - $this->rMargin) / $this->numFields; |
|
|
216 |
|
|
|
217 |
// loop through results header and set initial col widths/ titles/ alignment |
|
|
218 |
// if a col title is less than the starting col width / reduce that column size |
|
|
219 |
for ($i=0; $i < $this->numFields; $i++){ |
|
|
220 |
$stringWidth = $this->getstringwidth($this->fields[$i]->name) + 6 ; |
|
|
221 |
// set any column titles less than the start width to the column title width |
|
|
222 |
if (($stringWidth) < $this->sColWidth){ |
|
|
223 |
$colFits[$i] = $stringWidth ; |
|
|
224 |
} |
|
|
225 |
$this->colTitles[$i] = $this->fields[$i]->name; |
|
|
226 |
switch ($this->fields[$i]->type){ |
|
|
227 |
case 'int': |
|
|
228 |
$this->colAlign[$i] = 'R'; |
|
|
229 |
break; |
|
|
230 |
default: |
|
|
231 |
$this->colAlign[$i] = 'L'; |
|
|
232 |
} |
|
|
233 |
} |
|
|
234 |
|
|
|
235 |
// loop through the data, any column whose contents is bigger i |
|
|
236 |
// that the col size is resized |
|
|
237 |
while ($row = PMA_DBI_fetch_row($this->results)) { |
|
|
238 |
foreach ($colFits as $key => $val) { |
|
|
239 |
$stringWidth = $this->getstringwidth($row[$key]) + 6 ; |
|
|
240 |
if ($stringWidth > $this->sColWidth) { |
|
|
241 |
// any col where row is bigger than the start width is now discarded |
|
|
242 |
unset($colFits[$key]); |
|
|
243 |
} else { |
|
|
244 |
// if text is not bigger than the current column width setting enlarge the column |
|
|
245 |
if ($stringWidth > $val) { |
|
|
246 |
$colFits[$key] = ($stringWidth) ; |
|
|
247 |
} |
|
|
248 |
} |
|
|
249 |
} |
|
|
250 |
} |
|
|
251 |
|
|
|
252 |
$totAlreadyFitted = 0; |
|
|
253 |
foreach ($colFits as $key => $val){ |
|
|
254 |
// set fitted columns to smallest size |
|
|
255 |
$this->tablewidths[$key] = $val; |
|
|
256 |
// to work out how much (if any) space has been freed up |
|
|
257 |
$totAlreadyFitted += $val; |
|
|
258 |
} |
|
|
259 |
|
|
|
260 |
$surplus = (sizeof($colFits) * $this->sColWidth) - $totAlreadyFitted; |
|
|
261 |
for ($i=0; $i < $this->numFields; $i++) { |
|
|
262 |
if (!in_array($i, array_keys($colFits))) { |
|
|
263 |
$this->tablewidths[$i] = $this->sColWidth + ($surplus / ($this->numFields - sizeof($colFits))); |
|
|
264 |
} |
|
|
265 |
} |
|
|
266 |
|
|
|
267 |
ksort($this->tablewidths); |
|
|
268 |
|
|
|
269 |
} |
|
|
270 |
|
|
|
271 |
PMA_DBI_free_result($this->results); |
|
|
272 |
|
|
|
273 |
// Pass 2 |
|
|
274 |
|
|
|
275 |
$this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED); |
|
|
276 |
$this->Open(); |
|
|
277 |
$this->setY($this->tMargin); |
|
|
278 |
$this->AddPage(); |
|
|
279 |
$this->morepagestable($this->FontSizePt); |
|
|
280 |
PMA_DBI_free_result($this->results); |
|
|
281 |
|
|
|
282 |
} // end of mysql_report function |
|
|
283 |
|
|
|
284 |
} // end of PMA_PDF class |
|
|
285 |
|
|
|
286 |
/** |
|
|
287 |
* Outputs comment |
|
|
288 |
* |
|
|
289 |
* @param string Text of comment |
|
|
290 |
* |
|
|
291 |
* @return bool Whether it suceeded |
|
|
292 |
*/ |
|
|
293 |
function PMA_exportComment($text) |
|
|
294 |
{ |
|
|
295 |
return TRUE; |
|
|
296 |
} |
|
|
297 |
|
|
|
298 |
/** |
|
|
299 |
* Outputs export footer |
|
|
300 |
* |
|
|
301 |
* @return bool Whether it suceeded |
|
|
302 |
* |
|
|
303 |
* @access public |
|
|
304 |
*/ |
|
|
305 |
function PMA_exportFooter() |
|
|
306 |
{ |
|
|
307 |
return TRUE; |
|
|
308 |
} |
|
|
309 |
|
|
|
310 |
/** |
|
|
311 |
* Outputs export header |
|
|
312 |
* |
|
|
313 |
* @return bool Whether it suceeded |
|
|
314 |
* |
|
|
315 |
* @access public |
|
|
316 |
*/ |
|
|
317 |
function PMA_exportHeader() |
|
|
318 |
{ |
|
|
319 |
return TRUE; |
|
|
320 |
} |
|
|
321 |
|
|
|
322 |
/** |
|
|
323 |
* Outputs database header |
|
|
324 |
* |
|
|
325 |
* @param string Database name |
|
|
326 |
* |
|
|
327 |
* @return bool Whether it suceeded |
|
|
328 |
* |
|
|
329 |
* @access public |
|
|
330 |
*/ |
|
|
331 |
function PMA_exportDBHeader($db) |
|
|
332 |
{ |
|
|
333 |
return TRUE; |
|
|
334 |
} |
|
|
335 |
|
|
|
336 |
/** |
|
|
337 |
* Outputs database footer |
|
|
338 |
* |
|
|
339 |
* @param string Database name |
|
|
340 |
* |
|
|
341 |
* @return bool Whether it suceeded |
|
|
342 |
* |
|
|
343 |
* @access public |
|
|
344 |
*/ |
|
|
345 |
function PMA_exportDBFooter($db) |
|
|
346 |
{ |
|
|
347 |
return TRUE; |
|
|
348 |
} |
|
|
349 |
|
|
|
350 |
/** |
|
|
351 |
* Outputs create database database |
|
|
352 |
* |
|
|
353 |
* @param string Database name |
|
|
354 |
* |
|
|
355 |
* @return bool Whether it suceeded |
|
|
356 |
* |
|
|
357 |
* @access public |
|
|
358 |
*/ |
|
|
359 |
function PMA_exportDBCreate($db) |
|
|
360 |
{ |
|
|
361 |
return TRUE; |
|
|
362 |
} |
|
|
363 |
|
|
|
364 |
/** |
|
|
365 |
* Outputs the content of a table in PDF format |
|
|
366 |
* |
|
|
367 |
* @param string the database name |
|
|
368 |
* @param string the table name |
|
|
369 |
* @param string the end of line sequence |
|
|
370 |
* @param string the url to go back in case of error |
|
|
371 |
* @param string SQL query for obtaining data |
|
|
372 |
* |
|
|
373 |
* @return bool Whether it suceeded |
|
|
374 |
* |
|
|
375 |
* @access public |
|
|
376 |
*/ |
|
|
377 |
function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) |
|
|
378 |
{ |
|
|
379 |
global $what; |
|
|
380 |
global $pdf_report_title; |
|
|
381 |
|
|
|
382 |
// TODO: user-defined page orientation, paper size |
|
|
383 |
$pdf = new PMA_PDF('L', 'pt', 'A3'); |
|
|
384 |
|
|
|
385 |
$pdf->AddFont('FreeSans', '', 'FreeSans.php'); |
|
|
386 |
$pdf->AddFont('FreeSans', 'B', 'FreeSansBold.php'); |
|
|
387 |
$pdf->SetFont(PMA_PDF_FONT, '', 11.5); |
|
|
388 |
$pdf->AliasNbPages(); |
|
|
389 |
$attr=array('titleFontSize' => 18, 'titleText' => $pdf_report_title); |
|
|
390 |
$pdf->mysql_report($sql_query, $attr); |
|
|
391 |
|
|
|
392 |
// instead of $pdf->Output(): |
|
|
393 |
if ($pdf->state < 3) { |
|
|
394 |
$pdf->Close(); |
|
|
395 |
} |
|
|
396 |
if (!PMA_exportOutputHandler($pdf->buffer)) { |
|
|
397 |
return FALSE; |
|
|
398 |
} |
|
|
399 |
|
|
|
400 |
return TRUE; |
|
|
401 |
} // end of the 'PMA_exportData()' function |
|
|
402 |
?> |