diff --git a/Examples/.gitignore b/Examples/.gitignore
index 1888a98f..10192af2 100644
--- a/Examples/.gitignore
+++ b/Examples/.gitignore
@@ -1,3 +1,5 @@
-
*.xls
-*.xlsx
\ No newline at end of file
+*.xlsx
+*.csv
+*.jpg
+*.pdf
\ No newline at end of file
diff --git a/Examples/01simple.php b/Examples/01simple.php
index 5ff6fc13..b4a62494 100644
--- a/Examples/01simple.php
+++ b/Examples/01simple.php
@@ -78,6 +78,21 @@ $objPHPExcel->getActiveSheet()
->setWrapText(true);
+$value = "-ValueA\n-Value B\n-Value C";
+$objPHPExcel->getActiveSheet()
+ ->setCellValue('A10', $value);
+$objPHPExcel->getActiveSheet()
+ ->getRowDimension(10)
+ ->setRowHeight(-1);
+$objPHPExcel->getActiveSheet()
+ ->getStyle('A10')
+ ->getAlignment()
+ ->setWrapText(true);
+$objPHPExcel->getActiveSheet()
+ ->getStyle('A10')
+ ->setQuotePrefix(true);
+
+
// Rename worksheet
echo date('H:i:s') , " Rename worksheet" , EOL;
$objPHPExcel->getActiveSheet()
diff --git a/composer.json b/composer.json
index 940deec1..68c1da44 100644
--- a/composer.json
+++ b/composer.json
@@ -22,7 +22,7 @@
}
],
"require": {
- "php": ">=5.4.0",
+ "php": "^5.4|^7.0",
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*"
diff --git a/src/PhpSpreadsheet/Calculation.php b/src/PhpSpreadsheet/Calculation.php
index 269fabcf..2b12ee7d 100644
--- a/src/PhpSpreadsheet/Calculation.php
+++ b/src/PhpSpreadsheet/Calculation.php
@@ -203,10 +203,10 @@ class Calculation
/**
* Epsilon Precision used for comparisons in calculations
*
- * @var integer
+ * @var float
*
*/
- private $delta = 0.0000000000001;
+ private $delta = 0.1e-12;
/**
@@ -1490,7 +1490,7 @@ class Calculation
'OFFSET' => array(
'category' => Calculation\Categories::CATEGORY_LOOKUP_AND_REFERENCE,
'functionCall' => '\\PHPExcel\\Calculation\\LookupRef::OFFSET',
- 'argumentCount' => '3,5',
+ 'argumentCount' => '3-5',
'passCellReference' => true,
'passByReference' => array(true)
),
@@ -2061,14 +2061,10 @@ class Calculation
);
- private function __construct(Spreadsheet $spreadsheet = null)
+ public function __construct(Spreadsheet $spreadsheet = null)
{
$this->delta = 1 * pow(10, 0 - ini_get('precision'));
- if ($spreadsheet !== null) {
- self::$spreadsheetSets[$spreadsheet->getID()] = $this;
- }
-
$this->spreadsheet = $spreadsheet;
$this->cyclicReferenceStack = new CalcEngine\CyclicReferenceStack();
$this->_debugLog = new CalcEngine\Logger($this->cyclicReferenceStack);
@@ -2097,10 +2093,10 @@ class Calculation
public static function getInstance(Spreadsheet $spreadsheet = null)
{
if ($spreadsheet !== null) {
- if (isset(self::$spreadsheetSets[$spreadsheet->getID()])) {
- return self::$spreadsheetSets[$spreadsheet->getID()];
+ $instance = $workbook->getCalculationEngine();
+ if (isset($instance)) {
+ return $instance;
}
- return new Calculation($spreadsheet);
}
if (!isset(self::$instance) || (self::$instance === null)) {
@@ -2116,13 +2112,9 @@ class Calculation
* @access public
* @param Spreadsheet $spreadsheet Injected spreadsheet identifying the instance to unset
*/
- public static function unsetInstance(Spreadsheet $spreadsheet = null)
+ public function __destruct()
{
- if ($spreadsheet !== null) {
- if (isset(self::$spreadsheetSets[$spreadsheet->getID()])) {
- unset(self::$spreadsheetSets[$spreadsheet->getID()]);
- }
- }
+ $this->workbook = null;
}
/**
diff --git a/src/PhpSpreadsheet/Calculation/Financial.php b/src/PhpSpreadsheet/Calculation/Financial.php
index 126b8f07..ce50f91f 100644
--- a/src/PhpSpreadsheet/Calculation/Financial.php
+++ b/src/PhpSpreadsheet/Calculation/Financial.php
@@ -2139,8 +2139,8 @@ class Financial
if ((!is_array($values)) && (!is_array($dates))) {
return Functions::VALUE();
}
- $values = Functions::flattenArray($values);
- $dates = Functions::flattenArray($dates);
+ $values = Functions::flattenArray($values);
+ $dates = Functions::flattenArray($dates);
$guess = Functions::flattenSingleValue($guess);
if (count($values) != count($dates)) {
return Functions::NaN();
diff --git a/src/PhpSpreadsheet/Calculation/Functions.php b/src/PhpSpreadsheet/Calculation/Functions.php
index c0dc853b..dfbff0a5 100644
--- a/src/PhpSpreadsheet/Calculation/Functions.php
+++ b/src/PhpSpreadsheet/Calculation/Functions.php
@@ -546,10 +546,8 @@ class Functions
case 'float':
case 'integer':
return $value;
- break;
case 'boolean':
return (integer) $value;
- break;
case 'string':
// Errors
if ((strlen($value) > 0) && ($value{0} == '#')) {
diff --git a/src/PhpSpreadsheet/Reader/Excel2003XML.php b/src/PhpSpreadsheet/Reader/Excel2003XML.php
index 8ba1c0f6..51d696fb 100644
--- a/src/PhpSpreadsheet/Reader/Excel2003XML.php
+++ b/src/PhpSpreadsheet/Reader/Excel2003XML.php
@@ -406,11 +406,7 @@ class Excel2003XML extends BaseReader implements IReader
$style_ss = $style->attributes($namespaces['ss']);
$styleID = (string) $style_ss['ID'];
// echo 'Style ID = '.$styleID.'
';
- if ($styleID == 'Default') {
- $this->styles['Default'] = array();
- } else {
- $this->styles[$styleID] = $this->styles['Default'];
- }
+ $this->styles[$styleID] = (isset($this->styles['Default'])) ? $this->styles['Default'] : array();
foreach ($style as $styleType => $styleData) {
$styleAttributes = $styleData->attributes($namespaces['ss']);
// echo $styleType.'
';
diff --git a/src/PhpSpreadsheet/Reader/Excel2007.php b/src/PhpSpreadsheet/Reader/Excel2007.php
index 27b3c9bb..e1331c26 100644
--- a/src/PhpSpreadsheet/Reader/Excel2007.php
+++ b/src/PhpSpreadsheet/Reader/Excel2007.php
@@ -339,10 +339,17 @@ class Excel2007 extends BaseReader implements IReader
}
$fileName = \PHPExcel\Shared\File::realpath($fileName);
+ // Sadly, some 3rd party xlsx generators don't use consistent case for filenaming
+ // so we need to load case-insensitively from the zip file
+
// Apache POI fixes
- $contents = $archive->getFromName($fileName);
+ $contents = $archive->getFromIndex(
+ $archive->locateName($fileName, ZIPARCHIVE::FL_NOCASE)
+ );
if ($contents === false) {
- $contents = $archive->getFromName(substr($fileName, 1));
+ $contents = $archive->getFromIndex(
+ $archive->locateName(substr($fileName, 1), ZIPARCHIVE::FL_NOCASE)
+ );
}
return $contents;
diff --git a/src/PhpSpreadsheet/Reader/Excel2007/Chart.php b/src/PhpSpreadsheet/Reader/Excel2007/Chart.php
index 81c9b4b7..ae86bbbb 100644
--- a/src/PhpSpreadsheet/Reader/Excel2007/Chart.php
+++ b/src/PhpSpreadsheet/Reader/Excel2007/Chart.php
@@ -346,10 +346,6 @@ class Chart
}
}
- if (empty($seriesVal)) {
- $seriesVal = null;
- }
-
return array(
'formatCode' => $formatCode,
'pointCount' => $pointCount,
diff --git a/src/PhpSpreadsheet/Reader/Excel5.php b/src/PhpSpreadsheet/Reader/Excel5.php
index 7243a717..cf2cfb78 100644
--- a/src/PhpSpreadsheet/Reader/Excel5.php
+++ b/src/PhpSpreadsheet/Reader/Excel5.php
@@ -1733,16 +1733,16 @@ class Excel5 extends BaseReader implements IReader
if ($length != 54) {
throw new Exception('Unexpected file pass record length');
}
-
+
$recordData = $this->readRecordData($this->data, $this->pos + 4, $length);
-
+
// move stream pointer to next record
$this->pos += 4 + $length;
-
+
if (!$this->verifyPassword('VelvetSweatshop', substr($recordData, 6, 16), substr($recordData, 22, 16), substr($recordData, 38, 16), $this->md5Ctxt)) {
throw new Exception('Decryption password incorrect');
}
-
+
$this->encryption = self::MS_BIFF_CRYPTO_RC4;
// Decryption required from the record after next onwards
diff --git a/src/PhpSpreadsheet/Reader/HTML.php b/src/PhpSpreadsheet/Reader/HTML.php
index 7efc4496..e24478f8 100644
--- a/src/PhpSpreadsheet/Reader/HTML.php
+++ b/src/PhpSpreadsheet/Reader/HTML.php
@@ -486,7 +486,7 @@ class HTML extends BaseReader implements IReader
// Create a new DOM object
$dom = new domDocument;
// Reload the HTML file into the DOM object
- $loaded = $dom->loadHTML($this->securityScanFile($pFilename));
+ $loaded = $dom->loadHTML(mb_convert_encoding($this->securityScanFile($pFilename), 'HTML-ENTITIES', 'UTF-8'));
if ($loaded === false) {
throw new Exception('Failed to load ', $pFilename, ' as a DOM Document');
}
diff --git a/src/PhpSpreadsheet/Shared/ZipArchive.php b/src/PhpSpreadsheet/Shared/ZipArchive.php
index 03fe528b..981eeebd 100644
--- a/src/PhpSpreadsheet/Shared/ZipArchive.php
+++ b/src/PhpSpreadsheet/Shared/ZipArchive.php
@@ -110,17 +110,19 @@ class ZipArchive
*/
public function locateName($fileName)
{
+ $fileName = strtolower($fileName);
+
$list = $this->zip->listContent();
$listCount = count($list);
- $list_index = -1;
+ $index = -1;
for ($i = 0; $i < $listCount; ++$i) {
if (strtolower($list[$i]["filename"]) == strtolower($fileName) ||
strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) {
- $list_index = $i;
+ $index = $i;
break;
}
}
- return ($list_index > -1);
+ return ($index > -1) ? $index : false;
}
/**
@@ -131,36 +133,32 @@ class ZipArchive
*/
public function getFromName($fileName)
{
- $list = $this->zip->listContent();
- $listCount = count($list);
- $list_index = -1;
- for ($i = 0; $i < $listCount; ++$i) {
- if (strtolower($list[$i]["filename"]) == strtolower($fileName) ||
- strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) {
- $list_index = $i;
- break;
+ $index = $this->locateName($fileName);
+
+ if ($index !== false) {
+ $extracted = $this->getFromIndex($index);
+ } else {
+ $fileName = substr($fileName, 1);
+ $index = $this->locateName($fileName);
+ if ($index === false) {
+ return false;
}
+ $extracted = $this->zip->getFromIndex($index);
}
- $extracted = "";
- if ($list_index != -1) {
- $extracted = $this->zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING);
- } else {
- $filename = substr($fileName, 1);
- $list_index = -1;
- for ($i = 0; $i < $listCount; ++$i) {
- if (strtolower($list[$i]["filename"]) == strtolower($fileName) ||
- strtolower($list[$i]["stored_filename"]) == strtolower($fileName)) {
- $list_index = $i;
- break;
- }
- }
- $extracted = $this->zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING);
- }
+ $contents = $extracted;
if ((is_array($extracted)) && ($extracted != 0)) {
$contents = $extracted[0]["content"];
}
return $contents;
}
+
+ public function getFromIndex($index) {
+ $extracted = $this->zip->extractByIndex($index, PCLZIP_OPT_EXTRACT_AS_STRING);
+ $contents = '';
+ if ((is_array($extracted)) && ($extracted != 0)) {
+ $contents = $extracted[0]["content"];
+ }
+ }
}
diff --git a/src/PhpSpreadsheet/Spreadsheet.php b/src/PhpSpreadsheet/Spreadsheet.php
index 0223b78c..a2d27a23 100644
--- a/src/PhpSpreadsheet/Spreadsheet.php
+++ b/src/PhpSpreadsheet/Spreadsheet.php
@@ -360,7 +360,7 @@ class Spreadsheet
public function __construct()
{
$this->uniqueID = uniqid();
- $this->calculationEngine = Calculation::getInstance($this);
+ $this->calculationEngine = new Calculation($this);
// Initialise worksheet collection and add one worksheet
$this->workSheetCollection = array();
@@ -391,7 +391,7 @@ class Spreadsheet
*/
public function __destruct()
{
- Calculation::unsetInstance($this);
+ $this->calculationEngine = null;
$this->disconnectWorksheets();
}
diff --git a/src/PhpSpreadsheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet.php
index f1f5256c..78cc071c 100644
--- a/src/PhpSpreadsheet/Worksheet.php
+++ b/src/PhpSpreadsheet/Worksheet.php
@@ -863,10 +863,10 @@ class Worksheet implements IComparable
$this->title = $pValue;
$this->dirty = true;
- if ($this->parent) {
+ if ($this->parent && $this->parent->getCalculationEngine()) {
// New title
$newTitle = $this->getTitle();
- Calculation::getInstance($this->parent)
+ $this->parent->getCalculationEngine()
->renameCalculationCacheForWorksheet($oldTitle, $newTitle);
if ($updateFormulaCellReferences) {
ReferenceHelper::getInstance()->updateNamedFormulas($this->parent, $oldTitle, $newTitle);
diff --git a/src/PhpSpreadsheet/Worksheet/ColumnIterator.php b/src/PhpSpreadsheet/Worksheet/ColumnIterator.php
index 9146c982..a8e82914 100644
--- a/src/PhpSpreadsheet/Worksheet/ColumnIterator.php
+++ b/src/PhpSpreadsheet/Worksheet/ColumnIterator.php
@@ -66,7 +66,7 @@ class ColumnIterator implements \Iterator
* @param string $startColumn The column address at which to start iterating
* @param string $endColumn Optionally, the column address at which to stop iterating
*/
- public function __construct(\PHPExcel\Worksheet $subject = null, $startColumn = 'A', $endColumn = null)
+ public function __construct(\PHPExcel\Worksheet $subject, $startColumn = 'A', $endColumn = null)
{
// Set subject
$this->subject = $subject;
@@ -87,11 +87,19 @@ class ColumnIterator implements \Iterator
*
* @param integer $startColumn The column address at which to start iterating
* @return ColumnIterator
+ * @throws PHPExcel_Exception
*/
public function resetStart($startColumn = 'A')
{
$startColumnIndex = \PHPExcel\Cell::columnIndexFromString($startColumn) - 1;
+ if ($startColumnIndex > PHPExcel_Cell::columnIndexFromString($this->subject->getHighestColumn()) - 1) {
+ throw new PHPExcel_Exception("Start column ({$startColumn}) is beyond highest column ({$this->subject->getHighestColumn()})");
+ }
+
$this->startColumn = $startColumnIndex;
+ if ($this->endColumn < $this->startColumn) {
+ $this->endColumn = $this->startColumn;
+ }
$this->seek($startColumn);
return $this;
diff --git a/src/PhpSpreadsheet/Worksheet/RowIterator.php b/src/PhpSpreadsheet/Worksheet/RowIterator.php
index d5bc0cc8..80c887f8 100644
--- a/src/PhpSpreadsheet/Worksheet/RowIterator.php
+++ b/src/PhpSpreadsheet/Worksheet/RowIterator.php
@@ -66,7 +66,7 @@ class RowIterator implements \Iterator
* @param integer $startRow The row number at which to start iterating
* @param integer $endRow Optionally, the row number at which to stop iterating
*/
- public function __construct(\PHPExcel\Worksheet $subject = null, $startRow = 1, $endRow = null)
+ public function __construct(\PHPExcel\Worksheet $subject, $startRow = 1, $endRow = null)
{
// Set subject
$this->subject = $subject;
@@ -87,10 +87,18 @@ class RowIterator implements \Iterator
*
* @param integer $startRow The row number at which to start iterating
* @return RowIterator
+ * @throws PHPExcel_Exception
*/
public function resetStart($startRow = 1)
{
+ if ($startRow > $this->subject->getHighestRow()) {
+ throw new PHPExcel_Exception("Start row ({$startRow}) is beyond highest row ({$this->subject->getHighestRow()})");
+ }
+
$this->startRow = $startRow;
+ if ($this->endRow < $this->startRow) {
+ $this->endRow = $this->startRow;
+ }
$this->seek($startRow);
return $this;
diff --git a/src/PhpSpreadsheet/Writer/Excel2007.php b/src/PhpSpreadsheet/Writer/Excel2007.php
index 0f91b9e0..738b2600 100644
--- a/src/PhpSpreadsheet/Writer/Excel2007.php
+++ b/src/PhpSpreadsheet/Writer/Excel2007.php
@@ -290,7 +290,7 @@ class Excel2007 extends BaseWriter implements IWriter
$charts = $this->spreadSheet->getSheet($i)->getChartCollection();
if (count($charts) > 0) {
foreach ($charts as $chart) {
- $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart));
+ $objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart, $this->preCalculateFormulas));
$chartCount++;
}
}
diff --git a/src/PhpSpreadsheet/Writer/Excel2007/Chart.php b/src/PhpSpreadsheet/Writer/Excel2007/Chart.php
index d4afb4fc..35a36a5e 100644
--- a/src/PhpSpreadsheet/Writer/Excel2007/Chart.php
+++ b/src/PhpSpreadsheet/Writer/Excel2007/Chart.php
@@ -28,6 +28,8 @@ namespace PHPExcel\Writer\Excel2007;
*/
class Chart extends WriterPart
{
+ protected $calculateCellValues;
+
/**
* Write charts to XML format
*
@@ -36,8 +38,10 @@ class Chart extends WriterPart
* @return string XML Output
* @throws \PHPExcel\Writer\Exception
*/
- public function writeChart(PHPExcel_Chart $pChart = null)
+ public function writeChart(PHPExcel_Chart $pChart = null, $calculateCellValues = true)
{
+ $this->calculateCellValues = $calculateCellValues;
+
// Create XML writer
$objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
@@ -46,7 +50,9 @@ class Chart extends WriterPart
$objWriter = new \PHPExcel\Shared\XMLWriter(\PHPExcel\Shared\XMLWriter::STORAGE_MEMORY);
}
// Ensure that data series values are up-to-date before we save
- $pChart->refresh();
+ if ($this->calculateCellValues) {
+ $pChart->refresh();
+ }
// XML header
$objWriter->startDocument('1.0', 'UTF-8', 'yes');
diff --git a/src/PhpSpreadsheet/Writer/Excel2007/Rels.php b/src/PhpSpreadsheet/Writer/Excel2007/Rels.php
index ed8298d5..57332bc0 100644
--- a/src/PhpSpreadsheet/Writer/Excel2007/Rels.php
+++ b/src/PhpSpreadsheet/Writer/Excel2007/Rels.php
@@ -89,7 +89,7 @@ class Rels extends WriterPart
);
// a custom UI in workbook ?
if ($pPHPExcel->hasRibbon()) {
- $this->_writeRelationShip(
+ $this->writeRelationShip(
$objWriter,
5,
'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility',
@@ -163,7 +163,7 @@ class Rels extends WriterPart
// Relationships for vbaProject if needed
// id : just after the last sheet
if ($pPHPExcel->hasMacros()) {
- $this->_writeRelationShip(
+ $this->writeRelationShip(
$objWriter,
($i + 1 + 3),
'http://schemas.microsoft.com/office/2006/relationships/vbaProject',