Merge pull request #8 from box/add_multiline_strings_support
Add support for multiline strings
This commit is contained in:
commit
4ca1fc5851
@ -31,6 +31,9 @@ class SharedStringsHelper
|
|||||||
*/
|
*/
|
||||||
const MAX_NUM_STRINGS_PER_TEMP_FILE = 10000;
|
const MAX_NUM_STRINGS_PER_TEMP_FILE = 10000;
|
||||||
|
|
||||||
|
/** Value to use to escape the line feed character ("\n") */
|
||||||
|
const ESCAPED_LINE_FEED_CHARACTER = '_x000A_';
|
||||||
|
|
||||||
/** @var string Path of the XLSX file being read */
|
/** @var string Path of the XLSX file being read */
|
||||||
protected $filePath;
|
protected $filePath;
|
||||||
|
|
||||||
@ -80,7 +83,6 @@ class SharedStringsHelper
|
|||||||
* Please note that SimpleXML does not provide such a functionality but since it is faster
|
* Please note that SimpleXML does not provide such a functionality but since it is faster
|
||||||
* and more handy to parse few XML nodes, it is used in combination with XMLReader for that purpose.
|
* and more handy to parse few XML nodes, it is used in combination with XMLReader for that purpose.
|
||||||
*
|
*
|
||||||
* @param string $filePath
|
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Box\Spout\Common\Exception\IOException If sharedStrings.xml can't be read
|
* @throws \Box\Spout\Common\Exception\IOException If sharedStrings.xml can't be read
|
||||||
*/
|
*/
|
||||||
@ -120,7 +122,12 @@ class SharedStringsHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
$unescapedTextValue = $escaper->unescape($textValue);
|
$unescapedTextValue = $escaper->unescape($textValue);
|
||||||
$this->writeSharedStringToTempFile($unescapedTextValue, $sharedStringIndex);
|
|
||||||
|
// The shared string retrieval logic expects each cell data to be on one line only
|
||||||
|
// Encoding the line feed character allows to preserve this assumption
|
||||||
|
$lineFeedEncodedTextValue = $this->escapeLineFeed($unescapedTextValue);
|
||||||
|
|
||||||
|
$this->writeSharedStringToTempFile($lineFeedEncodedTextValue, $sharedStringIndex);
|
||||||
|
|
||||||
$sharedStringIndex++;
|
$sharedStringIndex++;
|
||||||
|
|
||||||
@ -246,7 +253,8 @@ class SharedStringsHelper
|
|||||||
|
|
||||||
$sharedString = null;
|
$sharedString = null;
|
||||||
if (array_key_exists($indexInFile, $this->inMemoryTempFileContents)) {
|
if (array_key_exists($indexInFile, $this->inMemoryTempFileContents)) {
|
||||||
$sharedString = $this->inMemoryTempFileContents[$indexInFile];
|
$escapedSharedString = $this->inMemoryTempFileContents[$indexInFile];
|
||||||
|
$sharedString = $this->unescapeLineFeed($escapedSharedString);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$sharedString) {
|
if (!$sharedString) {
|
||||||
@ -256,6 +264,28 @@ class SharedStringsHelper
|
|||||||
return rtrim($sharedString, PHP_EOL);
|
return rtrim($sharedString, PHP_EOL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes the line feed character (\n)
|
||||||
|
*
|
||||||
|
* @param string $unescapedString
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function escapeLineFeed($unescapedString)
|
||||||
|
{
|
||||||
|
return str_replace("\n", self::ESCAPED_LINE_FEED_CHARACTER, $unescapedString);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unescapes the line feed character (\n)
|
||||||
|
*
|
||||||
|
* @param string $escapedString
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function unescapeLineFeed($escapedString)
|
||||||
|
{
|
||||||
|
return str_replace(self::ESCAPED_LINE_FEED_CHARACTER, "\n", $escapedString);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes the created temporary folder and all its contents
|
* Deletes the created temporary folder and all its contents
|
||||||
*
|
*
|
||||||
|
@ -5,7 +5,6 @@ namespace Box\Spout\Writer\Internal\XLSX;
|
|||||||
use Box\Spout\Writer\Exception\SheetNotFoundException;
|
use Box\Spout\Writer\Exception\SheetNotFoundException;
|
||||||
use Box\Spout\Writer\Helper\XLSX\FileSystemHelper;
|
use Box\Spout\Writer\Helper\XLSX\FileSystemHelper;
|
||||||
use Box\Spout\Writer\Helper\XLSX\SharedStringsHelper;
|
use Box\Spout\Writer\Helper\XLSX\SharedStringsHelper;
|
||||||
use Box\Spout\Writer\Helper\XLSX\ZipHelper;
|
|
||||||
use Box\Spout\Writer\Sheet;
|
use Box\Spout\Writer\Sheet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,7 +42,8 @@ EOD;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \Box\Spout\Writer\Sheet $externalSheet The associated "external" sheet
|
* @param \Box\Spout\Writer\Sheet $externalSheet The associated "external" sheet
|
||||||
* @param string $tempFolder Temporary folder where the files to create the XLSX will be stored
|
* @param string $worksheetFilesFolder Temporary folder where the files to create the XLSX will be stored
|
||||||
|
* @param \Box\Spout\Writer\Helper\XLSX\SharedStringsHelper $sharedStringsHelper Helper for shared strings
|
||||||
* @param bool $shouldUseInlineStrings Whether inline or shared strings should be used
|
* @param bool $shouldUseInlineStrings Whether inline or shared strings should be used
|
||||||
* @throws \Box\Spout\Common\Exception\IOException If the sheet data file cannot be opened for writing
|
* @throws \Box\Spout\Common\Exception\IOException If the sheet data file cannot be opened for writing
|
||||||
*/
|
*/
|
||||||
|
@ -46,7 +46,7 @@ class SharedStringsHelperTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals(1, count($filesInTempFolder), 'One temp file should have been created in the temp folder.');
|
$this->assertEquals(1, count($filesInTempFolder), 'One temp file should have been created in the temp folder.');
|
||||||
|
|
||||||
$tempFileContents = file_get_contents($filesInTempFolder[0]);
|
$tempFileContents = file_get_contents($filesInTempFolder[0]);
|
||||||
$tempFileContentsPerLine = explode("\n", $tempFileContents);
|
$tempFileContentsPerLine = explode(PHP_EOL, $tempFileContents);
|
||||||
|
|
||||||
$this->assertEquals('s1--A1', $tempFileContentsPerLine[0]);
|
$this->assertEquals('s1--A1', $tempFileContentsPerLine[0]);
|
||||||
$this->assertEquals('s1--E5', $tempFileContentsPerLine[24]);
|
$this->assertEquals('s1--E5', $tempFileContentsPerLine[24]);
|
||||||
@ -96,4 +96,23 @@ class SharedStringsHelperTest extends \PHPUnit_Framework_TestCase
|
|||||||
$sharedString = $this->sharedStringsHelper->getStringAtIndex(24);
|
$sharedString = $this->sharedStringsHelper->getStringAtIndex(24);
|
||||||
$this->assertEquals('s1--E5', $sharedString);
|
$this->assertEquals('s1--E5', $sharedString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testGetStringAtIndexShouldWorkWithMultilineStrings()
|
||||||
|
{
|
||||||
|
$resourcePath = $this->getResourcePath('one_sheet_with_shared_multiline_strings.xlsx');
|
||||||
|
$sharedStringsHelper = new SharedStringsHelper($resourcePath);
|
||||||
|
|
||||||
|
$sharedStringsHelper->extractSharedStrings();
|
||||||
|
|
||||||
|
$sharedString = $sharedStringsHelper->getStringAtIndex(0);
|
||||||
|
$this->assertEquals("s1\nA1", $sharedString);
|
||||||
|
|
||||||
|
$sharedString = $sharedStringsHelper->getStringAtIndex(24);
|
||||||
|
$this->assertEquals("s1\nE5", $sharedString);
|
||||||
|
|
||||||
|
$sharedStringsHelper->cleanup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,6 +135,6 @@ class CSVTest extends \PHPUnit_Framework_TestCase
|
|||||||
private function trimWrittenContent($writtenContent)
|
private function trimWrittenContent($writtenContent)
|
||||||
{
|
{
|
||||||
// remove line feeds and UTF-8 BOM
|
// remove line feeds and UTF-8 BOM
|
||||||
return trim($writtenContent, "\n" . CSV::UTF8_BOM);
|
return trim($writtenContent, PHP_EOL . CSV::UTF8_BOM);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user