Files
crm.twinpol.com/emails/PHPReport-master/PHPReport.php
2025-05-12 15:44:39 +00:00

1050 lines
31 KiB
PHP
Executable File

<?php
/**
* PHPReport
* Library for generating reports from PHP
* Copyright (c) 2012 PHPReport
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*
* @package PHPReport
* @author Vernes Šiljegović
* @copyright Copyright (c) 2012 PHPReport
* @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt LGPL
* @version 1.1, 2013-01-06
*/
/**
* PHPExcel
*
* @copyright Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)
*/
require_once 'PHPExcel.php';
class PHPReport {
//report template
private $_templateDir;
private $_template;
private $_usingTemplate;
//internal collections of data
private $_data=array();
private $_search=array();
private $_replace=array();
private $_group=array();
private $_lastColumn='A';
private $_lastRow=1;
//parameters
private $_renderHeading=false;
private $_useStripRows=false;
private $_headingText;
private $_noResultText;
//styling
private $_headerStyleArray = array(
'font' => array(
'bold' => true,
'color' => array(
'rgb' => 'FFFFFF'
)
),
'fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'startcolor' => array(
'rgb' => '4E5A7A'
)
)
);
private $_footerStyleArray = array(
'font' => array(
'bold' => true,
),
'fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'startcolor' => array(
'rgb' => 'E4E8F3',
)
)
);
private $_headerGroupStyleArray = array(
'alignment' => array(
'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_LEFT
),
'font' => array(
'bold' => true
),
'fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'startcolor' => array(
'rgb' => '8DB4E3'
)
)
);
private $_footerGroupStyleArray = array(
'font' => array(
'bold' => true
),
'fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'startcolor' => array(
'rgb' => 'C5D9F1'
)
)
);
private $_noResultStyleArray = array(
'borders' => array(
'outline' => array(
'style' => PHPExcel_Style_Border::BORDER_THIN
)
),
'alignment' => array(
'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER
),
'font' => array(
'bold' => true
),
'fill' => array(
'type' => PHPExcel_Style_Fill::FILL_SOLID,
'startcolor' => array(
'rgb' => 'FFEBA5'
)
)
);
private $_headingStyleArray = array(
'font' => array(
'bold' => true,
'color' => array(
'rgb' => '4E5A7A'
),
'size' => '24'
),
'alignment' => array(
'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER
)
);
//PHPExcel objects
private $objReader;
private $objPHPExcel;
private $objWorksheet;
private $objWriter;
/**
* Creates new report with some configuration parameters
* @param array $config
*/
public function __construct($config=array())
{
$this->setConfig($config);
$this->init();
}
/**
* Uses configuration array to adjust report parameters
* @param array $config
*/
public function setConfig($config)
{
if(!is_array($config))
throw new Exception('Unable to use non-array configuration');
foreach($config as $key=>$value)
{
$_key='_'.$key;
$this->$_key=$value;
}
}
/**
* Initializes internal objects
*/
private function init()
{
if($this->_template!='')
{
$this->loadTemplate();
}
else
{
$this->createTemplate();
}
}
/**
* Loads Excel file as a template for report
*/
public function loadTemplate($template='')
{
if($template!='')
$this->_template=$template;
if(!is_file($this->_templateDir.$this->_template))
throw new Exception('Unable to load template file: '.$this->_templateDir.$this->_template);
//identify type of template file
$inputFileType = PHPExcel_IOFactory::identify($this->_templateDir.$this->_template);
//TODO: better control of allowed input types
//load template file into PHPExcel objects
$this->objReader = PHPExcel_IOFactory::createReader($inputFileType);
$this->objPHPExcel = $this->objReader->load($this->_templateDir.$this->_template);
$this->objWorksheet = $this->objPHPExcel->getActiveSheet();
$this->_usingTemplate=true;
}
/**
* Creates PHPExcel object and template for report
*/
private function createTemplate()
{
$this->objPHPExcel = new PHPExcel();
$this->objPHPExcel->setActiveSheetIndex(0);
$this->objWorksheet = $this->objPHPExcel->getActiveSheet();
//TODO: other parameters
$this->objWorksheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT);
$this->objWorksheet->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);
$this->objWorksheet->getPageSetup()->setHorizontalCentered(true);
$this->objWorksheet->getPageSetup()->setVerticalCentered(false);
$this->_usingTemplate=false;
}
/**
* Takes an array of all the data for report
*
* @param array $dataCollection Associative array with data for report
* or an array of such arrays
* id - unique identifier of data group
* data - Single array of data
*/
public function load($dataCollection)
{
if(!is_array($dataCollection))
throw new Exception("Could not load a non-array data!");
//clear current data
$this->clearData();
//check if it is a single array of data
if(isset ($dataCollection['data']))
{
$this->addData($dataCollection);
}
else
{
//it's an array of arrays of data, add all
foreach($dataCollection as $data)
$this->addData($data);
}
}
/**
* Takes an array of all the data for report
*
* @param array $data Associative array with two elements
* id - unique identifier of data group
* data - Single array of data
*/
private function addData($data)
{
if(!is_array($data))
throw new Exception("Could not load a non-array data!");
if(!isset ($data['id']))
throw new Exception("Every array of data needs an 'id'!");
if(!isset ($data['data']))
throw new Exception("Loaded array needs an element 'data'!");
$this->_data[]=$data;
}
/**
* Clears internal collection of data
*/
private function clearData()
{
$this->_data=array();
}
/**
*Creates a new report based on loaded data
*/
public function createReport()
{
foreach($this->_data as $data)
{
//$data must have id and data elements
//$data may also have config, header, footer, group
$id=$data['id'];
$format=isset($data['format'])?$data['format']:array();
$config=isset($data['config'])?$data['config']:array();
$group=isset($data['group'])?$data['group']:array();
$configHeader=isset($config['header'])?$config['header']:$config;
$configData=isset($config['data'])?$config['data']:$config;
$configFooter=isset($config['footer'])?$config['footer']:$config;
$config=array(
'header'=>$configHeader,
'data'=>$configData,
'footer'=>$configFooter
);
//set the group
$this->_group=$group;
$loadCollection=array();
$nextRow=$this->objWorksheet->getHighestRow();
if($nextRow>1)
$nextRow++;
$colIndex=-1;
//form the header for data
if(isset($data['header']))
{
$headerId='HEADER_'.$id;
foreach($data['header'] as $k=>$v)
{
$colIndex++;
$tag="{".$headerId.":".$k."}";
$this->objWorksheet->setCellValueByColumnAndRow($colIndex,$nextRow,$tag);
if(isset($config['header'][$k]['width']))
$this->objWorksheet->getColumnDimensionByColumn($colIndex)->setWidth(pixel2unit($config['header'][$k]['width']));
if(isset($config['header'][$k]['align']))
$this->objWorksheet->getStyleByColumnAndRow($colIndex,$nextRow)->getAlignment()->setHorizontal($config['header'][$k]['align']);
}
if($colIndex>-1)
{
$this->objWorksheet->getStyle(PHPExcel_Cell::stringFromColumnIndex(0).$nextRow.':'.PHPExcel_Cell::stringFromColumnIndex($colIndex).$nextRow)->applyFromArray($this->_headerStyleArray);
}
//add header row to load collection
$loadCollection[]=array('id'=>$headerId,'data'=>$data['header']);
//move to next row for data
$nextRow++;
}
//form the data repeating row
$dataId='DATA_'.$id;
$colIndex=-1;
//form the template row
if(count($data['data'])>0)
{
//we just need first row of data, to see array keys
$singleDataRow=$data['data'][0];
foreach($singleDataRow as $k=>$v)
{
$colIndex++;
$tag="{".$dataId.":".$k."}";
$this->objWorksheet->setCellValueByColumnAndRow($colIndex,$nextRow,$tag);
if(isset($config['data'][$k]['align']))
$this->objWorksheet->getStyleByColumnAndRow($colIndex,$nextRow)->getAlignment()->setHorizontal($config['data'][$k]['align']);
}
}
//add this row to collection for load but with repeating
$loadCollection[]=array('id'=>$dataId,'data'=>$data['data'],'repeat'=>true,'format'=>$format);
$this->enableStripRows();
//form the footer row for data if needed
if(isset($data['footer']))
{
$footerId='FOOTER_'.$id;
$colIndex=-1;
$nextRow++;
//formiraj template
foreach($data['footer'] as $k=>$v)
{
$colIndex++;
$tag="{".$footerId.":".$k."}";
$this->objWorksheet->setCellValueByColumnAndRow($colIndex,$nextRow,$tag);
if(isset($config['footer'][$k]['align']))
$this->objWorksheet->getStyleByColumnAndRow($colIndex,$nextRow)->getAlignment()->setHorizontal($config['footer'][$k]['align']);
}
if($colIndex>-1)
{
$this->objWorksheet->getStyle(PHPExcel_Cell::stringFromColumnIndex(0).$nextRow.':'.PHPExcel_Cell::stringFromColumnIndex($colIndex).$nextRow)->applyFromArray($this->_footerStyleArray);
}
//add footer row to load collection
$loadCollection[]=array('id'=>$footerId,'data'=>$data['footer'],'format'=>$format);
}
$this->load($loadCollection);
$this->generateReport();
}
}
/**
* Generates report based on loaded data
*/
public function generateReport()
{
$this->_lastColumn=$this->objWorksheet->getHighestColumn();//TODO: better detection
$this->_lastRow=$this->objWorksheet->getHighestRow();
foreach($this->_data as $data)
{
if(isset ($data['repeat']) && $data['repeat']==true)
{
//Repeating data
$foundTags=false;
$repeatRange='';
$firstRow='';
$lastRow='';
$firstCol='A';//TODO: better detection
$lastCol=$this->_lastColumn;
//scan the template
//search for repeating part
foreach ($this->objWorksheet->getRowIterator() as $row)
{
$cellIterator = $row->getCellIterator();
$rowIndex = $row->getRowIndex();
//find the repeating range (one or more rows)
foreach ($cellIterator as $cell)
{
$cellval=trim($cell->getValue());
$column = $cell->getColumn();
//see if the cell has something for replacing
if(preg_match_all("/\{".$data['id'].":(\w*|#\+?-?(\d*)?)\}/", $cellval, $matches))
{
//this cell has replacement tags
if(!$foundTags) $foundTags=true;
//remember the first ant the last row
if($rowIndex!=$firstRow)
$lastRow=$rowIndex;
if($firstRow=='')
$firstRow=$rowIndex;
}
}
}
//form the repeating range
if($foundTags)
$repeatRange=$firstCol.$firstRow.":".$lastCol.$lastRow;
//check if this is the last row
if($foundTags && $lastRow==$this->_lastRow)
$data['last']=true;
//set initial format data
if(! isset($data['format']))
$data['format']=array();
//set default step as 1
if(! isset($data['step']))
$data['step']=1;
//check if data is an array
if(is_array($data['data']))
{
//every element is an array with data for all the columns
if($foundTags)
{
//insert repeating rows, as many as needed
//check if grouping is defined
if(count($this->_group))
$this->generateRepeatingRowsWithGrouping($data, $repeatRange);
else
$this->generateRepeatingRows($data, $repeatRange);
//remove the template rows
for($i=$firstRow;$i<=$lastRow;$i++)
{
$this->objWorksheet->removeRow($firstRow);
}
//if there is no data
if(count($data['data'])==0)
$this->addNoResultRow($firstRow,$firstCol,$lastCol);
}
}
else
{
//TODO
//maybe an SQL query?
//needs to be database agnostic
}
}
else
{
//non-repeating data
//check for additional formating
if(! isset($data['format']))
$data['format']=array();
//check if data is an array or mybe a SQL query
if(is_array($data['data']))
{
//array of data
$this->generateSingleRow($data);
}
else
{
//TODO
//maybe an SQL query?
//needs to be database agnostic
}
}
}
//call the replacing function
$this->searchAndReplace();
//generate heading if heading text is set
if($this->_headingText!='')
$this->generateHeading();
}
/**
* Generates single non-repeating row of data
* @param array $data
*/
private function generateSingleRow(& $data)
{
$id=$data['id'];
$format=$data['format'];
foreach($data['data'] as $key=>$value)
{
$search="{".$id.":".$key."}";
$this->_search[]=$search;
//if it needs formating
if(isset($format[$key]))
{
foreach($format[$key] as $ftype=>$f)
{
$value=$this->formatValue($value,$ftype,$f);
}
}
$this->_replace[]=$value;
}
}
/**
* Generates repeating rows of data with some template range
* @param array $data
* @param string $repeatRange
*/
private function generateRepeatingRows(& $data, $repeatRange)
{
$rowCounter=0;
$repeatTemplateArray=$this->objWorksheet->rangeToArray($repeatRange,null,true,true,true);
//insert repeating rows but first check for minimum number of rows
if(isset($data['minRows']))
{
$minRows=(int)$data['minRows'];
}
else
$minRows=0;
//is this the last data
if(isset($data['last']))
$last=$data['last'];
else
$last=false;
$templateKeys=array_keys($repeatTemplateArray);
$lastRowFoundAt=end($templateKeys);
$firstRowFoundAt=reset($templateKeys);
$rowsFound=count($repeatTemplateArray);
$mergeCells=$this->objWorksheet->getMergeCells();
$needMerge=array();
foreach($mergeCells as $mergeCell)
{
if($this->isSubrange($mergeCell, $repeatRange))
{
//contains merged cells, save for later
$needMerge[]=$mergeCell;
}
}
//check if any new rows need to bi inserted
$dataRows=count($data['data']);
if($minRows<$dataRows)
$this->objWorksheet->insertNewRowBefore($lastRowFoundAt+1,$rowsFound * ($dataRows - $minRows));
//check all the data
foreach ($data['data'] as $value)
{
$rowCounter++;
$skip=$rowCounter*$rowsFound;
$newRowIndex=$firstRowFoundAt+$skip;
//copy merge definitions
foreach($needMerge as $nm)
{
$nm=PHPExcel_Cell::rangeBoundaries($nm);
$newMerge=PHPExcel_Cell::stringFromColumnIndex($nm[0][0]-1).($nm[0][1]+$skip).":".PHPExcel_Cell::stringFromColumnIndex($nm[1][0]-1).($nm[1][1]+$skip);
$this->objWorksheet->mergeCells($newMerge);
}
//generate row of data
$this->generateSingleRepeatingRow($value, $repeatTemplateArray, $rowCounter, $skip, $data['id'], $data['format'], $data['step']);
}
//remove merge on template, BUG fix
foreach($needMerge as $nm)
{
$this->objWorksheet->unmergeCells($nm);
}
}
/**
* Generates repeating rows of data with some template range but also with grouping
* @param array $data
* @param string $repeatRange
*/
private function generateRepeatingRowsWithGrouping(& $data, $repeatRange)
{
$rowCounter=0;
$groupCounter=0;
$footerCount=0;
$repeatTemplateArray=$this->objWorksheet->rangeToArray($repeatRange,null,true,true,true);
//insert repeating rows but first check for minimum number of rows
if(isset($data['minRows']))
{
$minRows=(int)$data['minRows'];
}
else
$minRows=0;
$templateKeys=array_keys($repeatTemplateArray);
$lastRowFoundAt=end($templateKeys);
$firstRowFoundAt=reset($templateKeys);
$rowsFound=count($repeatTemplateArray);
list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($repeatRange);
$firstCol=PHPExcel_Cell::stringFromColumnIndex($rangeStart[0]-1);
$lastCol=PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]-1);
$mergeCells=$this->objWorksheet->getMergeCells();
$needMerge=array();
foreach($mergeCells as $mergeCell)
{
if($this->isSubrange($mergeCell, $repeatRange))
{
//contains merged cells, save for later
$needMerge[]=$mergeCell;
}
}
//group array should have header, rows and summary elements
foreach($this->_group['rows'] as $name=>$rows)
{
$groupCounter++;
$caption=$this->_group['caption'][$name];
$newRowIndex=$firstRowFoundAt+$rowCounter*$rowsFound+$footerCount*$rowsFound+$groupCounter;
//insert header for the group
$this->objWorksheet->insertNewRowBefore($newRowIndex,1);
$this->objWorksheet->setCellValue($firstCol.$newRowIndex,$caption);
$this->objWorksheet->mergeCells($firstCol.$newRowIndex.":".$lastCol.$newRowIndex);
//add style for the header
$this->objWorksheet->getStyle($firstCol.$newRowIndex)->applyFromArray($this->_headerGroupStyleArray);
//add data for the group
foreach ($rows as $row)
{
$value=$data['data'][$row];
$rowCounter++;
$skip=$rowCounter*$rowsFound+$footerCount*$rowsFound+$groupCounter;
$newRowIndex=$firstRowFoundAt+$skip;
//insert one or more rows if needed
if($minRows<$rowCounter)
$this->objWorksheet->insertNewRowBefore($newRowIndex,$rowsFound);
//copy merge definitions
foreach($needMerge as $nm)
{
$nm=PHPExcel_Cell::rangeBoundaries($nm);
$newMerge=PHPExcel_Cell::stringFromColumnIndex($nm[0][0]-1).($nm[0][1]+$skip).":".PHPExcel_Cell::stringFromColumnIndex($nm[1][0]-1).($nm[1][1]+$skip);
$this->objWorksheet->mergeCells($newMerge);
}
//generate row of data
$this->generateSingleRepeatingRow($value, $repeatTemplateArray, $rowCounter, $skip, $data['id'], $data['format'], $data['step']);
}
//include the footer if defined
if(isset($this->_group['summary']) && isset($this->_group['summary'][$name]))
{
$footerCount++;
$skip=$groupCounter+$rowCounter*$rowsFound+$footerCount*$rowsFound;
$newRowIndex=$firstRowFoundAt+$skip;
$this->objWorksheet->insertNewRowBefore($newRowIndex,$rowsFound);
$this->generateSingleRepeatingRow($this->_group['summary'][$name], $repeatTemplateArray, '', $skip, $data['id'], $data['format'], $data['step']);
//add style for the footer
$this->objWorksheet->getStyle($firstCol.$newRowIndex.":".$lastCol.$newRowIndex)->applyFromArray($this->_footerGroupStyleArray);
}
//remove merge on template, BUG fix
foreach($needMerge as $nm)
{
$this->objWorksheet->unmergeCells($nm);
}
}
}
/**
* Generates single row for repeating data
* @param array $value
* @param array $repeatTemplateArray
* @param int $rowCounter
* @param int $skip
* @param string $id
* @param array $format
* @param int $step
*/
private function generateSingleRepeatingRow(& $value, & $repeatTemplateArray, $rowCounter, $skip, $id, $format, $step)
{
foreach($repeatTemplateArray as $rowKey=>$rowData)
{
foreach($rowData as $col=>$tag)
{
//$col is like A, B, C, ...
//$rowKey is like 9,10,11, ...
//$tag can have many replacement tags, e.g. "{item:item_id} --- {item:item_code}"
if(preg_match_all("/\{".$id.":(\w*|#\+?-?(\d*)?)\}/", $tag, $matches))
{
$matchTags=$matches[0]; //array with complete tags, e.g. '{item:item_id}'
$matchKeys=$matches[1]; //array with only the key names, e.g. 'item_id'
$matchNumber=count($matchTags); //how many replacement tags is there in this cell
$replaceTags=array();
$replaceValues=array();
foreach($matchKeys as $mkey)
{
$replaceTags[]="{".$id.":".$mkey."}";
if(strpos($mkey, "#")===0)
{
//this is a counter (optional offset)
$offset=explode("+", $mkey);
if(count($offset)>1)
$offset=$offset[1];
else
$offset=0;
$rValue=($rowCounter-1)*$step+1+(int)$offset;
}
elseif(key_exists($mkey, $value))
{
//format if needed
if(isset($format) && isset($format[$mkey]))
{
foreach($format[$mkey] as $ftype=>$f)
{
$rValue=$this->formatValue($value[$mkey],$ftype,$f);
}
}
else
{
//without additional formating
$rValue=$value[$mkey];
}
}
else
$rValue=$mkey;
//add to replace array
$replaceValues[]=$rValue;
}
//replace all the values in this cell
$tag=str_replace($replaceTags,$replaceValues,$tag);
}
$newCellAddress=$col.($rowKey+$skip);
$this->objWorksheet->setCellValue($newCellAddress,$tag);
//copy cell styles
$xfIndex=$this->objWorksheet->getCell($col.$rowKey)->getXfIndex();
$this->objWorksheet->getCell($newCellAddress)->setXfIndex($xfIndex);
//strip rows if requested
if($this->_useStripRows && $rowCounter%2)
{
$this->objWorksheet->getStyle($newCellAddress)->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
$this->objWorksheet->getStyle($newCellAddress)->getFill()->getStartColor()->setRGB('F2F2F2');
}
}
}
}
/**
* Check and apply various formating
*/
/**
* Applies various formatings
* Type can be datetime or number
* @param mixed $value
* @param string $type
* @param mixed $format
*/
protected function formatValue($value,$type,$format)
{
if($type=='datetime')
{
//format can only be string
if(is_string($format))
$value=date($format, strtotime($value));
}
elseif($type=='number')
{
//format must be an array
if(is_array($format))
{
//set the defaults
if(!isset($format['prefix']))
$format['prefix']='';
if(!isset($format['decimals']))
$format['decimals']=0;
if(!isset($format['decPoint']))
$format['decPoint']='.';
if(!isset($format['thousandsSep']))
$format['thousandsSep']=',';
if(!isset($format['sufix']))
$format['sufix']='';
$value=$format['prefix'].number_format($value,$format['decimals'],$format['decPoint'],$format['thousandsSep']).$format['sufix'];
}
}
return $value;
}
/**
* Replaces all the cells with real data
*/
private function searchAndReplace()
{
foreach ($this->objWorksheet->getRowIterator() as $row)
{
$cellIterator = $row->getCellIterator();
foreach ($cellIterator as $cell)
{
$cell->setValue(str_replace($this->_search, $this->_replace, $cell->getValue()));
}
}
}
/**
* Adda a row for repeating data when there is no results
* @param int $rowIndex
* @param string $colMin
* @param string $colMax
*/
private function addNoResultRow($rowIndex,$colMin,$colMax)
{
//insert one row
$this->objWorksheet->insertNewRowBefore($rowIndex);
//merge as required
$this->objWorksheet->mergeCells($colMin.$rowIndex.":".$colMax.$rowIndex);
//insert text
$this->objWorksheet->setCellValue($colMin.$rowIndex, $this->_noResultText);
$this->objWorksheet->getStyle($colMin.$rowIndex.":".$colMax.$rowIndex)->applyFromArray($this->_noResultStyleArray);
}
/**
* Generates heading title of the report
*/
private function generateHeading()
{
//get current dimensions
$highestRow = $this->objWorksheet->getHighestRow(); // e.g. 10
$highestColumn = $this->objWorksheet->getHighestColumn(); // e.g 'F'
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn);
//insert row on top
$this->objWorksheet->insertNewRowBefore(1,2);
//merge cells
$this->objWorksheet->mergeCells("A1:".$highestColumn."1");
//set the text for header
$this->objWorksheet->setCellValue("A1", $this->_headingText);
$this->objWorksheet->getStyle('A1')->getAlignment()->setWrapText(true);
$this->objWorksheet->getRowDimension('1')->setRowHeight(48);
//Apply style
$this->objWorksheet->getStyle("A1")->applyFromArray($this->_headingStyleArray);
}
/**
* Renders report as specified output file
* @param string $type
* @param string $filename
*/
public function render($type='html',$filename='')
{
//create or generate report
if($this->_usingTemplate)
$this->generateReport();
else
$this->createReport();
if($type=='')
$type="html";
if($filename=='')
$filename="Report ".date("Y-m-d");
else
$filename=strftime($filename);
//http://strftime.net/
if(strtolower($type)=='html')
return $this->renderHtml();
elseif(strtolower($type)=='excel')
return $this->renderXlsx($filename);
elseif(strtolower($type)=='excel2003')
return $this->renderXls($filename);
elseif(strtolower($type)=='pdf')
return $this->renderPdf($filename);
else
return "Error: unsupported export type!"; //TODO: better error handling
}
/**
* Renders report as a HTML output
*/
private function renderHtml()
{
$this->objWriter = new PHPExcel_Writer_HTML($this->objPHPExcel);
// Generate HTML
$html = '';
$html .= $this->objWriter->generateHTMLHeader(true);
$html .= $this->objWriter->generateSheetData();
$html .= $this->objWriter->generateHTMLFooter();
$html .= '';
$this->objPHPExcel->disconnectWorkSheets();
unset($this->objWriter);
unset($this->objWorksheet);
unset($this->objReader);
unset($this->objPHPExcel);
return $html;
}
/**
* Renders report as a XLSX file
*/
private function renderXlsx($filename)
{
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'.$filename.'.xlsx"');
header('Cache-Control: max-age=0');
$this->objWriter = PHPExcel_IOFactory::createWriter($this->objPHPExcel, 'Excel2007');
$this->objWriter->save('php://output');
unset($this->objWriter);
unset($this->objWorksheet);
unset($this->objReader);
unset($this->objPHPExcel);
exit();
}
/**
* Renders report as a XLS file
*/
private function renderXls($filename)
{
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="'.$filename.'.xls"');
header('Cache-Control: max-age=0');
$this->objWriter = PHPExcel_IOFactory::createWriter($this->objPHPExcel, 'Excel5');
$this->objWriter->save('php://output');
unset($this->objWriter);
unset($this->objWorksheet);
unset($this->objReader);
unset($this->objPHPExcel);
exit();
}
/**
* Renders report as a PDF file
*/
private function renderPdf($filename)
{
header('Content-Type: application/vnd.pdf');
header('Content-Disposition: attachment;filename="'.$filename.'.pdf"');
header('Cache-Control: max-age=0');
$this->objWriter = PHPExcel_IOFactory::createWriter($this->objPHPExcel, 'PDF');
$this->objWriter->save('php://output');
exit();
}
/**
* Helper function for checking subranges of a range
*/
public function isSubrange($subRange,$range)
{
list($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($range);
list($subrangeStart,$subrangeEnd) = PHPExcel_Cell::rangeBoundaries($subRange);
return (($subrangeStart[0]>=$rangeStart[0]) && ($subrangeStart[1]>=$rangeStart[1]) && ($subrangeEnd[0]<=$rangeEnd[0]) && ($subrangeEnd[1]<=$rangeEnd[1]));
}
/**
* Enabling strip rows
*/
function enableStripRows()
{
$this->_useStripRows=true;
}
/**
* Sets title of the report header
*/
function setHeading($h)
{
$this->_headingText=$h;
}
}
/**
* converts pixels to excel units
* @param float $p
* @return float
*/
function pixel2unit($p)
{
return ($p-5)/7;
}