Initial modifications for XML-based sheet readers to use XMLReader via streaming for large files in the listWorksheetNames() and listWorksheetInfo() methods... still needs some additional work for merged cells to work correctly, but gives a hell of a memory boost and executes more quickly - the same principles will be applied to the core data readers, but that still requires a lot more work. However, when completed, the effort should be worth it for both speed and memory usage, and the code should be a lot cleaner for the core data reader as well
This commit is contained in:
parent
5de1067a16
commit
0ad3f67da6
|
@ -28,7 +28,7 @@
|
|||
PHPExcel_Autoloader::Register();
|
||||
// As we always try to run the autoloader before anything else, we can use it to do a few
|
||||
// simple checks and initialisations
|
||||
PHPExcel_Shared_ZipStreamWrapper::register();
|
||||
//PHPExcel_Shared_ZipStreamWrapper::register();
|
||||
// check mbstring.func_overload
|
||||
if (ini_get('mbstring.func_overload') & 2) {
|
||||
throw new Exception('Multibyte function overloading in PHP must be disabled for string functions (2).');
|
||||
|
|
|
@ -112,6 +112,50 @@ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPE
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object
|
||||
*
|
||||
* @param string $pFilename
|
||||
* @throws PHPExcel_Reader_Exception
|
||||
*/
|
||||
public function listWorksheetNames($pFilename)
|
||||
{
|
||||
// Check if file exists
|
||||
if (!file_exists($pFilename)) {
|
||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
||||
}
|
||||
|
||||
$worksheetNames = array();
|
||||
|
||||
$zip = new ZipArchive;
|
||||
$zip->open($pFilename);
|
||||
|
||||
// The files we're looking at here are small enough that simpleXML is more efficient than XMLReader
|
||||
$rels = simplexml_load_string(
|
||||
$this->_getFromZipArchive($zip, "_rels/.rels")
|
||||
); //~ http://schemas.openxmlformats.org/package/2006/relationships");
|
||||
foreach ($rels->Relationship as $rel) {
|
||||
switch ($rel["Type"]) {
|
||||
case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument":
|
||||
$xmlWorkbook = simplexml_load_string(
|
||||
$this->_getFromZipArchive($zip, "{$rel['Target']}")
|
||||
); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
|
||||
|
||||
if ($xmlWorkbook->sheets) {
|
||||
foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
|
||||
// Check if sheet should be skipped
|
||||
$worksheetNames[] = (string) $eleSheet["name"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
return $worksheetNames;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
|
||||
*
|
||||
|
@ -148,33 +192,36 @@ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPE
|
|||
if ($xmlWorkbook->sheets) {
|
||||
$dir = dirname($rel["Target"]);
|
||||
foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
|
||||
$tmpInfo = array();
|
||||
$tmpInfo['worksheetName'] = (string) $eleSheet["name"];
|
||||
$tmpInfo['lastColumnLetter'] = 'A';
|
||||
$tmpInfo['lastColumnIndex'] = 0;
|
||||
$tmpInfo['totalRows'] = 0;
|
||||
$tmpInfo['totalColumns'] = 0;
|
||||
$tmpInfo = array(
|
||||
'worksheetName' => (string) $eleSheet["name"],
|
||||
'lastColumnLetter' => 'A',
|
||||
'lastColumnIndex' => 0,
|
||||
'totalRows' => 0,
|
||||
'totalColumns' => 0,
|
||||
);
|
||||
|
||||
$fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")];
|
||||
$xmlSheet = simplexml_load_string($this->_getFromZipArchive($zip, "$dir/$fileWorksheet")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
|
||||
if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) {
|
||||
foreach ($xmlSheet->sheetData->row as $row) {
|
||||
foreach ($row->c as $c) {
|
||||
$r = (string) $c["r"];
|
||||
$coordinates = PHPExcel_Cell::coordinateFromString($r);
|
||||
|
||||
$rowIndex = $coordinates[1];
|
||||
$columnIndex = PHPExcel_Cell::columnIndexFromString($coordinates[0]) - 1;
|
||||
|
||||
$tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex);
|
||||
$tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
||||
$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
|
||||
|
||||
|
||||
$xml = new XMLReader();
|
||||
$res = $xml->open('zip://'.realpath($pFilename).'#'."$dir/$fileWorksheet");
|
||||
$xml->setParserProperty(2,true);
|
||||
|
||||
$currCells = 0;
|
||||
while ($xml->read()) {
|
||||
if ($xml->name == 'row' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$tmpInfo['totalRows']++;
|
||||
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);
|
||||
$currCells = 0;
|
||||
} elseif ($xml->name == 'c' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$currCells++;
|
||||
}
|
||||
}
|
||||
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);
|
||||
$xml->close();
|
||||
|
||||
$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
|
||||
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
||||
|
||||
$worksheetInfo[] = $tmpInfo;
|
||||
}
|
||||
}
|
||||
|
@ -282,45 +329,6 @@ class PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPE
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object
|
||||
*
|
||||
* @param string $pFilename
|
||||
* @throws PHPExcel_Reader_Exception
|
||||
*/
|
||||
public function listWorksheetNames($pFilename)
|
||||
{
|
||||
// Check if file exists
|
||||
if (!file_exists($pFilename)) {
|
||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
||||
}
|
||||
|
||||
$worksheetNames = array();
|
||||
|
||||
$zip = new ZipArchive;
|
||||
$zip->open($pFilename);
|
||||
|
||||
$rels = simplexml_load_string($this->_getFromZipArchive($zip, "_rels/.rels")); //~ http://schemas.openxmlformats.org/package/2006/relationships");
|
||||
foreach ($rels->Relationship as $rel) {
|
||||
switch ($rel["Type"]) {
|
||||
case "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument":
|
||||
$xmlWorkbook = simplexml_load_string($this->_getFromZipArchive($zip, "{$rel['Target']}")); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main");
|
||||
|
||||
if ($xmlWorkbook->sheets) {
|
||||
foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
|
||||
// Check if sheet should be skipped
|
||||
$worksheetNames[] = (string) $eleSheet["name"];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
return $worksheetNames;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads PHPExcel from file
|
||||
*
|
||||
|
|
|
@ -102,6 +102,40 @@ class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPEx
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object
|
||||
*
|
||||
* @param string $pFilename
|
||||
* @throws PHPExcel_Reader_Exception
|
||||
*/
|
||||
public function listWorksheetNames($pFilename)
|
||||
{
|
||||
// Check if file exists
|
||||
if (!file_exists($pFilename)) {
|
||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
||||
}
|
||||
|
||||
$xml = new XMLReader();
|
||||
$xml->open(
|
||||
'compress.zlib://'.realpath($pFilename)
|
||||
);
|
||||
$xml->setParserProperty(2,true);
|
||||
|
||||
$worksheetNames = array();
|
||||
while ($xml->read()) {
|
||||
if ($xml->name == 'gnm:SheetName' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$xml->read(); // Move onto the value node
|
||||
$worksheetNames[] = (string) $xml->value;
|
||||
} elseif ($xml->name == 'gnm:Sheets') {
|
||||
// break out of the loop once we've got our sheet names rather than parse the entire file
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $worksheetNames;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
|
||||
*
|
||||
|
@ -115,37 +149,40 @@ class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPEx
|
|||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
||||
}
|
||||
|
||||
$gFileData = $this->_gzfileGetContents($pFilename);
|
||||
|
||||
$xml = simplexml_load_string($gFileData);
|
||||
$namespacesMeta = $xml->getNamespaces(true);
|
||||
|
||||
$gnmXML = $xml->children($namespacesMeta['gnm']);
|
||||
$xml = new XMLReader();
|
||||
$xml->open(
|
||||
'compress.zlib://'.realpath($pFilename)
|
||||
);
|
||||
$xml->setParserProperty(2,true);
|
||||
|
||||
$worksheetInfo = array();
|
||||
while ($xml->read()) {
|
||||
if ($xml->name == 'gnm:Sheet' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$tmpInfo = array(
|
||||
'worksheetName' => '',
|
||||
'lastColumnLetter' => 'A',
|
||||
'lastColumnIndex' => 0,
|
||||
'totalRows' => 0,
|
||||
'totalColumns' => 0,
|
||||
);
|
||||
|
||||
foreach ($gnmXML->Sheets->Sheet as $sheet) {
|
||||
$tmpInfo = array();
|
||||
$tmpInfo['worksheetName'] = (string) $sheet->Name;
|
||||
$tmpInfo['lastColumnLetter'] = 'A';
|
||||
$tmpInfo['lastColumnIndex'] = 0;
|
||||
$tmpInfo['totalRows'] = 0;
|
||||
$tmpInfo['totalColumns'] = 0;
|
||||
|
||||
foreach ($sheet->Cells->Cell as $cell) {
|
||||
$cellAttributes = $cell->attributes();
|
||||
|
||||
$rowIndex = (int) $cellAttributes->Row + 1;
|
||||
$columnIndex = (int) $cellAttributes->Col;
|
||||
|
||||
$tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex);
|
||||
$tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex);
|
||||
while ($xml->read()) {
|
||||
if ($xml->name == 'gnm:Name' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$xml->read(); // Move onto the value node
|
||||
$tmpInfo['worksheetName'] = (string) $xml->value;
|
||||
} elseif ($xml->name == 'gnm:MaxCol' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$xml->read(); // Move onto the value node
|
||||
$tmpInfo['lastColumnIndex'] = (int) $xml->value;
|
||||
$tmpInfo['totalColumns'] = (int) $xml->value + 1;
|
||||
} elseif ($xml->name == 'gnm:MaxRow' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$xml->read(); // Move onto the value node
|
||||
$tmpInfo['totalRows'] = (int) $xml->value + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
||||
$worksheetInfo[] = $tmpInfo;
|
||||
}
|
||||
|
||||
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
||||
$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
|
||||
|
||||
$worksheetInfo[] = $tmpInfo;
|
||||
}
|
||||
|
||||
return $worksheetInfo;
|
||||
|
@ -182,36 +219,6 @@ class PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPEx
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object
|
||||
*
|
||||
* @param string $pFilename
|
||||
* @throws PHPExcel_Reader_Exception
|
||||
*/
|
||||
public function listWorksheetNames($pFilename)
|
||||
{
|
||||
// Check if file exists
|
||||
if (!file_exists($pFilename)) {
|
||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
||||
}
|
||||
|
||||
$gFileData = $this->_gzfileGetContents($pFilename);
|
||||
|
||||
$xml = simplexml_load_string($gFileData);
|
||||
$namespacesMeta = $xml->getNamespaces(true);
|
||||
|
||||
$gnmXML = $xml->children($namespacesMeta['gnm']);
|
||||
|
||||
$worksheetNames = array();
|
||||
|
||||
foreach($gnmXML->Sheets->Sheet as $sheet) {
|
||||
$worksheetNames[] = (string) $sheet->Name;
|
||||
}
|
||||
|
||||
return $worksheetNames;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads PHPExcel from file into PHPExcel instance
|
||||
*
|
||||
|
|
|
@ -124,21 +124,35 @@ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExce
|
|||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
||||
}
|
||||
|
||||
$zip = new ZipArchive;
|
||||
if (!$zip->open($pFilename)) {
|
||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file.");
|
||||
}
|
||||
|
||||
$worksheetNames = array();
|
||||
|
||||
$zip = new ZipArchive;
|
||||
if ($zip->open($pFilename) === true) {
|
||||
$xml = new XMLReader();
|
||||
$res = $xml->open('zip://'.realpath($pFilename).'#content.xml');
|
||||
$xml->setParserProperty(2,true);
|
||||
|
||||
$xml = simplexml_load_string($zip->getFromName("content.xml"));
|
||||
$namespacesContent = $xml->getNamespaces(true);
|
||||
|
||||
$workbook = $xml->children($namespacesContent['office']);
|
||||
foreach($workbook->body->spreadsheet as $workbookData) {
|
||||
$workbookData = $workbookData->children($namespacesContent['table']);
|
||||
foreach($workbookData->table as $worksheetDataSet) {
|
||||
$worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']);
|
||||
|
||||
$worksheetNames[] = $worksheetDataAttributes['name'];
|
||||
// Step into the first level of content of the XML
|
||||
$xml->read();
|
||||
while ($xml->read()) {
|
||||
// Quickly jump through to the office:body node
|
||||
while ($xml->name !== 'office:body') {
|
||||
if ($xml->isEmptyElement)
|
||||
$xml->read();
|
||||
else
|
||||
$xml->next();
|
||||
}
|
||||
// Now read each node until we find our first table:table node
|
||||
while ($xml->read()) {
|
||||
if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
// Loop through each table:table node reading the table:name attribute for each worksheet name
|
||||
do {
|
||||
$worksheetNames[] = $xml->getAttribute('table:name');
|
||||
$xml->next();
|
||||
} while ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -147,6 +161,127 @@ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExce
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
|
||||
*
|
||||
* @param string $pFilename
|
||||
* @throws PHPExcel_Reader_Exception
|
||||
*/
|
||||
public function listWorksheetInfo($pFilename)
|
||||
{
|
||||
// Check if file exists
|
||||
if (!file_exists($pFilename)) {
|
||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
||||
}
|
||||
|
||||
$worksheetInfo = array();
|
||||
|
||||
$zip = new ZipArchive;
|
||||
if (!$zip->open($pFilename)) {
|
||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file.");
|
||||
}
|
||||
|
||||
$xml = new XMLReader();
|
||||
$res = $xml->open('zip://'.realpath($pFilename).'#content.xml');
|
||||
$xml->setParserProperty(2,true);
|
||||
|
||||
// Step into the first level of content of the XML
|
||||
$xml->read();
|
||||
while ($xml->read()) {
|
||||
// Quickly jump through to the office:body node
|
||||
while ($xml->name !== 'office:body') {
|
||||
if ($xml->isEmptyElement)
|
||||
$xml->read();
|
||||
else
|
||||
$xml->next();
|
||||
}
|
||||
// Now read each node until we find our first table:table node
|
||||
while ($xml->read()) {
|
||||
if ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$worksheetNames[] = $xml->getAttribute('table:name');
|
||||
|
||||
$tmpInfo = array(
|
||||
'worksheetName' => $xml->getAttribute('table:name'),
|
||||
'lastColumnLetter' => 'A',
|
||||
'lastColumnIndex' => 0,
|
||||
'totalRows' => 0,
|
||||
'totalColumns' => 0,
|
||||
);
|
||||
|
||||
// Loop through each child node of the table:table element reading
|
||||
$currCells = 0;
|
||||
do {
|
||||
$xml->read();
|
||||
if ($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$tmpInfo['totalRows']++;
|
||||
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);
|
||||
$currCells = 0;
|
||||
// Step into the row
|
||||
$xml->read();
|
||||
do {
|
||||
if ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
if (!$xml->isEmptyElement) {
|
||||
$currCells++;
|
||||
$xml->next();
|
||||
} else {
|
||||
$xml->read();
|
||||
}
|
||||
} elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||
$mergeSize = $xml->getAttribute('table:number-columns-repeated');
|
||||
$currCells += $mergeSize;
|
||||
$xml->read();
|
||||
}
|
||||
} while ($xml->name != 'table:table-row');
|
||||
}
|
||||
} while ($xml->name != 'table:table');
|
||||
|
||||
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);
|
||||
$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
|
||||
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
||||
$worksheetInfo[] = $tmpInfo;
|
||||
}
|
||||
}
|
||||
|
||||
// foreach($workbookData->table as $worksheetDataSet) {
|
||||
// $worksheetData = $worksheetDataSet->children($namespacesContent['table']);
|
||||
// $worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']);
|
||||
//
|
||||
// $rowIndex = 0;
|
||||
// foreach ($worksheetData as $key => $rowData) {
|
||||
// switch ($key) {
|
||||
// case 'table-row' :
|
||||
// $rowDataTableAttributes = $rowData->attributes($namespacesContent['table']);
|
||||
// $rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ?
|
||||
// $rowDataTableAttributes['number-rows-repeated'] : 1;
|
||||
// $columnIndex = 0;
|
||||
//
|
||||
// foreach ($rowData as $key => $cellData) {
|
||||
// $cellDataTableAttributes = $cellData->attributes($namespacesContent['table']);
|
||||
// $colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ?
|
||||
// $cellDataTableAttributes['number-columns-repeated'] : 1;
|
||||
// $cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']);
|
||||
// if (isset($cellDataOfficeAttributes['value-type'])) {
|
||||
// $tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex + $colRepeats - 1);
|
||||
// $tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex + $rowRepeats);
|
||||
// }
|
||||
// $columnIndex += $colRepeats;
|
||||
// }
|
||||
// $rowIndex += $rowRepeats;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// $tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
||||
// $tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
|
||||
//
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
return $worksheetInfo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads PHPExcel from file
|
||||
*
|
||||
|
@ -176,78 +311,6 @@ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExce
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)
|
||||
*
|
||||
* @param string $pFilename
|
||||
* @throws PHPExcel_Reader_Exception
|
||||
*/
|
||||
public function listWorksheetInfo($pFilename)
|
||||
{
|
||||
// Check if file exists
|
||||
if (!file_exists($pFilename)) {
|
||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
||||
}
|
||||
|
||||
$worksheetInfo = array();
|
||||
|
||||
$zip = new ZipArchive;
|
||||
if ($zip->open($pFilename) === true) {
|
||||
|
||||
$xml = simplexml_load_string($zip->getFromName("content.xml"));
|
||||
$namespacesContent = $xml->getNamespaces(true);
|
||||
|
||||
$workbook = $xml->children($namespacesContent['office']);
|
||||
foreach($workbook->body->spreadsheet as $workbookData) {
|
||||
$workbookData = $workbookData->children($namespacesContent['table']);
|
||||
foreach($workbookData->table as $worksheetDataSet) {
|
||||
$worksheetData = $worksheetDataSet->children($namespacesContent['table']);
|
||||
$worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']);
|
||||
|
||||
$tmpInfo = array();
|
||||
$tmpInfo['worksheetName'] = (string) $worksheetDataAttributes['name'];
|
||||
$tmpInfo['lastColumnLetter'] = 'A';
|
||||
$tmpInfo['lastColumnIndex'] = 0;
|
||||
$tmpInfo['totalRows'] = 0;
|
||||
$tmpInfo['totalColumns'] = 0;
|
||||
|
||||
$rowIndex = 0;
|
||||
foreach ($worksheetData as $key => $rowData) {
|
||||
switch ($key) {
|
||||
case 'table-row' :
|
||||
$rowDataTableAttributes = $rowData->attributes($namespacesContent['table']);
|
||||
$rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ?
|
||||
$rowDataTableAttributes['number-rows-repeated'] : 1;
|
||||
$columnIndex = 0;
|
||||
|
||||
foreach ($rowData as $key => $cellData) {
|
||||
$cellDataTableAttributes = $cellData->attributes($namespacesContent['table']);
|
||||
$colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ?
|
||||
$cellDataTableAttributes['number-columns-repeated'] : 1;
|
||||
$cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']);
|
||||
if (isset($cellDataOfficeAttributes['value-type'])) {
|
||||
$tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex + $colRepeats - 1);
|
||||
$tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex + $rowRepeats);
|
||||
}
|
||||
$columnIndex += $colRepeats;
|
||||
}
|
||||
$rowIndex += $rowRepeats;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
||||
$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
|
||||
|
||||
$worksheetInfo[] = $tmpInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $worksheetInfo;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads PHPExcel from file into PHPExcel instance
|
||||
*
|
||||
|
@ -267,350 +330,351 @@ class PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExce
|
|||
$GMT = new DateTimeZone('UTC');
|
||||
|
||||
$zip = new ZipArchive;
|
||||
if ($zip->open($pFilename) === true) {
|
||||
// echo '<h1>Meta Information</h1>';
|
||||
$xml = simplexml_load_string($zip->getFromName("meta.xml"));
|
||||
$namespacesMeta = $xml->getNamespaces(true);
|
||||
// echo '<pre>';
|
||||
// print_r($namespacesMeta);
|
||||
// echo '</pre><hr />';
|
||||
if (!$zip->open($pFilename)) {
|
||||
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file.");
|
||||
}
|
||||
|
||||
$docProps = $objPHPExcel->getProperties();
|
||||
$officeProperty = $xml->children($namespacesMeta['office']);
|
||||
foreach($officeProperty as $officePropertyData) {
|
||||
$officePropertyDC = array();
|
||||
if (isset($namespacesMeta['dc'])) {
|
||||
$officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
|
||||
}
|
||||
foreach($officePropertyDC as $propertyName => $propertyValue) {
|
||||
switch ($propertyName) {
|
||||
case 'title' :
|
||||
$docProps->setTitle($propertyValue);
|
||||
break;
|
||||
case 'subject' :
|
||||
$docProps->setSubject($propertyValue);
|
||||
break;
|
||||
case 'creator' :
|
||||
$docProps->setCreator($propertyValue);
|
||||
$docProps->setLastModifiedBy($propertyValue);
|
||||
break;
|
||||
case 'date' :
|
||||
$creationDate = strtotime($propertyValue);
|
||||
$docProps->setCreated($creationDate);
|
||||
$docProps->setModified($creationDate);
|
||||
break;
|
||||
case 'description' :
|
||||
$docProps->setDescription($propertyValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
$officePropertyMeta = array();
|
||||
if (isset($namespacesMeta['dc'])) {
|
||||
$officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
|
||||
}
|
||||
foreach($officePropertyMeta as $propertyName => $propertyValue) {
|
||||
$propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']);
|
||||
switch ($propertyName) {
|
||||
case 'initial-creator' :
|
||||
$docProps->setCreator($propertyValue);
|
||||
break;
|
||||
case 'keyword' :
|
||||
$docProps->setKeywords($propertyValue);
|
||||
break;
|
||||
case 'creation-date' :
|
||||
$creationDate = strtotime($propertyValue);
|
||||
$docProps->setCreated($creationDate);
|
||||
break;
|
||||
case 'user-defined' :
|
||||
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;
|
||||
foreach ($propertyValueAttributes as $key => $value) {
|
||||
if ($key == 'name') {
|
||||
$propertyValueName = (string) $value;
|
||||
} elseif($key == 'value-type') {
|
||||
switch ($value) {
|
||||
case 'date' :
|
||||
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'date');
|
||||
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE;
|
||||
break;
|
||||
case 'boolean' :
|
||||
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'bool');
|
||||
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN;
|
||||
break;
|
||||
case 'float' :
|
||||
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'r4');
|
||||
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT;
|
||||
break;
|
||||
default :
|
||||
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;
|
||||
}
|
||||
}
|
||||
}
|
||||
$docProps->setCustomProperty($propertyValueName,$propertyValue,$propertyValueType);
|
||||
break;
|
||||
}
|
||||
// echo '<h1>Meta Information</h1>';
|
||||
$xml = simplexml_load_string($zip->getFromName("meta.xml"));
|
||||
$namespacesMeta = $xml->getNamespaces(true);
|
||||
// echo '<pre>';
|
||||
// print_r($namespacesMeta);
|
||||
// echo '</pre><hr />';
|
||||
|
||||
$docProps = $objPHPExcel->getProperties();
|
||||
$officeProperty = $xml->children($namespacesMeta['office']);
|
||||
foreach($officeProperty as $officePropertyData) {
|
||||
$officePropertyDC = array();
|
||||
if (isset($namespacesMeta['dc'])) {
|
||||
$officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
|
||||
}
|
||||
foreach($officePropertyDC as $propertyName => $propertyValue) {
|
||||
switch ($propertyName) {
|
||||
case 'title' :
|
||||
$docProps->setTitle($propertyValue);
|
||||
break;
|
||||
case 'subject' :
|
||||
$docProps->setSubject($propertyValue);
|
||||
break;
|
||||
case 'creator' :
|
||||
$docProps->setCreator($propertyValue);
|
||||
$docProps->setLastModifiedBy($propertyValue);
|
||||
break;
|
||||
case 'date' :
|
||||
$creationDate = strtotime($propertyValue);
|
||||
$docProps->setCreated($creationDate);
|
||||
$docProps->setModified($creationDate);
|
||||
break;
|
||||
case 'description' :
|
||||
$docProps->setDescription($propertyValue);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// echo '<h1>Workbook Content</h1>';
|
||||
$xml = simplexml_load_string($zip->getFromName("content.xml"));
|
||||
$namespacesContent = $xml->getNamespaces(true);
|
||||
// echo '<pre>';
|
||||
// print_r($namespacesContent);
|
||||
// echo '</pre><hr />';
|
||||
|
||||
$workbook = $xml->children($namespacesContent['office']);
|
||||
foreach($workbook->body->spreadsheet as $workbookData) {
|
||||
$workbookData = $workbookData->children($namespacesContent['table']);
|
||||
$worksheetID = 0;
|
||||
foreach($workbookData->table as $worksheetDataSet) {
|
||||
$worksheetData = $worksheetDataSet->children($namespacesContent['table']);
|
||||
// print_r($worksheetData);
|
||||
// echo '<br />';
|
||||
$worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']);
|
||||
// print_r($worksheetDataAttributes);
|
||||
// echo '<br />';
|
||||
if ((isset($this->_loadSheetsOnly)) && (isset($worksheetDataAttributes['name'])) &&
|
||||
(!in_array($worksheetDataAttributes['name'], $this->_loadSheetsOnly))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// echo '<h2>Worksheet '.$worksheetDataAttributes['name'].'</h2>';
|
||||
// Create new Worksheet
|
||||
$objPHPExcel->createSheet();
|
||||
$objPHPExcel->setActiveSheetIndex($worksheetID);
|
||||
if (isset($worksheetDataAttributes['name'])) {
|
||||
$worksheetName = (string) $worksheetDataAttributes['name'];
|
||||
// Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in
|
||||
// formula cells... during the load, all formulae should be correct, and we're simply
|
||||
// bringing the worksheet name in line with the formula, not the reverse
|
||||
$objPHPExcel->getActiveSheet()->setTitle($worksheetName,false);
|
||||
}
|
||||
|
||||
$rowID = 1;
|
||||
foreach($worksheetData as $key => $rowData) {
|
||||
// echo '<b>'.$key.'</b><br />';
|
||||
switch ($key) {
|
||||
case 'table-header-rows':
|
||||
foreach ($rowData as $key=>$cellData) {
|
||||
$rowData = $cellData;
|
||||
break;
|
||||
$officePropertyMeta = array();
|
||||
if (isset($namespacesMeta['dc'])) {
|
||||
$officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
|
||||
}
|
||||
foreach($officePropertyMeta as $propertyName => $propertyValue) {
|
||||
$propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']);
|
||||
switch ($propertyName) {
|
||||
case 'initial-creator' :
|
||||
$docProps->setCreator($propertyValue);
|
||||
break;
|
||||
case 'keyword' :
|
||||
$docProps->setKeywords($propertyValue);
|
||||
break;
|
||||
case 'creation-date' :
|
||||
$creationDate = strtotime($propertyValue);
|
||||
$docProps->setCreated($creationDate);
|
||||
break;
|
||||
case 'user-defined' :
|
||||
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;
|
||||
foreach ($propertyValueAttributes as $key => $value) {
|
||||
if ($key == 'name') {
|
||||
$propertyValueName = (string) $value;
|
||||
} elseif($key == 'value-type') {
|
||||
switch ($value) {
|
||||
case 'date' :
|
||||
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'date');
|
||||
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE;
|
||||
break;
|
||||
case 'boolean' :
|
||||
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'bool');
|
||||
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN;
|
||||
break;
|
||||
case 'float' :
|
||||
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'r4');
|
||||
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT;
|
||||
break;
|
||||
default :
|
||||
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;
|
||||
}
|
||||
}
|
||||
case 'table-row' :
|
||||
$rowDataTableAttributes = $rowData->attributes($namespacesContent['table']);
|
||||
$rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ?
|
||||
$rowDataTableAttributes['number-rows-repeated'] : 1;
|
||||
$columnID = 'A';
|
||||
foreach($rowData as $key => $cellData) {
|
||||
if ($this->getReadFilter() !== NULL) {
|
||||
if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$docProps->setCustomProperty($propertyValueName,$propertyValue,$propertyValueType);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// echo '<h1>Workbook Content</h1>';
|
||||
$xml = simplexml_load_string($zip->getFromName("content.xml"));
|
||||
$namespacesContent = $xml->getNamespaces(true);
|
||||
// echo '<pre>';
|
||||
// print_r($namespacesContent);
|
||||
// echo '</pre><hr />';
|
||||
|
||||
$workbook = $xml->children($namespacesContent['office']);
|
||||
foreach($workbook->body->spreadsheet as $workbookData) {
|
||||
$workbookData = $workbookData->children($namespacesContent['table']);
|
||||
$worksheetID = 0;
|
||||
foreach($workbookData->table as $worksheetDataSet) {
|
||||
$worksheetData = $worksheetDataSet->children($namespacesContent['table']);
|
||||
// print_r($worksheetData);
|
||||
// echo '<br />';
|
||||
$worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']);
|
||||
// print_r($worksheetDataAttributes);
|
||||
// echo '<br />';
|
||||
if ((isset($this->_loadSheetsOnly)) && (isset($worksheetDataAttributes['name'])) &&
|
||||
(!in_array($worksheetDataAttributes['name'], $this->_loadSheetsOnly))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// echo '<h2>Worksheet '.$worksheetDataAttributes['name'].'</h2>';
|
||||
// Create new Worksheet
|
||||
$objPHPExcel->createSheet();
|
||||
$objPHPExcel->setActiveSheetIndex($worksheetID);
|
||||
if (isset($worksheetDataAttributes['name'])) {
|
||||
$worksheetName = (string) $worksheetDataAttributes['name'];
|
||||
// Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in
|
||||
// formula cells... during the load, all formulae should be correct, and we're simply
|
||||
// bringing the worksheet name in line with the formula, not the reverse
|
||||
$objPHPExcel->getActiveSheet()->setTitle($worksheetName,false);
|
||||
}
|
||||
|
||||
$rowID = 1;
|
||||
foreach($worksheetData as $key => $rowData) {
|
||||
// echo '<b>'.$key.'</b><br />';
|
||||
switch ($key) {
|
||||
case 'table-header-rows':
|
||||
foreach ($rowData as $key=>$cellData) {
|
||||
$rowData = $cellData;
|
||||
break;
|
||||
}
|
||||
case 'table-row' :
|
||||
$rowDataTableAttributes = $rowData->attributes($namespacesContent['table']);
|
||||
$rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ?
|
||||
$rowDataTableAttributes['number-rows-repeated'] : 1;
|
||||
$columnID = 'A';
|
||||
foreach($rowData as $key => $cellData) {
|
||||
if ($this->getReadFilter() !== NULL) {
|
||||
if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// echo '<b>'.$columnID.$rowID.'</b><br />';
|
||||
$cellDataText = (isset($namespacesContent['text'])) ?
|
||||
$cellData->children($namespacesContent['text']) :
|
||||
'';
|
||||
$cellDataOffice = $cellData->children($namespacesContent['office']);
|
||||
$cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']);
|
||||
$cellDataTableAttributes = $cellData->attributes($namespacesContent['table']);
|
||||
// echo '<b>'.$columnID.$rowID.'</b><br />';
|
||||
$cellDataText = (isset($namespacesContent['text'])) ?
|
||||
$cellData->children($namespacesContent['text']) :
|
||||
'';
|
||||
$cellDataOffice = $cellData->children($namespacesContent['office']);
|
||||
$cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']);
|
||||
$cellDataTableAttributes = $cellData->attributes($namespacesContent['table']);
|
||||
|
||||
// echo 'Office Attributes: ';
|
||||
// print_r($cellDataOfficeAttributes);
|
||||
// echo '<br />Table Attributes: ';
|
||||
// print_r($cellDataTableAttributes);
|
||||
// echo '<br />Cell Data Text';
|
||||
// print_r($cellDataText);
|
||||
// echo '<br />';
|
||||
// echo 'Office Attributes: ';
|
||||
// print_r($cellDataOfficeAttributes);
|
||||
// echo '<br />Table Attributes: ';
|
||||
// print_r($cellDataTableAttributes);
|
||||
// echo '<br />Cell Data Text';
|
||||
// print_r($cellDataText);
|
||||
// echo '<br />';
|
||||
//
|
||||
$type = $formatting = $hyperlink = null;
|
||||
$hasCalculatedValue = false;
|
||||
$cellDataFormula = '';
|
||||
if (isset($cellDataTableAttributes['formula'])) {
|
||||
$cellDataFormula = $cellDataTableAttributes['formula'];
|
||||
$hasCalculatedValue = true;
|
||||
}
|
||||
$type = $formatting = $hyperlink = null;
|
||||
$hasCalculatedValue = false;
|
||||
$cellDataFormula = '';
|
||||
if (isset($cellDataTableAttributes['formula'])) {
|
||||
$cellDataFormula = $cellDataTableAttributes['formula'];
|
||||
$hasCalculatedValue = true;
|
||||
}
|
||||
|
||||
if (isset($cellDataOffice->annotation)) {
|
||||
// echo 'Cell has comment<br />';
|
||||
$annotationText = $cellDataOffice->annotation->children($namespacesContent['text']);
|
||||
$textArray = array();
|
||||
foreach($annotationText as $t) {
|
||||
foreach($t->span as $text) {
|
||||
$textArray[] = (string)$text;
|
||||
}
|
||||
if (isset($cellDataOffice->annotation)) {
|
||||
// echo 'Cell has comment<br />';
|
||||
$annotationText = $cellDataOffice->annotation->children($namespacesContent['text']);
|
||||
$textArray = array();
|
||||
foreach($annotationText as $t) {
|
||||
foreach($t->span as $text) {
|
||||
$textArray[] = (string)$text;
|
||||
}
|
||||
$text = implode("\n",$textArray);
|
||||
// echo $text,'<br />';
|
||||
$objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID )
|
||||
// ->setAuthor( $author )
|
||||
->setText($this->_parseRichText($text) );
|
||||
}
|
||||
$text = implode("\n",$textArray);
|
||||
// echo $text,'<br />';
|
||||
$objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID )
|
||||
// ->setAuthor( $author )
|
||||
->setText($this->_parseRichText($text) );
|
||||
}
|
||||
|
||||
if (isset($cellDataText->p)) {
|
||||
// Consolidate if there are multiple p records (maybe with spans as well)
|
||||
$dataArray = array();
|
||||
// Text can have multiple text:p and within those, multiple text:span.
|
||||
// text:p newlines, but text:span does not.
|
||||
// Also, here we assume there is no text data is span fields are specified, since
|
||||
// we have no way of knowing proper positioning anyway.
|
||||
foreach ($cellDataText->p as $pData) {
|
||||
if (isset($pData->span)) {
|
||||
// span sections do not newline, so we just create one large string here
|
||||
$spanSection = "";
|
||||
foreach ($pData->span as $spanData) {
|
||||
$spanSection .= $spanData;
|
||||
// Consolidate if there are multiple p records (maybe with spans as well)
|
||||
$dataArray = array();
|
||||
// Text can have multiple text:p and within those, multiple text:span.
|
||||
// text:p newlines, but text:span does not.
|
||||
// Also, here we assume there is no text data is span fields are specified, since
|
||||
// we have no way of knowing proper positioning anyway.
|
||||
foreach ($cellDataText->p as $pData) {
|
||||
if (isset($pData->span)) {
|
||||
// span sections do not newline, so we just create one large string here
|
||||
$spanSection = "";
|
||||
foreach ($pData->span as $spanData) {
|
||||
$spanSection .= $spanData;
|
||||
}
|
||||
array_push($dataArray, $spanSection);
|
||||
} else {
|
||||
array_push($dataArray, $pData);
|
||||
}
|
||||
}
|
||||
$allCellDataText = implode($dataArray, "\n");
|
||||
|
||||
// echo 'Value Type is '.$cellDataOfficeAttributes['value-type'].'<br />';
|
||||
switch ($cellDataOfficeAttributes['value-type']) {
|
||||
case 'string' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_STRING;
|
||||
$dataValue = $allCellDataText;
|
||||
if (isset($dataValue->a)) {
|
||||
$dataValue = $dataValue->a;
|
||||
$cellXLinkAttributes = $dataValue->attributes($namespacesContent['xlink']);
|
||||
$hyperlink = $cellXLinkAttributes['href'];
|
||||
}
|
||||
array_push($dataArray, $spanSection);
|
||||
} else {
|
||||
array_push($dataArray, $pData);
|
||||
}
|
||||
}
|
||||
$allCellDataText = implode($dataArray, "\n");
|
||||
|
||||
// echo 'Value Type is '.$cellDataOfficeAttributes['value-type'].'<br />';
|
||||
switch ($cellDataOfficeAttributes['value-type']) {
|
||||
case 'string' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_STRING;
|
||||
$dataValue = $allCellDataText;
|
||||
if (isset($dataValue->a)) {
|
||||
$dataValue = $dataValue->a;
|
||||
$cellXLinkAttributes = $dataValue->attributes($namespacesContent['xlink']);
|
||||
$hyperlink = $cellXLinkAttributes['href'];
|
||||
}
|
||||
break;
|
||||
case 'boolean' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_BOOL;
|
||||
$dataValue = ($allCellDataText == 'TRUE') ? True : False;
|
||||
break;
|
||||
case 'percentage' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
||||
$dataValue = (float) $cellDataOfficeAttributes['value'];
|
||||
if (floor($dataValue) == $dataValue) {
|
||||
$dataValue = (integer) $dataValue;
|
||||
}
|
||||
$formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00;
|
||||
break;
|
||||
case 'currency' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
||||
$dataValue = (float) $cellDataOfficeAttributes['value'];
|
||||
if (floor($dataValue) == $dataValue) {
|
||||
$dataValue = (integer) $dataValue;
|
||||
}
|
||||
$formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE;
|
||||
break;
|
||||
case 'float' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
||||
$dataValue = (float) $cellDataOfficeAttributes['value'];
|
||||
if (floor($dataValue) == $dataValue) {
|
||||
if ($dataValue = (integer) $dataValue)
|
||||
$dataValue = (integer) $dataValue;
|
||||
else
|
||||
$dataValue = (float) $dataValue;
|
||||
}
|
||||
break;
|
||||
case 'date' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
||||
$dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT);
|
||||
$dateObj->setTimeZone($timezoneObj);
|
||||
list($year,$month,$day,$hour,$minute,$second) = explode(' ',$dateObj->format('Y m d H i s'));
|
||||
$dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year,$month,$day,$hour,$minute,$second);
|
||||
if ($dataValue != floor($dataValue)) {
|
||||
$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4;
|
||||
} else {
|
||||
$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15;
|
||||
}
|
||||
break;
|
||||
case 'time' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
||||
$dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'],'PT%dH%dM%dS'))));
|
||||
$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4;
|
||||
break;
|
||||
}
|
||||
// echo 'Data value is '.$dataValue.'<br />';
|
||||
// if ($hyperlink !== NULL) {
|
||||
// echo 'Hyperlink is '.$hyperlink.'<br />';
|
||||
// }
|
||||
} else {
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NULL;
|
||||
$dataValue = NULL;
|
||||
}
|
||||
|
||||
if ($hasCalculatedValue) {
|
||||
$type = PHPExcel_Cell_DataType::TYPE_FORMULA;
|
||||
// echo 'Formula: '.$cellDataFormula.'<br />';
|
||||
$cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1);
|
||||
$temp = explode('"',$cellDataFormula);
|
||||
$tKey = false;
|
||||
foreach($temp as &$value) {
|
||||
// Only replace in alternate array entries (i.e. non-quoted blocks)
|
||||
if ($tKey = !$tKey) {
|
||||
$value = preg_replace('/\[\.(.*):\.(.*)\]/Ui','$1:$2',$value);
|
||||
$value = preg_replace('/\[\.(.*)\]/Ui','$1',$value);
|
||||
$value = PHPExcel_Calculation::_translateSeparator(';',',',$value,$inBraces);
|
||||
}
|
||||
}
|
||||
unset($value);
|
||||
// Then rebuild the formula string
|
||||
$cellDataFormula = implode('"',$temp);
|
||||
// echo 'Adjusted Formula: '.$cellDataFormula.'<br />';
|
||||
}
|
||||
|
||||
$colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ?
|
||||
$cellDataTableAttributes['number-columns-repeated'] : 1;
|
||||
if ($type !== NULL) {
|
||||
for ($i = 0; $i < $colRepeats; ++$i) {
|
||||
if ($i > 0) {
|
||||
++$columnID;
|
||||
}
|
||||
if ($type !== PHPExcel_Cell_DataType::TYPE_NULL) {
|
||||
for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) {
|
||||
$rID = $rowID + $rowAdjust;
|
||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type);
|
||||
if ($hasCalculatedValue) {
|
||||
// echo 'Forumla result is '.$dataValue.'<br />';
|
||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setCalculatedValue($dataValue);
|
||||
}
|
||||
if ($formatting !== NULL) {
|
||||
$objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode($formatting);
|
||||
} else {
|
||||
$objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL);
|
||||
}
|
||||
if ($hyperlink !== NULL) {
|
||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->getHyperlink()->setUrl($hyperlink);
|
||||
}
|
||||
break;
|
||||
case 'boolean' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_BOOL;
|
||||
$dataValue = ($allCellDataText == 'TRUE') ? True : False;
|
||||
break;
|
||||
case 'percentage' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
||||
$dataValue = (float) $cellDataOfficeAttributes['value'];
|
||||
if (floor($dataValue) == $dataValue) {
|
||||
$dataValue = (integer) $dataValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
$formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00;
|
||||
break;
|
||||
case 'currency' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
||||
$dataValue = (float) $cellDataOfficeAttributes['value'];
|
||||
if (floor($dataValue) == $dataValue) {
|
||||
$dataValue = (integer) $dataValue;
|
||||
}
|
||||
$formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE;
|
||||
break;
|
||||
case 'float' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
||||
$dataValue = (float) $cellDataOfficeAttributes['value'];
|
||||
if (floor($dataValue) == $dataValue) {
|
||||
if ($dataValue = (integer) $dataValue)
|
||||
$dataValue = (integer) $dataValue;
|
||||
else
|
||||
$dataValue = (float) $dataValue;
|
||||
}
|
||||
break;
|
||||
case 'date' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
||||
$dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT);
|
||||
$dateObj->setTimeZone($timezoneObj);
|
||||
list($year,$month,$day,$hour,$minute,$second) = explode(' ',$dateObj->format('Y m d H i s'));
|
||||
$dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year,$month,$day,$hour,$minute,$second);
|
||||
if ($dataValue != floor($dataValue)) {
|
||||
$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4;
|
||||
} else {
|
||||
$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15;
|
||||
}
|
||||
break;
|
||||
case 'time' :
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
||||
$dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'],'PT%dH%dM%dS'))));
|
||||
$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4;
|
||||
break;
|
||||
}
|
||||
|
||||
// Merged cells
|
||||
if ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) {
|
||||
if (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->_readDataOnly)) {
|
||||
$columnTo = $columnID;
|
||||
if (isset($cellDataTableAttributes['number-columns-spanned'])) {
|
||||
$columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2);
|
||||
}
|
||||
$rowTo = $rowID;
|
||||
if (isset($cellDataTableAttributes['number-rows-spanned'])) {
|
||||
$rowTo = $rowTo + $cellDataTableAttributes['number-rows-spanned'] - 1;
|
||||
}
|
||||
$cellRange = $columnID.$rowID.':'.$columnTo.$rowTo;
|
||||
$objPHPExcel->getActiveSheet()->mergeCells($cellRange);
|
||||
}
|
||||
}
|
||||
|
||||
++$columnID;
|
||||
// echo 'Data value is '.$dataValue.'<br />';
|
||||
// if ($hyperlink !== NULL) {
|
||||
// echo 'Hyperlink is '.$hyperlink.'<br />';
|
||||
// }
|
||||
} else {
|
||||
$type = PHPExcel_Cell_DataType::TYPE_NULL;
|
||||
$dataValue = NULL;
|
||||
}
|
||||
$rowID += $rowRepeats;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++$worksheetID;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasCalculatedValue) {
|
||||
$type = PHPExcel_Cell_DataType::TYPE_FORMULA;
|
||||
// echo 'Formula: '.$cellDataFormula.'<br />';
|
||||
$cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1);
|
||||
$temp = explode('"',$cellDataFormula);
|
||||
$tKey = false;
|
||||
foreach($temp as &$value) {
|
||||
// Only replace in alternate array entries (i.e. non-quoted blocks)
|
||||
if ($tKey = !$tKey) {
|
||||
$value = preg_replace('/\[\.(.*):\.(.*)\]/Ui','$1:$2',$value);
|
||||
$value = preg_replace('/\[\.(.*)\]/Ui','$1',$value);
|
||||
$value = PHPExcel_Calculation::_translateSeparator(';',',',$value,$inBraces);
|
||||
}
|
||||
}
|
||||
unset($value);
|
||||
// Then rebuild the formula string
|
||||
$cellDataFormula = implode('"',$temp);
|
||||
// echo 'Adjusted Formula: '.$cellDataFormula.'<br />';
|
||||
}
|
||||
|
||||
$colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ?
|
||||
$cellDataTableAttributes['number-columns-repeated'] : 1;
|
||||
if ($type !== NULL) {
|
||||
for ($i = 0; $i < $colRepeats; ++$i) {
|
||||
if ($i > 0) {
|
||||
++$columnID;
|
||||
}
|
||||
if ($type !== PHPExcel_Cell_DataType::TYPE_NULL) {
|
||||
for ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) {
|
||||
$rID = $rowID + $rowAdjust;
|
||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type);
|
||||
if ($hasCalculatedValue) {
|
||||
// echo 'Forumla result is '.$dataValue.'<br />';
|
||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setCalculatedValue($dataValue);
|
||||
}
|
||||
if ($formatting !== NULL) {
|
||||
$objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode($formatting);
|
||||
} else {
|
||||
$objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL);
|
||||
}
|
||||
if ($hyperlink !== NULL) {
|
||||
$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->getHyperlink()->setUrl($hyperlink);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Merged cells
|
||||
if ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) {
|
||||
if (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->_readDataOnly)) {
|
||||
$columnTo = $columnID;
|
||||
if (isset($cellDataTableAttributes['number-columns-spanned'])) {
|
||||
$columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2);
|
||||
}
|
||||
$rowTo = $rowID;
|
||||
if (isset($cellDataTableAttributes['number-rows-spanned'])) {
|
||||
$rowTo = $rowTo + $cellDataTableAttributes['number-rows-spanned'] - 1;
|
||||
}
|
||||
$cellRange = $columnID.$rowID.':'.$columnTo.$rowTo;
|
||||
$objPHPExcel->getActiveSheet()->mergeCells($cellRange);
|
||||
}
|
||||
}
|
||||
|
||||
++$columnID;
|
||||
}
|
||||
$rowID += $rowRepeats;
|
||||
break;
|
||||
}
|
||||
}
|
||||
++$worksheetID;
|
||||
}
|
||||
}
|
||||
|
||||
// Return
|
||||
|
|
|
@ -100,6 +100,24 @@ class PHPExcel_Shared_ZipStreamWrapper {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fstat().
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function statName() {
|
||||
return $this->_fileNameInArchive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fstat().
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function url_stat() {
|
||||
return $this->statName( $this->_fileNameInArchive );
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements support for fstat().
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue