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();
|
PHPExcel_Autoloader::Register();
|
||||||
// As we always try to run the autoloader before anything else, we can use it to do a few
|
// As we always try to run the autoloader before anything else, we can use it to do a few
|
||||||
// simple checks and initialisations
|
// simple checks and initialisations
|
||||||
PHPExcel_Shared_ZipStreamWrapper::register();
|
//PHPExcel_Shared_ZipStreamWrapper::register();
|
||||||
// check mbstring.func_overload
|
// check mbstring.func_overload
|
||||||
if (ini_get('mbstring.func_overload') & 2) {
|
if (ini_get('mbstring.func_overload') & 2) {
|
||||||
throw new Exception('Multibyte function overloading in PHP must be disabled for string functions (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)
|
* 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) {
|
if ($xmlWorkbook->sheets) {
|
||||||
$dir = dirname($rel["Target"]);
|
$dir = dirname($rel["Target"]);
|
||||||
foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
|
foreach ($xmlWorkbook->sheets->sheet as $eleSheet) {
|
||||||
$tmpInfo = array();
|
$tmpInfo = array(
|
||||||
$tmpInfo['worksheetName'] = (string) $eleSheet["name"];
|
'worksheetName' => (string) $eleSheet["name"],
|
||||||
$tmpInfo['lastColumnLetter'] = 'A';
|
'lastColumnLetter' => 'A',
|
||||||
$tmpInfo['lastColumnIndex'] = 0;
|
'lastColumnIndex' => 0,
|
||||||
$tmpInfo['totalRows'] = 0;
|
'totalRows' => 0,
|
||||||
$tmpInfo['totalColumns'] = 0;
|
'totalColumns' => 0,
|
||||||
|
);
|
||||||
|
|
||||||
$fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes("http://schemas.openxmlformats.org/officeDocument/2006/relationships"), "id")];
|
$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) {
|
$xml = new XMLReader();
|
||||||
foreach ($xmlSheet->sheetData->row as $row) {
|
$res = $xml->open('zip://'.realpath($pFilename).'#'."$dir/$fileWorksheet");
|
||||||
foreach ($row->c as $c) {
|
$xml->setParserProperty(2,true);
|
||||||
$r = (string) $c["r"];
|
|
||||||
$coordinates = PHPExcel_Cell::coordinateFromString($r);
|
$currCells = 0;
|
||||||
|
while ($xml->read()) {
|
||||||
$rowIndex = $coordinates[1];
|
if ($xml->name == 'row' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||||
$columnIndex = PHPExcel_Cell::columnIndexFromString($coordinates[0]) - 1;
|
$tmpInfo['totalRows']++;
|
||||||
|
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);
|
||||||
$tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex);
|
$currCells = 0;
|
||||||
$tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex);
|
} elseif ($xml->name == 'c' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||||
}
|
$currCells++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);
|
||||||
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
$xml->close();
|
||||||
$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
|
|
||||||
|
$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;
|
||||||
|
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
||||||
|
|
||||||
$worksheetInfo[] = $tmpInfo;
|
$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
|
* 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)
|
* 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.");
|
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! File does not exist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
$gFileData = $this->_gzfileGetContents($pFilename);
|
$xml = new XMLReader();
|
||||||
|
$xml->open(
|
||||||
$xml = simplexml_load_string($gFileData);
|
'compress.zlib://'.realpath($pFilename)
|
||||||
$namespacesMeta = $xml->getNamespaces(true);
|
);
|
||||||
|
$xml->setParserProperty(2,true);
|
||||||
$gnmXML = $xml->children($namespacesMeta['gnm']);
|
|
||||||
|
|
||||||
$worksheetInfo = array();
|
$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) {
|
while ($xml->read()) {
|
||||||
$tmpInfo = array();
|
if ($xml->name == 'gnm:Name' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||||
$tmpInfo['worksheetName'] = (string) $sheet->Name;
|
$xml->read(); // Move onto the value node
|
||||||
$tmpInfo['lastColumnLetter'] = 'A';
|
$tmpInfo['worksheetName'] = (string) $xml->value;
|
||||||
$tmpInfo['lastColumnIndex'] = 0;
|
} elseif ($xml->name == 'gnm:MaxCol' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||||
$tmpInfo['totalRows'] = 0;
|
$xml->read(); // Move onto the value node
|
||||||
$tmpInfo['totalColumns'] = 0;
|
$tmpInfo['lastColumnIndex'] = (int) $xml->value;
|
||||||
|
$tmpInfo['totalColumns'] = (int) $xml->value + 1;
|
||||||
foreach ($sheet->Cells->Cell as $cell) {
|
} elseif ($xml->name == 'gnm:MaxRow' && $xml->nodeType == XMLReader::ELEMENT) {
|
||||||
$cellAttributes = $cell->attributes();
|
$xml->read(); // Move onto the value node
|
||||||
|
$tmpInfo['totalRows'] = (int) $xml->value + 1;
|
||||||
$rowIndex = (int) $cellAttributes->Row + 1;
|
break;
|
||||||
$columnIndex = (int) $cellAttributes->Col;
|
}
|
||||||
|
}
|
||||||
$tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex);
|
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
||||||
$tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex);
|
$worksheetInfo[] = $tmpInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);
|
|
||||||
$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;
|
|
||||||
|
|
||||||
$worksheetInfo[] = $tmpInfo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $worksheetInfo;
|
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
|
* 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.");
|
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();
|
$worksheetNames = array();
|
||||||
|
|
||||||
$zip = new ZipArchive;
|
$xml = new XMLReader();
|
||||||
if ($zip->open($pFilename) === true) {
|
$res = $xml->open('zip://'.realpath($pFilename).'#content.xml');
|
||||||
|
$xml->setParserProperty(2,true);
|
||||||
|
|
||||||
$xml = simplexml_load_string($zip->getFromName("content.xml"));
|
// Step into the first level of content of the XML
|
||||||
$namespacesContent = $xml->getNamespaces(true);
|
$xml->read();
|
||||||
|
while ($xml->read()) {
|
||||||
$workbook = $xml->children($namespacesContent['office']);
|
// Quickly jump through to the office:body node
|
||||||
foreach($workbook->body->spreadsheet as $workbookData) {
|
while ($xml->name !== 'office:body') {
|
||||||
$workbookData = $workbookData->children($namespacesContent['table']);
|
if ($xml->isEmptyElement)
|
||||||
foreach($workbookData->table as $worksheetDataSet) {
|
$xml->read();
|
||||||
$worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']);
|
else
|
||||||
|
$xml->next();
|
||||||
$worksheetNames[] = $worksheetDataAttributes['name'];
|
}
|
||||||
|
// 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
|
* 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
|
* 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');
|
$GMT = new DateTimeZone('UTC');
|
||||||
|
|
||||||
$zip = new ZipArchive;
|
$zip = new ZipArchive;
|
||||||
if ($zip->open($pFilename) === true) {
|
if (!$zip->open($pFilename)) {
|
||||||
// echo '<h1>Meta Information</h1>';
|
throw new PHPExcel_Reader_Exception("Could not open " . $pFilename . " for reading! Error opening file.");
|
||||||
$xml = simplexml_load_string($zip->getFromName("meta.xml"));
|
}
|
||||||
$namespacesMeta = $xml->getNamespaces(true);
|
|
||||||
// echo '<pre>';
|
|
||||||
// print_r($namespacesMeta);
|
|
||||||
// echo '</pre><hr />';
|
|
||||||
|
|
||||||
$docProps = $objPHPExcel->getProperties();
|
// echo '<h1>Meta Information</h1>';
|
||||||
$officeProperty = $xml->children($namespacesMeta['office']);
|
$xml = simplexml_load_string($zip->getFromName("meta.xml"));
|
||||||
foreach($officeProperty as $officePropertyData) {
|
$namespacesMeta = $xml->getNamespaces(true);
|
||||||
$officePropertyDC = array();
|
// echo '<pre>';
|
||||||
if (isset($namespacesMeta['dc'])) {
|
// print_r($namespacesMeta);
|
||||||
$officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
|
// echo '</pre><hr />';
|
||||||
}
|
|
||||||
foreach($officePropertyDC as $propertyName => $propertyValue) {
|
$docProps = $objPHPExcel->getProperties();
|
||||||
switch ($propertyName) {
|
$officeProperty = $xml->children($namespacesMeta['office']);
|
||||||
case 'title' :
|
foreach($officeProperty as $officePropertyData) {
|
||||||
$docProps->setTitle($propertyValue);
|
$officePropertyDC = array();
|
||||||
break;
|
if (isset($namespacesMeta['dc'])) {
|
||||||
case 'subject' :
|
$officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
|
||||||
$docProps->setSubject($propertyValue);
|
}
|
||||||
break;
|
foreach($officePropertyDC as $propertyName => $propertyValue) {
|
||||||
case 'creator' :
|
switch ($propertyName) {
|
||||||
$docProps->setCreator($propertyValue);
|
case 'title' :
|
||||||
$docProps->setLastModifiedBy($propertyValue);
|
$docProps->setTitle($propertyValue);
|
||||||
break;
|
break;
|
||||||
case 'date' :
|
case 'subject' :
|
||||||
$creationDate = strtotime($propertyValue);
|
$docProps->setSubject($propertyValue);
|
||||||
$docProps->setCreated($creationDate);
|
break;
|
||||||
$docProps->setModified($creationDate);
|
case 'creator' :
|
||||||
break;
|
$docProps->setCreator($propertyValue);
|
||||||
case 'description' :
|
$docProps->setLastModifiedBy($propertyValue);
|
||||||
$docProps->setDescription($propertyValue);
|
break;
|
||||||
break;
|
case 'date' :
|
||||||
}
|
$creationDate = strtotime($propertyValue);
|
||||||
}
|
$docProps->setCreated($creationDate);
|
||||||
$officePropertyMeta = array();
|
$docProps->setModified($creationDate);
|
||||||
if (isset($namespacesMeta['dc'])) {
|
break;
|
||||||
$officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
|
case 'description' :
|
||||||
}
|
$docProps->setDescription($propertyValue);
|
||||||
foreach($officePropertyMeta as $propertyName => $propertyValue) {
|
break;
|
||||||
$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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$officePropertyMeta = array();
|
||||||
|
if (isset($namespacesMeta['dc'])) {
|
||||||
// echo '<h1>Workbook Content</h1>';
|
$officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
|
||||||
$xml = simplexml_load_string($zip->getFromName("content.xml"));
|
}
|
||||||
$namespacesContent = $xml->getNamespaces(true);
|
foreach($officePropertyMeta as $propertyName => $propertyValue) {
|
||||||
// echo '<pre>';
|
$propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']);
|
||||||
// print_r($namespacesContent);
|
switch ($propertyName) {
|
||||||
// echo '</pre><hr />';
|
case 'initial-creator' :
|
||||||
|
$docProps->setCreator($propertyValue);
|
||||||
$workbook = $xml->children($namespacesContent['office']);
|
break;
|
||||||
foreach($workbook->body->spreadsheet as $workbookData) {
|
case 'keyword' :
|
||||||
$workbookData = $workbookData->children($namespacesContent['table']);
|
$docProps->setKeywords($propertyValue);
|
||||||
$worksheetID = 0;
|
break;
|
||||||
foreach($workbookData->table as $worksheetDataSet) {
|
case 'creation-date' :
|
||||||
$worksheetData = $worksheetDataSet->children($namespacesContent['table']);
|
$creationDate = strtotime($propertyValue);
|
||||||
// print_r($worksheetData);
|
$docProps->setCreated($creationDate);
|
||||||
// echo '<br />';
|
break;
|
||||||
$worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']);
|
case 'user-defined' :
|
||||||
// print_r($worksheetDataAttributes);
|
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;
|
||||||
// echo '<br />';
|
foreach ($propertyValueAttributes as $key => $value) {
|
||||||
if ((isset($this->_loadSheetsOnly)) && (isset($worksheetDataAttributes['name'])) &&
|
if ($key == 'name') {
|
||||||
(!in_array($worksheetDataAttributes['name'], $this->_loadSheetsOnly))) {
|
$propertyValueName = (string) $value;
|
||||||
continue;
|
} elseif($key == 'value-type') {
|
||||||
}
|
switch ($value) {
|
||||||
|
case 'date' :
|
||||||
// echo '<h2>Worksheet '.$worksheetDataAttributes['name'].'</h2>';
|
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'date');
|
||||||
// Create new Worksheet
|
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE;
|
||||||
$objPHPExcel->createSheet();
|
break;
|
||||||
$objPHPExcel->setActiveSheetIndex($worksheetID);
|
case 'boolean' :
|
||||||
if (isset($worksheetDataAttributes['name'])) {
|
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'bool');
|
||||||
$worksheetName = (string) $worksheetDataAttributes['name'];
|
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN;
|
||||||
// Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in
|
break;
|
||||||
// formula cells... during the load, all formulae should be correct, and we're simply
|
case 'float' :
|
||||||
// bringing the worksheet name in line with the formula, not the reverse
|
$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'r4');
|
||||||
$objPHPExcel->getActiveSheet()->setTitle($worksheetName,false);
|
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT;
|
||||||
}
|
break;
|
||||||
|
default :
|
||||||
$rowID = 1;
|
$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;
|
||||||
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']);
|
$docProps->setCustomProperty($propertyValueName,$propertyValue,$propertyValueType);
|
||||||
$rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ?
|
break;
|
||||||
$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 '<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 />';
|
// echo '<b>'.$columnID.$rowID.'</b><br />';
|
||||||
$cellDataText = (isset($namespacesContent['text'])) ?
|
$cellDataText = (isset($namespacesContent['text'])) ?
|
||||||
$cellData->children($namespacesContent['text']) :
|
$cellData->children($namespacesContent['text']) :
|
||||||
'';
|
'';
|
||||||
$cellDataOffice = $cellData->children($namespacesContent['office']);
|
$cellDataOffice = $cellData->children($namespacesContent['office']);
|
||||||
$cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']);
|
$cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']);
|
||||||
$cellDataTableAttributes = $cellData->attributes($namespacesContent['table']);
|
$cellDataTableAttributes = $cellData->attributes($namespacesContent['table']);
|
||||||
|
|
||||||
// echo 'Office Attributes: ';
|
// echo 'Office Attributes: ';
|
||||||
// print_r($cellDataOfficeAttributes);
|
// print_r($cellDataOfficeAttributes);
|
||||||
// echo '<br />Table Attributes: ';
|
// echo '<br />Table Attributes: ';
|
||||||
// print_r($cellDataTableAttributes);
|
// print_r($cellDataTableAttributes);
|
||||||
// echo '<br />Cell Data Text';
|
// echo '<br />Cell Data Text';
|
||||||
// print_r($cellDataText);
|
// print_r($cellDataText);
|
||||||
// echo '<br />';
|
// echo '<br />';
|
||||||
//
|
//
|
||||||
$type = $formatting = $hyperlink = null;
|
$type = $formatting = $hyperlink = null;
|
||||||
$hasCalculatedValue = false;
|
$hasCalculatedValue = false;
|
||||||
$cellDataFormula = '';
|
$cellDataFormula = '';
|
||||||
if (isset($cellDataTableAttributes['formula'])) {
|
if (isset($cellDataTableAttributes['formula'])) {
|
||||||
$cellDataFormula = $cellDataTableAttributes['formula'];
|
$cellDataFormula = $cellDataTableAttributes['formula'];
|
||||||
$hasCalculatedValue = true;
|
$hasCalculatedValue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($cellDataOffice->annotation)) {
|
if (isset($cellDataOffice->annotation)) {
|
||||||
// echo 'Cell has comment<br />';
|
// echo 'Cell has comment<br />';
|
||||||
$annotationText = $cellDataOffice->annotation->children($namespacesContent['text']);
|
$annotationText = $cellDataOffice->annotation->children($namespacesContent['text']);
|
||||||
$textArray = array();
|
$textArray = array();
|
||||||
foreach($annotationText as $t) {
|
foreach($annotationText as $t) {
|
||||||
foreach($t->span as $text) {
|
foreach($t->span as $text) {
|
||||||
$textArray[] = (string)$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)) {
|
if (isset($cellDataText->p)) {
|
||||||
// Consolidate if there are multiple p records (maybe with spans as well)
|
// Consolidate if there are multiple p records (maybe with spans as well)
|
||||||
$dataArray = array();
|
$dataArray = array();
|
||||||
// Text can have multiple text:p and within those, multiple text:span.
|
// Text can have multiple text:p and within those, multiple text:span.
|
||||||
// text:p newlines, but text:span does not.
|
// text:p newlines, but text:span does not.
|
||||||
// Also, here we assume there is no text data is span fields are specified, since
|
// Also, here we assume there is no text data is span fields are specified, since
|
||||||
// we have no way of knowing proper positioning anyway.
|
// we have no way of knowing proper positioning anyway.
|
||||||
foreach ($cellDataText->p as $pData) {
|
foreach ($cellDataText->p as $pData) {
|
||||||
if (isset($pData->span)) {
|
if (isset($pData->span)) {
|
||||||
// span sections do not newline, so we just create one large string here
|
// span sections do not newline, so we just create one large string here
|
||||||
$spanSection = "";
|
$spanSection = "";
|
||||||
foreach ($pData->span as $spanData) {
|
foreach ($pData->span as $spanData) {
|
||||||
$spanSection .= $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);
|
break;
|
||||||
} else {
|
case 'boolean' :
|
||||||
array_push($dataArray, $pData);
|
$type = PHPExcel_Cell_DataType::TYPE_BOOL;
|
||||||
}
|
$dataValue = ($allCellDataText == 'TRUE') ? True : False;
|
||||||
}
|
break;
|
||||||
$allCellDataText = implode($dataArray, "\n");
|
case 'percentage' :
|
||||||
|
$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;
|
||||||
// echo 'Value Type is '.$cellDataOfficeAttributes['value-type'].'<br />';
|
$dataValue = (float) $cellDataOfficeAttributes['value'];
|
||||||
switch ($cellDataOfficeAttributes['value-type']) {
|
if (floor($dataValue) == $dataValue) {
|
||||||
case 'string' :
|
$dataValue = (integer) $dataValue;
|
||||||
$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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
$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 />';
|
||||||
// Merged cells
|
// if ($hyperlink !== NULL) {
|
||||||
if ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) {
|
// echo 'Hyperlink is '.$hyperlink.'<br />';
|
||||||
if (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->_readDataOnly)) {
|
// }
|
||||||
$columnTo = $columnID;
|
} else {
|
||||||
if (isset($cellDataTableAttributes['number-columns-spanned'])) {
|
$type = PHPExcel_Cell_DataType::TYPE_NULL;
|
||||||
$columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2);
|
$dataValue = NULL;
|
||||||
}
|
|
||||||
$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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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
|
// Return
|
||||||
|
|
|
@ -100,6 +100,24 @@ class PHPExcel_Shared_ZipStreamWrapper {
|
||||||
return true;
|
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().
|
* Implements support for fstat().
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue