_fileName = str_replace(' ', '-', $report->getTitle());
$objPHPExcel = new \PHPExcel();
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$this->_objReport = $report;
$this->_format = $report->getFormat();
$this->_queries = $report->getQueries();
$this->_headers = $report->getHeaders();
$this->_fields = $report->getFields();
$this->_totals = $report->getTotalFields();
$this->_currencyFields = $report->getCurrencyFields();
$this->_notes = $report->getNotes();
$this->_chart = $report->getChart();
$this->_data = $report->getData();
$this->_objWriter = $objWriter;
$this->_objPHPExcel = $objPHPExcel;
$this->_objPHPExcel->getProperties()->setCreator(APPLICATION);
$this->_objPHPExcel->getProperties()->setLastModifiedBy(APPLICATION);
$this->_objPHPExcel->getProperties()->setTitle($report->getTitle());
$this->_objPHPExcel->getProperties()->setSubject($report->getSubject());
$this->_objPHPExcel->getProperties()->setDescription($report->getDescription());
$this->_addLogo();
$numQueries = count($this->_queries);
$numRecords = count($this->_data);
$numNotes = count($this->_notes);
$numChart = !empty($this->_chart)
? 15 : 0;
$numTotals = (!empty($this->_totals))
? 1
: 0;
if ($numQueries)
{
$this->_writeQueries(2);
$numQueries += 2;
}
$this->_createHeaders(2 + $numQueries);
$this->_writeRecords(3 + $numQueries);
if (!empty($this->_totals))
{
$this->_writeTotals(3 + $numQueries + $numRecords);
}
$this->_setCurrencyFormat(3 + $numQueries, $numRecords + $numTotals);
if ($numChart)
{
$this->_writeChart(
5 + $numQueries + $numRecords,
3 + $numQueries,
2 + $numQueries + $numRecords
);
$this->_objWriter->setIncludeCharts(true);
$numChart += 2;
}
if ($numNotes)
{
$this->_writeNotes(5 + $numQueries + $numRecords + $numChart);
}
return $this;
}
/**
* Set formatting.
* @param string $format
* @return Struct_Abstract_ExcelReport
*/
public function setFormat($format)
{
$this->_format = $format;
return $this;
}
/**
* Output result.
* @todo add email, filesystem and ftp as potential targets.
* @param null|string $target
*/
public function output($target = null)
{
set_time_limit(900);
ini_set('memory_limit', '-1');
if (is_null($target))
{
#-> Direct output.
header("Content-Type: application/vnd.ms-excel");
header('Content-Disposition: attachment; filename="' .$this->_fileName.'_'. time() . '.xlsx"' );
$this->_objWriter->save('php://output');
}
elseif (strpos($target, '@'))
{
#-> Send to email.
}
else
{
#-> Write to file.
$this->_objWriter->save($target);
}
}
/**
* Add logo to top of spreadsheet.
*/
protected function _addLogo()
{
$totalCols = count($this->_headers);
// Add a drawing to the worksheet
$objDrawing = new \PHPExcel_Worksheet_Drawing();
$objDrawing->setName('Logo');
$objDrawing->setDescription('Logo');
$objDrawing->setPath(__DIR__ . '/../../../../../public/img/app/logos/logo-excel.png');
$objDrawing->setHeight(56);
$this->_objPHPExcel->getActiveSheet()->getRowDimension(1)->setRowHeight(56);
$style_logo = array(
'fill' => array(
'type' => \PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('rgb'=>'222222'),
)
);
$style_header = array(
'fill' => array(
'type' => \PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('rgb'=>'bbbbbb'),
),
'font' => array(
'bold' => true,
)
);
$convertTotalToString = $this->numberToColumn[$totalCols-1];
$this->_objPHPExcel->getActiveSheet()->getStyle("A1:{$convertTotalToString}1")->applyFromArray($style_logo);
$objDrawing->setWorksheet($this->_objPHPExcel->getActiveSheet());
}
/**
* Set text wrapping for specified column.
* @param integer $column
* @param boolean $wrap
*/
protected function _setColumnWrapping($column, $wrap = true)
{
$this->_objPHPExcel->getActiveSheet()->getStyle($column)->getAlignment()->setWrapText($wrap);
}
protected function _setCurrencyFormat($fromRow, $numRows)
{
foreach ($this->_currencyFields as $field)
{
$endRow = $fromRow + $numRows;
$labelInd = array_search($field, $this->_fields);
$labelInd = $this->numberToColumn[$labelInd];
$this->_objPHPExcel
->getActiveSheet()
->getStyle($labelInd . $fromRow . ':' . $labelInd . $endRow)
->getNumberFormat()
->setFormatCode(\Utility\Definitions\Locale::getExcelCurrencyFormat());
}
}
/**
* Insert report query details.
* @param integer $lineNumber
*/
protected function _writeQueries($lineNumber)
{
$convertTotalToString = $this->numberToColumn[count($this->_headers)-1];
$this->_objPHPExcel->getActiveSheet()->setCellValue('A'.$lineNumber, 'Filters applied to report:');
$style_header = array(
'fill' => array(
'type' => \PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('rgb'=>'aaaaaa'),
),
'font' => array(
'bold' => true,
)
);
$this->_objPHPExcel->getActiveSheet()->getStyle("A$lineNumber:$convertTotalToString".$lineNumber)->applyFromArray($style_header);
$lineNumber++;
foreach ($this->_queries as $param => $value)
{
$this->_objPHPExcel->getActiveSheet()->setCellValue('A'.$lineNumber, $param);
$this->_objPHPExcel->getActiveSheet()->setCellValue('B'.$lineNumber, $value);
$this->_objPHPExcel->getActiveSheet()->getStyle('A'.$lineNumber)->applyFromArray(
array(
'font' => array('bold' => true),
'alignment' => array('horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_LEFT),
'fill' => array(
'type' => \PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('rgb'=>'dddddd'),
))
);
$this->_objPHPExcel->getActiveSheet()->getStyle('A'.$lineNumber.':'.$convertTotalToString.$lineNumber)->applyFromArray(
array(
'alignment' => array('horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_LEFT),
'fill' => array(
'type' => \PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('rgb'=>'dddddd'),
))
);
$lineNumber++;
}
}
/**
* Insert report totals.
* @param integer $lineNumber
*/
protected function _writeTotals($lineNumber)
{
$i = 0;
$convertTotalToString = $this->numberToColumn[count($this->_headers)-1];
$this->_objPHPExcel->getActiveSheet()->getStyle($this->numberToColumn[$i].$lineNumber.':'.$convertTotalToString.$lineNumber)->applyFromArray(
array(
'font' => array('bold' => true),
'alignment' => array('horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_RIGHT),
'fill' => array(
'type' => \PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('rgb'=>'dddddd')
)
)
);
foreach ($this->_fields as $field)
{
if (isset($this->_totalAccum[$field]))
{
$this->_objPHPExcel->getActiveSheet()->setCellValue(
$this->numberToColumn[$i].$lineNumber,
$this->_totalAccum[$field]
);
}
$i++;
}
}
/**
* Insert report notes.
* @param integer $lineNumber
*/
protected function _writeNotes($lineNumber)
{
foreach ($this->_notes as $note)
{
$this->_objPHPExcel->getActiveSheet()->setCellValue('A'.$lineNumber, $note);
$this->_objPHPExcel->getActiveSheet()->getStyle('A'.$lineNumber)->applyFromArray(
array(
'font' => array('bold' => true),
'alignment' => array('horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_LEFT)
)
);
$lineNumber++;
}
}
/**
* Insert column headers.
* @param integer $lineNumber
*/
protected function _createHeaders($lineNumber)
{
$i = 0;
foreach($this->_headers as $key => $val)
{
$this->_objPHPExcel->getActiveSheet()->setCellValue($this->numberToColumn[$i].$lineNumber, $val);
$this->_objPHPExcel->getActiveSheet()->getStyle($this->numberToColumn[$i].$lineNumber)->applyFromArray(array('alignment' => array('horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_LEFT) ) );
$i++;
}
#-> Set column sizes
$this->_objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(30);
for ($i = 1; $i < count($this->_headers); $i++)
{
$this->_objPHPExcel->getActiveSheet()->getColumnDimension($this->numberToColumn[$i])->setAutoSize(true);
}
$this->_objPHPExcel->getActiveSheet()->duplicateStyleArray(
array(
'font' => array('bold' => true),
'alignment' => array('horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_LEFT),
'fill' => array(
'type' => \PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('rgb'=>'aaaaaa')
)
),
$this->numberToColumn[0]. $lineNumber .':'.$this->numberToColumn[$i - 1]. $lineNumber
);
}
/**
* Write data rows starting at specified line number.
* @param integer $lineNumber
*/
protected function _writeRecords($lineNumber)
{
//[green]$#,##0.00;[red]$(-#,##0.00)
if (!empty($this->_totals))
{
foreach ($this->_totals as $field)
{
$this->_totalAccum[$field] = 0;
}
}
$i = 0;
foreach ($this->_data as $record)
{
if (empty($record))
{
$lineNumber++;
continue;
}
if($i > 30000)
{
return;
}
// Totals
if (!empty($this->_totals))
{
foreach ($this->_totals as $field)
{
if (is_numeric($record[$field]))
{
$this->_totalAccum[$field] += $record[$field];
}
}
}
// Format record
$tmpRecord = array();
$style = isset($record['excel.rowStyle'])
? $record['excel.rowStyle']
: false;
foreach($this->_fields as $field)
{
$tmpRecord[] = $record[$field];
}
$this->_insertValues($tmpRecord, $lineNumber, 0, $style);
$lineNumber++;
$i++;
}
}
/**
* Insert cell values for a data row.
* @param array $values
* @param integer $lineNumber
* @param integer $offset
* @param string|false $style
*/
protected function _insertValues($values, $lineNumber, $offset = 0, $style = false)
{
$i = 0 + $offset;
if ('Totals' == $style)
{
$convertTotalToString = $this->numberToColumn[count($this->_headers)-1];
$this->_objPHPExcel->getActiveSheet()->getStyle($this->numberToColumn[$i].$lineNumber.':'.$convertTotalToString.$lineNumber)->applyFromArray(
array(
'font' => array('bold' => true),
'fill' => array(
'type' => \PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('rgb'=>'dddddd')
)
)
);
}
if ('Titles' == $style)
{
$convertTotalToString = $this->numberToColumn[count($this->_headers)-1];
$this->_objPHPExcel->getActiveSheet()->getStyle($this->numberToColumn[$i].$lineNumber.':'.$convertTotalToString.$lineNumber)->applyFromArray(
array(
'font' => array('bold' => true),
'alignment' => array('horizontal' => \PHPExcel_Style_Alignment::HORIZONTAL_LEFT),
'fill' => array(
'type' => \PHPExcel_Style_Fill::FILL_SOLID,
'color' => array('rgb'=>'aaaaaa')
)
)
);
}
foreach ($values as $key => $val)
{
if (is_a($val, 'DateTime'))
{
$this->_objPHPExcel->getActiveSheet()->getCell($this->numberToColumn[$i].$lineNumber)
->setValueExplicit(
utf8_encode(
$val->format(\Utility\Definitions\Locale::getDateTimeFormat())
), \PHPExcel_Cell_DataType::TYPE_STRING
);
$i++;
continue;
}
$output = $values[$key];
if (strpos($val, "
") || strpos($val, "
") || strpos($val, "
"))
{
$this->_setColumnWrapping($this->numberToColumn[$i], true);
}
$output = str_replace(array("
", "
", "
"), "\r", $output);
$output = str_replace(
array('/', '&', '�'),
array('-', 'and', ' degrees'),
$output
);
$output = str_replace(
array("", "", "", "", "", "", "\\", "(", ")"),
'',
$output
);
/* $replacable = array("", "", "", "", "", "", "\\", "(", ")");
foreach($replacable as $val)
{
$output = str_replace(
array($val, '/', '&', '�'),
array('', ' - ', 'and', ' degrees'),
$output
);
} */
$type = is_numeric($output)
? \PHPExcel_Cell_DataType::TYPE_NUMERIC
: \PHPExcel_Cell_DataType::TYPE_STRING;
$this->_objPHPExcel->getActiveSheet()->getCell($this->numberToColumn[$i].$lineNumber)
->setValueExplicit(
utf8_encode($output), $type
);
$i++;
}
}
protected function _writeChart($lineNumber, $dataStart, $dataEnd)
{
$dataCount = $dataEnd - $dataStart;
$labelRow = $dataStart - 1;
$labelInd = array_search($this->_chart['LabelSource'], $this->_fields);
$labelInd = $this->numberToColumn[$labelInd];
$labels = array();
$categories = array();
$values = array();
foreach ($this->_chart['DataSource'] as $field)
{
$fieldInd = array_search($field, $this->_fields);
$fieldInd = $this->numberToColumn[$fieldInd];
$labels[] = new \PHPExcel_Chart_DataSeriesValues(
'String',
'Worksheet!$' . $fieldInd . '$' . $labelRow,
null, 1
);
$categories[] = new \PHPExcel_Chart_DataSeriesValues(
'String',
'Worksheet!$' . $labelInd . '$' . $dataStart . ':$' . $labelInd . '$' . $dataEnd,
null, $dataCount
);
$values[] = new \PHPExcel_Chart_DataSeriesValues(
'Number',
'Worksheet!$' . $fieldInd . '$' . $dataStart . ':$' . $fieldInd . '$' . $dataEnd,
null, $dataCount
);
}
$sheet = $this->_objPHPExcel->getActiveSheet();
$series = new \PHPExcel_Chart_DataSeries(
$this->_chart['Type'], // plotType
$this->_chart['Grouping'], // plotGrouping
$this->_chart['Order'], // plotOrder
$labels, // plotLabel
$categories, // plotCategory
$values // plotValues
);
$series->setPlotDirection(\PHPExcel_Chart_DataSeries::DIRECTION_COL);
$plotarea = new \PHPExcel_Chart_PlotArea(null, array($series));
$legend = new \PHPExcel_Chart_Legend(\PHPExcel_Chart_Legend::POSITION_RIGHT, null, false);
$chart = new \PHPExcel_Chart(
$this->_chart['Name'], // name
null, // title
$legend, // legend
$plotarea, // plotArea
true, // plotVisibleOnly
0, // displayBlanksAs
null, // xAxisLabel
null // yAxisLabel
);
$chart->setTopLeftPosition('A' . $lineNumber);
$chart->setBottomRightPosition('J' . ($lineNumber + 15));
$sheet->addChart($chart);
}
}