'.utils::EscapeHtml($oAttDef->GetEditValue($oObj->Get($sAttCode), $oObj)).'';
}
}
return ''.utils::EscapeHtml($this->GetValue($oObj, $sAttCode)).'
';
}
protected function GetValue($oObj, $sAttCode)
{
switch($sAttCode)
{
case 'id':
$sRet = $oObj->GetKey();
break;
default:
$value = $oObj->Get($sAttCode);
if ($value instanceOf ormCaseLog)
{
if (array_key_exists('formatted_text', $this->aStatusInfo) && $this->aStatusInfo['formatted_text'])
{
$sText = $value->GetText();
}
else
{
$sText = $value->GetAsPlainText();
}
// Extract the case log as text and remove the "===" which make Excel think that the cell contains a formula the next time you edit it!
$sRet = trim(preg_replace('/========== ([^=]+) ============/', '********** $1 ************', $sText));
}
else if ($value instanceOf DBObjectSet)
{
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
$sRet = $oAttDef->GetAsCSV($value, '', '', $oObj);
}
else if ($value instanceOf ormDocument)
{
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
$sRet = $oAttDef->GetAsCSV($value, '', '', $oObj);
}
else if ($value instanceOf ormSet)
{
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
$sRet = $oAttDef->GetAsCSV($value, '', '', $oObj);
}
else
{
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
if ($oAttDef instanceof AttributeDateTime)
{
// Date and times are formatted using the ISO encoding, not the localized format
if ($oAttDef->IsNull($value))
{
// NOt a valid date
$sRet = '';
}
else
{
$sRet = $value;
}
}
else if (array_key_exists('formatted_text', $this->aStatusInfo) && $this->aStatusInfo['formatted_text'])
{
if ($oAttDef instanceof AttributeText && $oAttDef->GetFormat()=='html')
{
$sRet = str_replace(">", ">", $value);
}
else
{
$sRet = $oAttDef->GetEditValue($value, $oObj);
}
}
else
{
$sRet = $oAttDef->GetAsPlainText($value, $oObj);
}
}
}
return $sRet;
}
public function GetHeader()
{
$oSet = new DBObjectSet($this->oSearch);
$this->aStatusInfo['status'] = 'retrieving';
$this->aStatusInfo['tmp_file'] = $this->MakeTmpFile('data');
$this->aStatusInfo['position'] = 0;
$this->aStatusInfo['total'] = $oSet->Count();
foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec)
{
$sExtendedAttCode = $aFieldSpec['sFieldSpec'];
$sAttCode = $aFieldSpec['sAttCode'];
$sColLabel = $aFieldSpec['sColLabel'];
switch($sAttCode)
{
case 'id':
$sType = '0';
break;
default:
$oAttDef = MetaModel::GetAttributeDef($aFieldSpec['sClass'], $aFieldSpec['sAttCode']);
$sType = 'string';
if($oAttDef instanceof AttributeDate)
{
$sType = 'date';
}
else if($oAttDef instanceof AttributeDateTime)
{
$sType = 'datetime';
}
}
$aTableHeaders[] = array('label' => $sColLabel, 'type' => $sType);
}
$sRow = json_encode($aTableHeaders);
$hFile = @fopen($this->aStatusInfo['tmp_file'], 'ab');
if ($hFile === false)
{
throw new Exception('ExcelBulkExport: Failed to open temporary data file: "'.$this->aStatusInfo['tmp_file'].'" for writing.');
}
fwrite($hFile, $sRow."\n");
fclose($hFile);
return '';
}
public function GetNextChunk(&$aStatus)
{
$sRetCode = 'run';
$iPercentage = 0;
$hFile = fopen($this->aStatusInfo['tmp_file'], 'ab');
$oSet = new DBObjectSet($this->oSearch);
$oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']);
$this->OptimizeColumnLoad($oSet);
$iCount = 0;
$iPreviousTimeLimit = ini_get('max_execution_time');
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
while($aRow = $oSet->FetchAssoc())
{
set_time_limit(intval($iLoopTimeLimit));
$aData = array();
foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec)
{
$sAlias = $aFieldSpec['sAlias'];
$sAttCode = $aFieldSpec['sAttCode'];
$oObj = $aRow[$sAlias];
$sField = '';
if ($oObj)
{
$sField = $this->GetValue($oObj, $sAttCode);
}
$aData[] = $sField;
}
fwrite($hFile, json_encode($aData)."\n");
$iCount++;
}
set_time_limit(intval($iPreviousTimeLimit));
$this->aStatusInfo['position'] += $this->iChunkSize;
if ($this->aStatusInfo['total'] == 0)
{
$iPercentage = 100;
$sRetCode = 'done'; // Next phase (GetFooter) will be to build the xlsx file
}
else
{
$iPercentage = floor(min(100.0, 100.0*$this->aStatusInfo['position']/$this->aStatusInfo['total']));
}
if ($iCount < $this->iChunkSize)
{
$sRetCode = 'done';
}
$aStatus = array('code' => $sRetCode, 'message' => Dict::S('Core:BulkExport:RetrievingData'), 'percentage' => $iPercentage);
return ''; // The actual XLSX file is built in GetFooter();
}
public function GetFooter()
{
$hFile = @fopen($this->aStatusInfo['tmp_file'], 'rb');
if ($hFile === false)
{
throw new Exception('ExcelBulkExport: Failed to open temporary data file: "'.$this->aStatusInfo['tmp_file'].'" for reading.');
}
$sHeaders = fgets($hFile);
$aHeaders = json_decode($sHeaders, true);
$aData = array();
while($sLine = fgets($hFile))
{
$aRow = json_decode($sLine);
$aData[] = $aRow;
}
fclose($hFile);
$fStartExcel = microtime(true);
$writer = new XLSXWriter();
$sDateFormat = isset($this->aStatusInfo['date_format']) ? $this->aStatusInfo['date_format'] : (string)AttributeDateTime::GetFormat();
$oDateTimeFormat = new DateTimeFormat($sDateFormat);
$writer->setDateTimeFormat($oDateTimeFormat->ToExcel());
$oDateFormat = new DateTimeFormat($oDateTimeFormat->ToDateFormat());
$writer->setDateFormat($oDateFormat->ToExcel());
$writer->setAuthor(UserRights::GetUserFriendlyName());
$aHeaderTypes = array();
$aHeaderNames = array();
foreach($aHeaders as $Header)
{
$aHeaderNames[] = $Header['label'];
$aHeaderTypes[] = $Header['type'];
}
$writer->writeSheet($aData,'Sheet1', $aHeaderTypes, $aHeaderNames);
$fExcelTime = microtime(true) - $fStartExcel;
//$this->aStatistics['excel_build_duration'] = $fExcelTime;
$fTime = microtime(true);
$data = $writer->writeToString();
$fExcelSaveTime = microtime(true) - $fTime;
//$this->aStatistics['excel_write_duration'] = $fExcelSaveTime;
@unlink($this->aStatusInfo['tmp_file']);
return $data;
}
public function GetMimeType()
{
return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
}
public function GetFileExtension()
{
return 'xlsx';
}
public function GetSupportedFormats()
{
return array('xlsx' => Dict::S('Core:BulkExport:XLSXFormat'));
}
}