Bugfix to ensure that General format is not treated as a date format

despite containg e for epoch
OOCalc Reader modified to process number-rows-repeated
Modify OOCalc Reader to only read cells that containing data, or merged cells
(depending on setReadDataOnly setting)
This commit is contained in:
Mark Baker 2012-07-23 21:52:14 +01:00
parent d9f9fd37f4
commit 317f00b259
3 changed files with 73 additions and 47 deletions

View File

@ -319,14 +319,23 @@ class PHPExcel_Reader_OOCalc implements PHPExcel_Reader_IReader
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) {
$tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex);
++$columnIndex;
$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;
$tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex);
$rowIndex += $rowRepeats;
break;
}
}
@ -492,6 +501,9 @@ class PHPExcel_Reader_OOCalc implements PHPExcel_Reader_IReader
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) {
@ -644,44 +656,53 @@ class PHPExcel_Reader_OOCalc implements PHPExcel_Reader_IReader
// echo 'Adjusted Formula: '.$cellDataFormula.'<br />';
}
$repeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ?
$colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ?
$cellDataTableAttributes['number-columns-repeated'] : 1;
if ($type !== NULL) {
for ($i = 0; $i < $repeats; ++$i) {
for ($i = 0; $i < $colRepeats; ++$i) {
if ($i > 0) {
++$columnID;
}
$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type);
if ($hasCalculatedValue) {
// echo 'Forumla result is '.$dataValue.'<br />';
$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($dataValue);
}
if ($formatting !== NULL) {
$objPHPExcel->getActiveSheet()->getStyle($columnID.$rowID)->getNumberFormat()->setFormatCode($formatting);
}
if ($hyperlink !== NULL) {
$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->getHyperlink()->setUrl($hyperlink);
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']))) {
$columnTo = $columnID;
if (isset($cellDataTableAttributes['number-columns-spanned'])) {
$columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2);
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);
}
$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;
$rowID += $rowRepeats;
break;
}
}

View File

@ -88,9 +88,9 @@ class PHPExcel_Shared_Date
if (($baseDate == self::CALENDAR_WINDOWS_1900) ||
($baseDate == self::CALENDAR_MAC_1904)) {
self::$ExcelBaseDate = $baseDate;
return True;
return TRUE;
}
return False;
return FALSE;
} // function setExcelCalendar()
@ -166,12 +166,12 @@ class PHPExcel_Shared_Date
*
* @param mixed $dateValue PHP serialized date/time or date object
* @return mixed Excel date/time value
* or boolean False on failure
* or boolean FALSE on failure
*/
public static function PHPToExcel($dateValue = 0) {
$saveTimeZone = date_default_timezone_get();
date_default_timezone_set('UTC');
$retValue = False;
$retValue = FALSE;
if ((is_object($dateValue)) && ($dateValue instanceof self::$dateTimeObjectType)) {
$retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'),
$dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s')
@ -204,12 +204,12 @@ class PHPExcel_Shared_Date
// Fudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel
// This affects every date following 28th February 1900
//
$excel1900isLeapYear = True;
if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = False; }
$excel1900isLeapYear = TRUE;
if (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = FALSE; }
$myExcelBaseDate = 2415020;
} else {
$myExcelBaseDate = 2416481;
$excel1900isLeapYear = False;
$excel1900isLeapYear = FALSE;
}
// Julian base date Adjustment
@ -264,6 +264,10 @@ class PHPExcel_Shared_Date
public static function isDateTimeFormatCode($pFormatCode = '') {
// Switch on formatcode
switch ($pFormatCode) {
// General contains an epoch letter 'e', so we trap for it explicitly here
case PHPExcel_Style_NumberFormat::GENERAL:
return FALSE;
// Explicitly defined date formats
case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD:
case PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2:
case PHPExcel_Style_NumberFormat::FORMAT_DATE_DDMMYYYY:
@ -286,32 +290,32 @@ class PHPExcel_Shared_Date
case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX16:
case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX17:
case PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX22:
return true;
return TRUE;
}
// Typically number, currency or accounting (or occasionally fraction) formats
if ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) {
return false;
return FALSE;
}
// Try checking for any of the date formatting characters that don't appear within square braces
if (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$pFormatCode)) {
// We might also have a format mask containing quoted strings...
// we don't want to test for any of our characters within the quoted blocks
if (strpos($pFormatCode,'"') !== false) {
$i = false;
if (strpos($pFormatCode,'"') !== FALSE) {
$i = FALSE;
foreach(explode('"',$pFormatCode) as $subVal) {
// Only test in alternate array entries (the non-quoted blocks)
if (($i = !$i) && (preg_match('/(^|\])[^\[]*['.self::$possibleDateFormatCharacters.']/i',$subVal))) {
return true;
return TRUE;
}
}
return false;
return FALSE;
}
return true;
return TRUE;
}
// No date...
return false;
return FALSE;
} // function isDateTimeFormatCode()
@ -319,23 +323,23 @@ class PHPExcel_Shared_Date
* Convert a date/time string to Excel time
*
* @param string $dateValue Examples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10'
* @return float|false Excel date/time serial value
* @return float|FALSE Excel date/time serial value
*/
public static function stringToExcel($dateValue = '') {
if (strlen($dateValue) < 2)
return false;
return FALSE;
if (!preg_match('/^(\d{1,4}[ \.\/\-][A-Z]{3,9}([ \.\/\-]\d{1,4})?|[A-Z]{3,9}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?|\d{1,4}[ \.\/\-]\d{1,4}([ \.\/\-]\d{1,4})?)( \d{1,2}:\d{1,2}(:\d{1,2})?)?$/iu', $dateValue))
return false;
return FALSE;
$dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue);
if ($dateValueNew === PHPExcel_Calculation_Functions::VALUE()) {
return false;
return FALSE;
} else {
if (strpos($dateValue, ':') !== false) {
if (strpos($dateValue, ':') !== FALSE) {
$timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($dateValue);
if ($timeValue === PHPExcel_Calculation_Functions::VALUE()) {
return false;
return FALSE;
}
$dateValueNew += $timeValue;
}

View File

@ -89,6 +89,7 @@ Fixed in develop branch:
- Bugfix: (seltzlab) Fix to excel2007 Chart Writer when a $plotSeriesValues is empty
- Bugfix: (MBaker) Work item 18370 - Error loading xlsx file with column breaks
- Bugfix: (MBaker) OOCalc Reader now handles percentage and currency data types
- Bugfix: (MBaker) OOCalc Reader modified to process number-rows-repeated
2012-05-19 (v1.7.7):