Option for saving report selections ($save_report_selection > 0 in config.php means...
[fa-stable.git] / reporting / includes / excel_report.inc
1 <?php
2 /**********************************************************************
3     Copyright (C) FrontAccounting, LLC.
4         Released under the terms of the GNU General Public License, GPL, 
5         as published by the Free Software Foundation, either version 3 
6         of the License, or (at your option) any later version.
7     This program is distributed in the hope that it will be useful,
8     but WITHOUT ANY WARRANTY; without even the implied warranty of
9     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
10     See the License here <http://www.gnu.org/licenses/gpl-3.0.html>.
11 ***********************************************************************/
12 include_once($path_to_root . "/reporting/includes/Workbook.php");
13 include_once($path_to_root . "/admin/db/company_db.inc");
14 include_once($path_to_root . "/admin/db/fiscalyears_db.inc");
15 include_once($path_to_root . "/config.php");
16 // xls version
17 class FrontReport extends Spreadsheet_Excel_Writer_Workbook
18 {
19         var $size;
20         var $company;
21         var $user;
22         var $host;
23         var $fiscal_year;
24         var $title;
25         var $filename;
26         var $unique_name;
27         var $path;
28         var $code;
29         var $bottomMargin = 0;
30         var $lineHeight;
31         var $leftMargin = 0;
32
33         var $cols;
34         var $params;
35         var $headers;
36         var $aligns;
37         var $headers2;
38         var $aligns2;
39         var $cols2;
40         var $fontSize;
41         var $oldFontSize;
42         var $currency;
43         var $row = 9999999;
44         var $y;
45         var $numcols;
46         var $excelColWidthFactor;
47         var $endLine;
48
49         var $formatTitle;
50         var $formatDateTime;
51         var $formatDate;
52         var $formatHeaderLeft;
53         var $formatHeaderRight;
54         var $formatFooter;
55         var $formatAmount = array();
56         var $headerFunc;
57         
58         var $sheet;
59
60         function FrontReport($title, $filename, $size = 'A4', $fontsize = 9, $orientation = 'P', $margins = NULL, $excelColWidthFactor = 6.5)
61         {
62                 global $dateseps, $page_security;
63                 if (!$_SESSION["wa_current_user"]->can_access_page($page_security))
64                 {
65                         display_error(_("The security settings on your account do not permit you to print this report"));
66                         end_page();
67                         exit;
68                 }
69                 $this->size = $size;
70                 $this->title = $title;
71                 $this->lineHeight = 12;
72                 $this->endLine = 760;
73                 $this->fontSize = $fontsize;
74                 $this->oldFontSize = 0;
75                 $this->y = 0;
76                 $this->currency = '';
77                 $this->excelColWidthFactor = $excelColWidthFactor;
78                 $rtl = ($_SESSION['language']->dir == 'rtl');
79                 $this->code = strtolower($_SESSION['language']->encoding);
80                 $this->filename = $filename.".xls";
81                 $this->unique_name = uniqid('').".xls";
82                 $this->path = company_path(). '/pdf_files';
83                 $this->Spreadsheet_Excel_Writer_Workbook($this->path."/".$this->unique_name);
84                 //$this->setCountry(48);
85                 if ($this->code != "iso-8859-1")
86                         $this->setVersion(8); // set biff version to 8 (0x0006 internal)
87                 $this->sheet =& $this->addWorksheet($this->worksheetNameGenerator($this->title));
88                 if ($this->code != "iso-8859-1")
89                         $this->sheet->setInputEncoding($this->code); // set sheet encoding
90                 if ($rtl)
91                         $this->sheet->setRTL();
92                 $this->formatTitle =& $this->addFormat();       
93                 $this->formatTitle->setSize(16);
94                 $this->formatTitle->setBold();
95                 $this->formatTitle->setAlign($rtl ? 'right' : 'left');
96                 $this->formatTitle->setTop(2);
97                 $this->formatTitle->setTopColor('gray');
98
99                 $how = user_date_format();
100                 $sep = $dateseps[user_date_sep()];
101                 if ($sep == '.')
102                         $sep = "\\.";
103                 if ($how == 0)
104                 {
105                         $dateformat_long = "mm{$sep}dd{$sep}yyyy\ \ hh:mm\ am/pm";
106                         $dateformat = "mm{$sep}dd{$sep}yyyy";
107                 }       
108                 elseif ($how == 1)      
109                 {
110                         $dateformat_long = "dd{$sep}mm{$sep}yyyy\ \ hh:mm";
111                         $dateformat = "dd{$sep}mm{$sep}yyyy";
112                 }       
113                 else    
114                 {
115                         $dateformat_long = "yyyy{$sep}mm{$sep}dd\ \ hh:mm";
116                         $dateformat = "yyyy{$sep}mm{$sep}dd";
117                 }       
118                 $this->formatDateTime =& $this->addFormat();
119                 $this->formatDateTime->setNumFormat($dateformat_long);
120                 $this->formatDateTime->setAlign($rtl ? 'right' : 'left');
121                 $this->formatDate =& $this->addFormat();
122                 $this->formatDate->setNumFormat($dateformat);
123                 $this->formatDate->setAlign($rtl ? 'right' : 'left');
124                 $this->formatRight =& $this->addFormat();
125                 $this->formatRight->setAlign($rtl ? 'left' : 'right');
126                 $this->formatLeft =& $this->addFormat();
127                 $this->formatLeft->setAlign($rtl ? 'right' : 'left');
128                 
129                 $this->formatHeaderLeft =& $this->addFormat();
130                 $this->formatHeaderLeft->setItalic();
131                 $this->formatHeaderLeft->setTop(2);
132                 $this->formatHeaderLeft->setTopColor('gray');
133                 $this->formatHeaderLeft->setBottom(2);
134                 $this->formatHeaderLeft->setBottomColor('gray');
135                 $this->formatHeaderLeft->setAlign('vcenter');
136                 $this->formatTopHeaderLeft =& $this->addFormat();
137                 $this->formatTopHeaderLeft->setItalic();
138                 $this->formatTopHeaderLeft->setTop(2);
139                 $this->formatTopHeaderLeft->setTopColor('gray');
140                 $this->formatTopHeaderLeft->setAlign('vcenter');
141                 $this->formatBottomHeaderLeft =& $this->addFormat();
142                 $this->formatBottomHeaderLeft->setItalic();
143                 $this->formatBottomHeaderLeft->setBottom(2);
144                 $this->formatBottomHeaderLeft->setBottomColor('gray');
145                 $this->formatBottomHeaderLeft->setAlign('vcenter');
146                 $this->formatDate->setAlign($rtl ? 'right' : 'left');
147                 $this->formatHeaderRight =& $this->addFormat();
148                 $this->formatHeaderRight->setItalic();
149                 $this->formatHeaderRight->setTop(2);
150                 $this->formatHeaderRight->setTopColor('gray');
151                 $this->formatHeaderRight->setBottom(2);
152                 $this->formatHeaderRight->setBottomColor('gray');
153                 $this->formatHeaderRight->setAlign('vcenter');
154                 $this->formatHeaderRight->setAlign('right');
155                 $this->formatTopHeaderRight =& $this->addFormat();
156                 $this->formatTopHeaderRight->setItalic();
157                 $this->formatTopHeaderRight->setTop(2);
158                 $this->formatTopHeaderRight->setTopColor('gray');
159                 $this->formatTopHeaderRight->setAlign('vcenter');
160                 $this->formatTopHeaderRight->setAlign('right');
161                 $this->formatBottomHeaderRight =& $this->addFormat();
162                 $this->formatBottomHeaderRight->setItalic();
163                 $this->formatBottomHeaderRight->setBottom(2);
164                 $this->formatBottomHeaderRight->setBottomColor('gray');
165                 $this->formatBottomHeaderRight->setAlign('vcenter');
166                 $this->formatBottomHeaderRight->setAlign('right');
167                 $this->formatFooter =& $this->addFormat();
168                 $this->formatFooter->setTop(2);
169                 $this->formatFooter->setTopColor('gray');
170                 $this->SetHeaderType("header");
171         }
172         
173
174         /*
175                 Set header handler
176         */
177         function SetHeaderType($name) {
178                 $this->headerFunc = $name;
179         }
180         // Check a given name to see if it's a valid Excel worksheet name,
181         // and fix if necessary
182         function worksheetNameGenerator($name)
183         {
184                 // First, strip out characters which aren't allowed
185                 $illegal_chars = array(':', '\\', '/', '?', '*', '[', ']');
186                 for ($i = 0; $i < count($illegal_chars); $i++)
187                         $name = str_replace($illegal_chars[$i], '', $name);
188                 // Now, if name is longer than 31 chars, truncate it
189                 if (strlen($name) > 31)
190                         $name = substr($name, 0, 31);
191                 return $name;
192         }
193         
194         function NumFormat($dec) 
195         {
196                 if (!isset($this->formatAmount[$dec]))
197                 {
198                         //global $thoseps,$decseps;
199                         $dec = (int)$dec;
200                         //$tsep = $thoseps[user_tho_sep()];
201                         //$dsep = $decseps[user_dec_sep()];
202                         $tsep = ',';
203                         $dsep = '.';
204                         $format = "###{$tsep}###{$tsep}###{$tsep}##0";
205                         if ($dec>0)
206                                 $format .= "{$dsep}".str_repeat('0',$dec);
207                         $this->formatAmount[$dec] =& $this->addFormat();
208                         $this->formatAmount[$dec]->setNumFormat($format);
209                         $this->formatAmount[$dec]->setAlign('right');
210                 }
211                 return $this->formatAmount[$dec];
212         }
213
214         function Font($fontname = '', $style = 'normal')
215         {
216         }
217
218         function Info($params, $cols, $headers, $aligns,
219                 $cols2 = null, $headers2 = null, $aligns2 = null)
220         {
221                 global $app_title, $version, $power_by, $power_url;
222                 $this->company = get_company_prefs();
223                 $year = get_current_fiscalyear();
224                 if ($year['closed'] == 0)
225                         $how = _("Active");
226                 else
227                         $how = _("Closed");
228                 $this->fiscal_year = sql2date($year['begin']) . " - " . sql2date($year['end']) . "  " . "(" . $how . ")";
229                 $this->user = $_SESSION["wa_current_user"]->name;
230                 $this->host = $_SERVER['SERVER_NAME'];
231                 $this->params = $params;
232                 $this->cols = $cols;
233                 $this->headers = $headers;
234                 $this->aligns = $aligns;
235                 $this->cols2 = $cols2;
236                 $this->headers2 = $headers2;
237                 $this->aligns2 = $aligns2;
238                 $this->numcols = count($this->headers);
239                 $tcols = count($this->headers2);
240                 if ($tcols > $this->numcols)
241                         $this->numcols = $tcols;
242                 for ($i = 0; $i < $this->numcols; $i++)
243                         $this->sheet->setColumn($i, $i, $this->px2units($this->cols[$i + 1] - $this->cols[$i]));
244         }
245
246         function Header()
247         {
248                 $tcol = $this->numcols - 1;
249                 $this->sheet->setRow($this->y, 20);
250                 for ($i = 0; $i < $this->numcols; $i++)
251                         $this->sheet->writeBlank($this->y, $i, $this->formatTitle);
252                 $this->sheet->writeString($this->y, 0, $this->title, $this->formatTitle);
253                 $this->sheet->mergeCells($this->y, 0, $this->y, $tcol);
254                 $this->NewLine();
255                 $str = _("Print Out Date") . ':';
256                 $this->sheet->writeString($this->y, 0, $str, $this->formatLeft);
257                 $this->sheet->writeString($this->y, 1, Today() . "  ".Now(), $this->formatLeft);
258                 $this->sheet->writeString($this->y, $tcol-1, $this->company['coy_name'], $this->formatLeft);
259                 $this->sheet->mergeCells($this->y, $tcol-1, $this->y, $tcol);
260                 $this->NewLine();
261                 $str = _("Fiscal Year") . ':';
262                 $this->sheet->writeString($this->y, 0, $str, $this->formatLeft);
263                 $str = $this->fiscal_year;
264                 $this->sheet->writeString($this->y, 1, $str, $this->formatLeft);
265                 $this->sheet->writeString($this->y, $tcol-1, $this->host, $this->formatLeft);
266                 $this->sheet->mergeCells($this->y, $tcol-1, $this->y, $tcol);
267                 for ($i = 1; $i < count($this->params); $i++)
268                 {
269                         if ($this->params[$i]['from'] != '')
270                         {
271                                 $this->NewLine();
272                                 $str = $this->params[$i]['text'] . ':';
273                                 $this->sheet->writeString($this->y, 0, $str);
274                                 $str = $this->params[$i]['from'];
275                                 if ($this->params[$i]['to'] != '')
276                                         $str .= " - " . $this->params[$i]['to'];
277                                 $this->sheet->writeString($this->y, 1, $str, $this->formatLeft);
278                                 if ($i == 1)
279                                 {
280                                         $this->sheet->writeString($this->y, $tcol-1, $this->user, $this->formatLeft);
281                                         $this->sheet->mergeCells($this->y, $tcol-1, $this->y, $tcol);
282                                 }       
283                         }
284                 }
285                 if ($this->params[0] != '') // Comments
286                 {
287                         $this->NewLine();
288                         $str = _("Comments") . ':';
289                         $this->sheet->writeString($this->y, 0, $str, $this->formatLeft);
290                         $this->sheet->writeString($this->y, 1, $this->params[0], $this->formatLeft);
291                 }
292                 $this->NewLine();
293                 if ($this->headers2 != null)
294                 {
295                         for ($i = 0, $j = 0; $i < $this->numcols; $i++)
296                         {
297                                 if ($this->cols2[$j] >= $this->cols[$i] && $this->cols2[$j] <= $this->cols[$i + 1])
298                                 {
299                                         if ($this->aligns2[$j] == "right")
300                                                 $this->sheet->writeString($this->y, $i, $this->headers2[$j], $this->formatHeaderRight);
301                                         else    
302                                                 $this->sheet->writeString($this->y, $i, $this->headers2[$j], $this->formatHeaderLeft);
303                                         $j++;   
304                                 }
305                                 else
306                                         $this->sheet->writeString($this->y, $i, "", $this->formatHeaderLeft);
307                         }               
308                         $this->NewLine();
309                 }
310
311                 for ($i = 0; $i < $this->numcols; $i++)
312                 {
313                         if (!isset($this->headers[$i]))
314                                 $header = "";
315                         else
316                                 $header = $this->headers[$i];
317                         if ($this->aligns[$i] == "right")
318                                 $this->sheet->writeString($this->y, $i, $header, $this->formatHeaderRight);
319                         else    
320                                 $this->sheet->writeString($this->y, $i, $header, $this->formatHeaderLeft);
321                 }
322                 $this->NewLine();
323         }
324
325         function Header2($myrow, $branch, $sales_order, $bankaccount, $doctype)
326         {
327                 return;
328         }
329
330         // Alternate header style - primary differences are for PDFs
331         function Header3()
332         {
333                 // Flag to make sure we only print the company name once
334                 $companyNamePrinted = false;
335                 
336                 $this->y = 0;
337                 $tcol = $this->numcols - 1;
338                 $this->sheet->setRow($this->y, 20);
339                 // Title
340                 for ($i = 0; $i < $this->numcols; $i++)
341                         $this->sheet->writeBlank($this->y, $i, $this->formatTitle);
342                 $this->sheet->writeString($this->y, 0, $this->title, $this->formatTitle);
343                 $this->sheet->mergeCells($this->y, 0, $this->y, $tcol);
344
345                 // Dimension 1 - optional
346                 // - only print if available and not blank
347                 if (count($this->params) > 3)
348                         if ($this->params[3]['from'] != '')
349                         {
350                                 $this->NewLine();
351                                 $str = $this->params[3]['text'] . ':';
352                                 $this->sheet->writeString($this->y, 0, $str, $this->formatLeft);
353                                 $this->sheet->writeString($this->y, 1, $this->params[3]['from'], $this->formatLeft);
354                                 // Company Name - at end of this row
355                                 if (!$companyNamePrinted)
356                                 {
357                                         $this->sheet->writeString($this->y, $tcol-1, $this->company['coy_name'], $this->formatLeft);
358                                         $this->sheet->mergeCells($this->y, $tcol-1, $this->y, $tcol);
359                                         $companyNamePrinted = true;
360                                 }
361                         }
362
363
364                 // Dimension 2 - optional
365                 // - only print if available and not blank
366                 if (count($this->params) > 4)
367                         if ($this->params[4]['from'] != '')
368                         {
369                                 $this->NewLine();
370                                 $str = $this->params[4]['text'] . ':';
371                                 $this->sheet->writeString($this->y, 0, $str, $this->formatLeft);
372                                 $this->sheet->writeString($this->y, 1, $this->params[4]['from'], $this->formatLeft);
373                                 // Company Name - at end of this row
374                                 if (!$companyNamePrinted)
375                                 {
376                                         $this->sheet->writeString($this->y, $tcol-1, $this->company['coy_name'], $this->formatLeft);
377                                         $this->sheet->mergeCells($this->y, $tcol-1, $this->y, $tcol);
378                                         $companyNamePrinted = true;
379                                 }
380                         }
381                         
382                 // Tags - optional
383                 // TBD!!!               
384         
385                 // Report Date - time period covered
386                 // - can specify a range, or just the end date (and the report contents
387                 //   should make it obvious what the beginning date is)
388                 $this->NewLine();
389                 $str = _("Report Date") . ':';
390                 $this->sheet->writeString($this->y, 0, $str, $this->formatLeft);
391                 $str = '';
392                 if ($this->params[1]['from'] != '')
393                         $str = $this->params[1]['from'] . ' - ';
394                 $str .= $this->params[1]['to'];
395                 $this->sheet->writeString($this->y, 1, $str, $this->formatLeft);
396                 // Company Name - at end of this row
397                 if (!$companyNamePrinted)
398                 {
399                         $this->sheet->writeString($this->y, $tcol-1, $this->company['coy_name'], $this->formatLeft);
400                         $this->sheet->mergeCells($this->y, $tcol-1, $this->y, $tcol);
401                         $companyNamePrinted = true;
402                 }
403                         
404                 // Timestamp of when this copy of the report was generated 
405                 $this->NewLine();
406                 $str = _("Generated At") . ':';
407                 $this->sheet->writeString($this->y, 0, $str, $this->formatLeft);
408                 $this->sheet->writeString($this->y, 1, Today() . "  ".Now(), $this->formatLeft);
409
410                 // Name of the user that generated this copy of the report
411                 $this->NewLine();
412                 $str = _("Generated By") . ':';
413                 $this->sheet->writeString($this->y, 0, $str, $this->formatLeft);
414                 $str = $this->user;
415                 $this->sheet->writeString($this->y, 1, $str, $this->formatLeft);
416
417                 // Comments - display any user-generated comments for this copy of the report
418                 if ($this->params[0] != '')
419                 {
420                         $this->NewLine();
421                         $str = _("Comments") . ':';
422                         $this->sheet->writeString($this->y, 0, $str, $this->formatLeft);
423                         $this->sheet->writeString($this->y, 1, $this->params[0], $this->formatLeft);
424                 }
425                 $this->NewLine();
426
427                 if ($this->headers2 != null)
428                 {
429                         for ($i = 0, $j = 0; $i < $this->numcols; $i++)
430                         {
431                                 if ($this->cols2[$j] >= $this->cols[$i] && $this->cols2[$j] <= $this->cols[$i + 1])
432                                 {
433                                         if ($this->aligns2[$j] == "right")
434                                                 $this->sheet->writeString($this->y, $i, $this->headers2[$j], $this->formatTopHeaderRight);
435                                         else    
436                                                 $this->sheet->writeString($this->y, $i, $this->headers2[$j], $this->formatTopHeaderLeft);
437                                         $j++;   
438                                 }
439                                 else
440                                         $this->sheet->writeString($this->y, $i, "", $this->formatTopHeaderLeft);
441                         }               
442                         $this->NewLine();
443                 }
444
445                 for ($i = 0; $i < $this->numcols; $i++)
446                 {
447                         if (!isset($this->headers[$i]))
448                                 $header = "";
449                         else
450                                 $header = $this->headers[$i];
451                         if ($this->aligns[$i] == "right")
452                                 if ($this->headers2 == null)
453                                         $this->sheet->writeString($this->y, $i, $header, $this->formatHeaderRight);
454                                 else
455                                         $this->sheet->writeString($this->y, $i, $header, $this->formatBottomHeaderRight);
456                         else    
457                                 if ($this->headers2 == null)
458                                         $this->sheet->writeString($this->y, $i, $header, $this->formatHeaderLeft);
459                                 else
460                                         $this->sheet->writeString($this->y, $i, $header, $this->formatBottomHeaderLeft);
461                 }
462                 $this->NewLine();
463         }
464
465         /**
466          * Format a numeric string date into something nicer looking.
467          *
468          * @param string $date Date string to be formatted.
469          * @param int $input_format Format of the input string.  Possible values are:<ul><li>0: user's default (default)</li></ul>
470          * @param int $output_format Format of the output string.  Possible values are:<ul><li>0: Month (word) Day (numeric), 4-digit Year - Example: January 1, 2000 (default)</li><li>1: Month 4-digit Year - Example: January 2000</li><li>2: Month Abbreviation 4-digit Year - Example: Jan 2000</li></ul>
471          * @access public
472          */
473         function DatePrettyPrint($date, $input_format = 0, $output_format = 0)
474         {
475                 if ($date != '')
476                 {
477                         $date = date2sql($date);
478                         $year = (int) (substr($date, 0, 4));
479                         $month = (int) (substr($date, 5, 2));
480                         $day = (int) (substr($date, 8, 2));
481                         if ($output_format == 0)
482                                 return(date('F j, Y', mktime(12, 0, 0, $month, $day, $year)));
483                         elseif ($output_format == 1)
484                                 return(date('F Y', mktime(12, 0, 0, $month, $day, $year)));
485                         elseif ($output_format == 2)
486                                 return(date('M Y', mktime(12, 0, 0, $month, $day, $year)));
487                 }
488                 else
489                         return $date;
490         }
491                 
492         function AddImage($logo, $x, $y, $w, $h)
493         {
494                 return;
495         }
496
497         function SetDrawColor($r, $g, $b)
498         {
499                 return;
500         }
501
502         function SetTextColor($r, $g, $b)
503         {
504                 return;
505         }
506
507         function SetFillColor($r, $g, $b)
508         {
509                 return;
510         }
511         
512         function GetCellPadding()
513         {
514                 return 0;
515         }
516         
517         function SetCellPadding($pad)
518         {
519                 return;
520         }
521         
522         function Text($c, $txt, $n=0, $corr=0, $r=0, $align='left', $border=0, $fill=0, $link=NULL, $stretch=0)
523         {
524                 return;
525         }
526
527         function TextWrap($xpos, $ypos, $len, $str, $align = 'left', $border = 0, $fill = 0, $link = NULL, $stretch = 0)
528         {
529                 return;
530         }
531
532         function TextCol($c, $n, $txt, $corr=0, $r=0, $border=0, $fill=0, $link=NULL, $stretch=0)
533         {
534                 $txt = html_entity_decode($txt);        
535                 if ($this->aligns[$c] == 'right')
536                         $this->sheet->writeString($this->y, $c, $txt, $this->formatRight);
537                 else    
538                         $this->sheet->writeString($this->y, $c, $txt, $this->formatLeft);
539                 if ($n - $c > 1)
540                         $this->sheet->mergeCells($this->y, $c, $this->y, $n - 1);
541         }
542
543         function AmountCol($c, $n, $txt, $dec=0, $corr=0, $r=0, $border=0, $fill=0, $link=NULL, $stretch=0, $color_red=false) 
544         { 
545                 if (!is_numeric($txt))
546                         $txt = 0;
547                 $this->sheet->writeNumber($this->y, $c, $txt, $this->NumFormat($dec)); 
548         }
549         
550         function AmountCol2($c, $n, $txt, $dec=0, $corr=0, $r=0, $border=0, $fill=0, $link=NULL, $stretch=0, $color_red=false, $amount_locale = NULL, $amount_format = NULL) 
551         { 
552                 if (!is_numeric($txt))
553                         $txt = 0;
554                 $this->sheet->writeNumber($this->y, $c, $txt, $this->NumFormat($dec)); 
555         }
556         
557         function DateCol($c, $n, $txt, $conv=false, $corr=0, $r=0, $border=0, $fill=0, $link=NULL, $stretch=0) 
558         {
559                 if (!$conv)
560                         $txt = date2sql($txt);
561                 list($year, $mo, $day) = explode("-", $txt);    
562                 $date = $this->ymd2date((int)$year, (int)$mo, (int)$day);
563                 $this->sheet->writeNumber($this->y, $c, $date, $this->formatDate);
564         }
565
566         function TextCol2($c, $n, $txt, $corr=0, $r=0, $border=0, $fill=0, $link=NULL, $stretch=0)
567         {
568                 $txt = html_entity_decode($txt);        
569                 $this->sheet->writeString($this->y, $c, $txt, $this->formatLeft);
570                 if ($n - $c > 1)
571                         $this->sheet->mergeCells($this->y, $c, $this->y, $n - 1);
572         }
573
574         function TextColLines($c, $n, $txt, $corr=0, $r=0, $border=0, $fill=0, $link=NULL, $stretch=0)
575         {
576                 return;
577         }
578
579         function TextWrapLines($c, $width, $txt, $align='left', $border=0, $fill=0, $link=NULL, $stretch=0)
580         {
581                 return;
582         }
583
584         /**
585          * Crude text wrap calculator based on PDF version.
586          */
587         function TextWrapCalc($txt, $width, $spacebreak=false)
588         {
589                 // Assume an average character width
590                 $avg_char_width = 5;
591                 $ret = "";
592                 $txt2 = $txt;
593                 $w = strlen($txt) * $avg_char_width;
594                 if ($w > $width && $w > 0 && $width != 0)
595                 {
596                         $n = strlen($txt);
597                         $k = intval($n * $width / $w);
598                         if ($k > 0 && $k < $n)
599                         {
600                                 $txt2 = substr($txt, 0, $k);
601                                 if ($spacebreak && (($pos = strrpos($txt2, " ")) !== false))
602                                 {
603                                         $txt2 = substr($txt2, 0, $pos);
604                                         $ret = substr($txt, $pos+1);
605                                 }
606                                 else
607                                         $ret = substr($txt, $k);
608                         }
609                 }
610                 return array($txt2, $ret);
611         }
612
613         function SetLineStyle($style)
614         {
615                 return;
616         }
617
618         function SetLineWidth($width)
619         {
620                 return;
621         }
622         
623         function LineTo($from, $row, $to, $row2)
624         {
625                 return;
626         }
627
628         function Line($row, $height = 0)
629         {
630                 return;
631         }
632
633         function UnderlineCell($c, $r = 0, $type = 1, $linewidth = 0, $style = array())
634         {
635                 return;
636         }
637         
638         function NewLine($l=1, $np=0, $h=NULL)
639         {
640                 $this->y += $l;
641         }
642         
643         function NewPage()
644         {
645                 if (method_exists($this, $this->headerFunc))    // draw predefined page layout if any
646                         $this->{$this->headerFunc}();
647         }
648         
649         function ymd2Date($year, $mon, $day) // XLS internal date representation is a number between 1900-01-01 and 2078-12-31
650         {                                                                               // if we need the time part too, we have to add this value after a decimalpoint.
651         $mo = array(0,31,28,31,30,31,30,31,31,30,31,30,31);
652         $BASE = 1900;
653                 $MAXYEAR = 2075;
654                 if (($year % 4) == 0)
655                 $mo[2]++;
656         if ($mon < 1)
657             $mon = 1;
658         elseif ($mon > 12)
659             $mon = 12;
660         if ($day < 1)
661             $day = 1;
662         elseif ($day > $mo[$mon])
663             $day = $mo[$mon];
664         if ($year < $BASE)
665             $year = $BASE;
666         elseif ($year > $MAXYEAR)
667             $year = $MAXYEAR;
668         $jul = (int)$day;
669         for ($n = 1; $n < $mon; $n++)
670         {
671             $jul += $mo[$n];
672         }
673         for ($n = $BASE; $n < $year; $n++)
674         {
675             $jul += 365;
676             if (($n % 4) == 0)
677                 $jul++;
678         }
679         return $jul;
680         }
681   
682         function px2units($px) // XLS app conversion. Not bulletproof.
683         {
684                 $excel_column_width_factor = 256;
685                 $unit_offset_length = $this->excelColWidthFactor;
686                 return ($px / $unit_offset_length);
687         }       
688
689         function End($email=0, $subject=null, $myrow=null, $doctype = 0)
690         {
691                 ++$this->y;
692                 for ($i = 0; $i < $this->numcols; $i++)
693                         $this->sheet->writeBlank($this->y, $i, $this->formatFooter);
694                 $this->sheet->mergeCells($this->y, 0, $this->y, $this->numcols - 1);
695                 $this->close();
696                 // first have a look through the directory, 
697                 // and remove old temporary pdfs
698                 if ($d = @opendir($this->path)) {
699                         while (($file = readdir($d)) !== false) {
700                                 if (!is_file($this->path.'/'.$file) || $file == 'index.php') continue;
701                                 // then check to see if this one is too old
702                                 $ftime = filemtime($this->path.'/'.$file);
703                                 // seems 3 min is enough for any report download, isn't it?
704                                 if (time()-$ftime > 180){
705                                         unlink($this->path.'/'.$file);
706                                 }
707                         }
708                         closedir($d);
709                 }
710                 meta_forward($_SERVER['PHP_SELF'], "xls=1&filename=$this->filename&unique=$this->unique_name");
711                 exit();
712         }
713 }
714
715 ?>