Compare commits

..
8 Commits
Author SHA1 Message Date
Adrien Loison d617a50b85 Merge pull request #44 from box/bump_to_v1.0.9
Bump to version 1.0.9
2015-05-29 09:50:21 -07:00
Adrien Loison 92981fa80b Bump to version 1.0.9 2015-05-29 09:42:38 -07:00
Adrien Loison 766c733466 Update README.md
Added question about charts and formulas in the FAQ
2015-05-29 09:39:36 -07:00
Adrien Loison 46cae76546 Update README.md
Added new badges
2015-05-29 09:30:40 -07:00
Adrien Loison 03be58b84d Merge pull request #43 from box/support_files_with_formulas
Add support for files containing formulas
2015-05-29 09:08:48 -07:00
Adrien Loison b21bb86682 Add support for files containing formulas
Formulas will be skipped on reading.
The result of the formulas will be kept though.
2015-05-29 09:01:28 -07:00
Adrien Loison 8a45cec220 Merge pull request #42 from box/support_files_without_shared_strings
Support XLSX that don't have a sharedStrings.xml file
2015-05-28 18:06:09 -07:00
Adrien Loison 04d41d7c9f Support XLSX that don't have a sharedStrings.xml file 2015-05-28 17:59:30 -07:00
7 changed files with 80 additions and 23 deletions

No files matched your search

+10 -3
View File
@@ -1,11 +1,13 @@
# Spout
[![Latest Stable Version](https://poser.pugx.org/box/spout/v/stable)](https://packagist.org/packages/box/spout)
[![Project Status](http://opensource.box.com/badges/active.svg)](http://opensource.box.com/badges)
[![Build Status](https://travis-ci.org/box/spout.png?branch=master)](http://travis-ci.org/box/spout)
[![Total Downloads](https://poser.pugx.org/box/spout/downloads)](https://packagist.org/packages/box/spout) [![License](https://poser.pugx.org/box/spout/license)](https://packagist.org/packages/box/spout)
Spout is a PHP library to read and write CSV and XLSX files, in a fast and scalable way.
Contrary to other file readers or writers, it is capable of processing very large files while keeping the memory usage really low (less than 10MB).
[![Build Status](https://travis-ci.org/box/spout.png?branch=master)](http://travis-ci.org/box/spout)
[![Project Status](http://opensource.box.com/badges/active.svg)](http://opensource.box.com/badges)
## Installation
@@ -248,6 +250,11 @@ Here are a few numbers regarding the performance of Spout:
| Read XLSX (using shared strings) | 1 second | 1-2 minutes | 35-40 minutes |
| Write XLSX | 1 second | 20-25 seconds | 8-10 minutes |
#### Does Spout support charts or formulas?
No. This is a compromise to keep memory usage low. Charts and formulas requires data to be kept in memory in order to be used.
So the larger the file would be, the more memory would be consumed, preventing your code to scale well.
## Support
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "box/spout",
"description": "PHP Library to read and write CSV and XLSX files, in a fast and scalable way",
"type": "library",
"version": "1.0.8",
"version": "1.0.9",
"keywords": ["php","read","write","csv","xlsx","excel","spreadsheet","scale","memory","stream","ooxml"],
"license": "Apache-2.0",
"homepage": "https://www.github.com/box/spout",
@@ -71,6 +71,24 @@ class SharedStringsHelper
$this->tempFolder = $this->fileSystemHelper->createFolder($rootTempFolder, uniqid('sharedstrings'));
}
/**
* Returns whether the XLSX file contains a shared strings XML file
*
* @return bool
*/
public function hasSharedStrings()
{
$hasSharedStrings = false;
$zip = new \ZipArchive();
if ($zip->open($this->filePath) === true) {
$hasSharedStrings = ($zip->locateName(self::SHARED_STRINGS_XML_FILE_PATH) !== false);
$zip->close();
}
return $hasSharedStrings;
}
/**
* Builds an in-memory array containing all the shared strings of the worksheet.
* All the strings are stored in a XML file, located at 'xl/sharedStrings.xml'.
+22 -19
View File
@@ -72,8 +72,12 @@ class XLSX extends AbstractReader
$this->zip = new \ZipArchive();
if ($this->zip->open($filePath) === true) {
// Extracts all the strings from the worksheets for easy access in the future
$this->extractSharedStrings($filePath);
$this->sharedStringsHelper = new SharedStringsHelper($filePath, $this->tempFolder);
if ($this->sharedStringsHelper->hasSharedStrings()) {
// Extracts all the strings from the worksheets for easy access in the future
$this->sharedStringsHelper->extractSharedStrings();
}
// Fetch all available worksheets
$this->worksheetHelper = new WorksheetHelper($filePath, $this->globalFunctionsHelper);
@@ -87,19 +91,6 @@ class XLSX extends AbstractReader
}
}
/**
* Builds an in-memory array containing all the shared strings of the worksheets.
*
* @param string $filePath Path of the XLSX file to be read
* @return void
* @throws \Box\Spout\Common\Exception\IOException If sharedStrings XML file can't be read
*/
protected function extractSharedStrings($filePath)
{
$this->sharedStringsHelper = new SharedStringsHelper($filePath, $this->tempFolder);
$this->sharedStringsHelper->extractSharedStrings();
}
/**
* Returns whether another worksheet exists after the current worksheet.
*
@@ -215,13 +206,25 @@ class XLSX extends AbstractReader
$currentColumnIndex = CellHelper::getColumnIndexFromCellIndex($currentCellIndex);
$node = $this->xmlReader->expand();
$hasInlineString = ($this->xmlReader->getAttribute('t') === 'inlineStr');
$hasSharedString = ($this->xmlReader->getAttribute('t') === 's');
if ($hasSharedString) {
$sharedStringIndex = intval($node->nodeValue);
if ($hasInlineString) {
// inline strings are formatted this way:
// <c r="A1" t="inlineStr"><is><t>[INLINE_STRING]</t></is></c>
$tNode = $node->getElementsByTagName('t')->item(0);
$rowData[$currentColumnIndex] = trim($tNode->nodeValue);
} else if ($hasSharedString) {
// shared strings are formatted this way:
// <c r="A1" t="s"><v>[SHARED_STRING_INDEX]</v></c>
$vNode = $node->getElementsByTagName('v')->item(0);
$sharedStringIndex = intval($vNode->nodeValue);
$rowData[$currentColumnIndex] = $this->sharedStringsHelper->getStringAtIndex($sharedStringIndex);
} else {
// for inline strings or numbers, just get the value
$rowData[$currentColumnIndex] = trim($node->nodeValue);
// other values are formatted this way:
// <c r="A1"><v>[VALUE]</v></c>
$vNode = $node->getElementsByTagName('v')->item(0);
$rowData[$currentColumnIndex] = intval($vNode->nodeValue);
}
} else if ($this->xmlReader->nodeType == \XMLReader::END_ELEMENT && $this->xmlReader->name === 'row') {
// End of the row description
+29
View File
@@ -100,6 +100,20 @@ class XLSXTest extends \PHPUnit_Framework_TestCase
}
}
/**
* @return void
*/
public function testReadShouldSupportFilesWithoutSharedStringsFile()
{
$allRows = $this->getAllRowsForFile('sheet_with_no_shared_strings_file.xlsx');
$expectedRows = [
[10, 11],
[20, 21],
];
$this->assertEquals($expectedRows, $allRows);
}
/**
* @return void
*/
@@ -231,6 +245,21 @@ class XLSXTest extends \PHPUnit_Framework_TestCase
$this->assertEquals([], $allRows, 'Sheet with no cells should be correctly processed.');
}
/**
* @return void
*/
public function testReadShouldSkipFormulas()
{
$allRows = $this->getAllRowsForFile('sheet_with_formulas.xlsx');
$expectedRows = [
['val1', 'val2', 'total1', 'total2'],
[10, 20, 30, 21],
[11, 21, 32, 41],
];
$this->assertEquals($expectedRows, $allRows);
}
/**
* @param string $fileName
* @return array All the read rows the given file
Binary file not shown.