Fix XLSX Writer on Windows plaftorms
A bug was introduced, preventing Spout to create valid XLSX files on Windows. This commits reverts the changes that introduced DIRECTORY_SEPARATOR everywhere and fixes the original issue with the writer by normalizing paths when creating the zipped file.
This commit is contained in:
parent
c6ebf115fc
commit
b3df57d2e5
@ -36,7 +36,7 @@ class FileSystemHelper
|
||||
{
|
||||
$this->throwIfOperationNotInBaseFolder($parentFolderPath);
|
||||
|
||||
$folderPath = $parentFolderPath . DIRECTORY_SEPARATOR . $folderName;
|
||||
$folderPath = $parentFolderPath . '/' . $folderName;
|
||||
|
||||
$wasCreationSuccessful = mkdir($folderPath, 0777, true);
|
||||
if (!$wasCreationSuccessful) {
|
||||
@ -60,7 +60,7 @@ class FileSystemHelper
|
||||
{
|
||||
$this->throwIfOperationNotInBaseFolder($parentFolderPath);
|
||||
|
||||
$filePath = $parentFolderPath . DIRECTORY_SEPARATOR . $fileName;
|
||||
$filePath = $parentFolderPath . '/' . $fileName;
|
||||
|
||||
$wasCreationSuccessful = file_put_contents($filePath, $fileContents);
|
||||
if (!$wasCreationSuccessful) {
|
||||
|
@ -162,12 +162,11 @@ class SharedStringsHelper
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string The path to the shared strings XML file, working cross-platforms
|
||||
* @return string The path to the shared strings XML file
|
||||
*/
|
||||
protected function getSharedStringsFilePath()
|
||||
{
|
||||
$sharedStringsXmlFilePath = str_replace('/', DIRECTORY_SEPARATOR, self::SHARED_STRINGS_XML_FILE_PATH);
|
||||
return 'zip://' . $this->filePath . '#' . $sharedStringsXmlFilePath;
|
||||
return 'zip://' . $this->filePath . '#' . self::SHARED_STRINGS_XML_FILE_PATH;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -250,7 +249,7 @@ class SharedStringsHelper
|
||||
protected function getSharedStringTempFilePath($sharedStringIndex)
|
||||
{
|
||||
$numTempFile = intval($sharedStringIndex / self::MAX_NUM_STRINGS_PER_TEMP_FILE);
|
||||
return $this->tempFolder . DIRECTORY_SEPARATOR . 'sharedstrings' . $numTempFile;
|
||||
return $this->tempFolder . '/sharedstrings' . $numTempFile;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -186,8 +186,7 @@ class WorksheetHelper
|
||||
*/
|
||||
protected function getFileAsXMLElementWithNamespace($xmlFilePath, $mainNamespace)
|
||||
{
|
||||
$normalizedXmlFilePath = str_replace('/', DIRECTORY_SEPARATOR, $xmlFilePath);
|
||||
$xmlContents = $this->globalFunctionsHelper->file_get_contents('zip://' . $this->filePath . '#' . $normalizedXmlFilePath);
|
||||
$xmlContents = $this->globalFunctionsHelper->file_get_contents('zip://' . $this->filePath . '#' . $xmlFilePath);
|
||||
|
||||
$xmlElement = new \SimpleXMLElement($xmlContents);
|
||||
$xmlElement->registerXPathNamespace('ns', $mainNamespace);
|
||||
|
@ -33,12 +33,11 @@ class Worksheet
|
||||
|
||||
/**
|
||||
* @return string Path of the XML file containing the worksheet data,
|
||||
* without the leading slash and working cross-platforms.
|
||||
* without the leading slash.
|
||||
*/
|
||||
public function getDataXmlFilePath()
|
||||
{
|
||||
$dataXmlFilePath = ltrim($this->dataXmlFilePath, '/');
|
||||
return str_replace('/', DIRECTORY_SEPARATOR, $dataXmlFilePath);
|
||||
return ltrim($this->dataXmlFilePath, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,7 +36,7 @@ EOD;
|
||||
*/
|
||||
public function __construct($xlFolder)
|
||||
{
|
||||
$sharedStringsFilePath = $xlFolder . DIRECTORY_SEPARATOR . self::SHARED_STRINGS_FILE_NAME;
|
||||
$sharedStringsFilePath = $xlFolder . '/' . self::SHARED_STRINGS_FILE_NAME;
|
||||
$this->sharedStringsFilePointer = fopen($sharedStringsFilePath, 'w');
|
||||
|
||||
$this->throwIfSharedStringsFilePointerIsNotAvailable();
|
||||
|
@ -33,18 +33,30 @@ class ZipHelper
|
||||
*/
|
||||
protected function addFolderToZip($zip, $folderPath)
|
||||
{
|
||||
$folderRealPath = realpath($folderPath) . DIRECTORY_SEPARATOR;
|
||||
$folderRealPath = $this->getNormalizedRealPath($folderPath) . '/';
|
||||
$itemIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folderPath, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
foreach ($itemIterator as $itemInfo) {
|
||||
$itemRealPath = realpath($itemInfo->getPathname());
|
||||
$itemRealPath = $this->getNormalizedRealPath($itemInfo->getPathname());
|
||||
$itemLocalPath = str_replace($folderRealPath, '', $itemRealPath);
|
||||
|
||||
if ($itemInfo->isFile()) {
|
||||
$zip->addFile($itemInfo->getPathname(), $itemLocalPath);
|
||||
$zip->addFile($itemRealPath, $itemLocalPath);
|
||||
} else if ($itemInfo->isDir()) {
|
||||
$zip->addEmptyDir($itemLocalPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns canonicalized absolute pathname, containing only forward slashes.
|
||||
*
|
||||
* @param string $path Path to normalize
|
||||
* @return string Normalized and canonicalized path
|
||||
*/
|
||||
protected function getNormalizedRealPath($path)
|
||||
{
|
||||
$realPath = realpath($path);
|
||||
return str_replace(DIRECTORY_SEPARATOR, '/', $realPath);
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ EOD;
|
||||
|
||||
$this->stringsEscaper = new \Box\Spout\Common\Escaper\XLSX();
|
||||
|
||||
$this->worksheetFilePath = $worksheetFilesFolder . DIRECTORY_SEPARATOR . strtolower($this->externalSheet->getName()) . '.xml';
|
||||
$this->worksheetFilePath = $worksheetFilesFolder . '/' . strtolower($this->externalSheet->getName()) . '.xml';
|
||||
$this->startSheet();
|
||||
}
|
||||
|
||||
|
@ -90,18 +90,9 @@ class SheetTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
private function assertSheetNameEquals($expectedName, $resourcePath, $message = '')
|
||||
{
|
||||
$pathToWorkbookFile = $resourcePath . $this->normalizePath('#xl/workbook.xml');
|
||||
$pathToWorkbookFile = $resourcePath . '#xl/workbook.xml';
|
||||
$xmlContents = file_get_contents('zip://' . $pathToWorkbookFile);
|
||||
|
||||
$this->assertContains('<sheet name="' . $expectedName . '"', $xmlContents, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return string The path with the correct directory separators, as defined for the current platform
|
||||
*/
|
||||
private function normalizePath($path)
|
||||
{
|
||||
return str_replace('/', DIRECTORY_SEPARATOR, $path);
|
||||
}
|
||||
}
|
||||
|
@ -408,7 +408,7 @@ class XLSXTest extends \PHPUnit_Framework_TestCase
|
||||
private function assertInlineDataWasWrittenToSheet($fileName, $sheetIndex, $inlineData, $message = '')
|
||||
{
|
||||
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
||||
$pathToSheetFile = $resourcePath . $this->normalizePath('#xl/worksheets/sheet' . $sheetIndex . '.xml');
|
||||
$pathToSheetFile = $resourcePath . '#xl/worksheets/sheet' . $sheetIndex . '.xml';
|
||||
$xmlContents = file_get_contents('zip://' . $pathToSheetFile);
|
||||
|
||||
$this->assertContains((string)$inlineData, $xmlContents, $message);
|
||||
@ -424,7 +424,7 @@ class XLSXTest extends \PHPUnit_Framework_TestCase
|
||||
private function assertInlineDataWasNotWrittenToSheet($fileName, $sheetIndex, $inlineData, $message = '')
|
||||
{
|
||||
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
||||
$pathToSheetFile = $resourcePath . $this->normalizePath('#xl/worksheets/sheet' . $sheetIndex . '.xml');
|
||||
$pathToSheetFile = $resourcePath . '#xl/worksheets/sheet' . $sheetIndex . '.xml';
|
||||
$xmlContents = file_get_contents('zip://' . $pathToSheetFile);
|
||||
|
||||
$this->assertNotContains((string)$inlineData, $xmlContents, $message);
|
||||
@ -439,18 +439,9 @@ class XLSXTest extends \PHPUnit_Framework_TestCase
|
||||
private function assertSharedStringWasWritten($fileName, $sharedString, $message = '')
|
||||
{
|
||||
$resourcePath = $this->getGeneratedResourcePath($fileName);
|
||||
$pathToSharedStringsFile = $resourcePath . $this->normalizePath('#xl/sharedStrings.xml');
|
||||
$pathToSharedStringsFile = $resourcePath . '#xl/sharedStrings.xml';
|
||||
$xmlContents = file_get_contents('zip://' . $pathToSharedStringsFile);
|
||||
|
||||
$this->assertContains($sharedString, $xmlContents, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @return string The path with the correct directory separators, as defined for the current platform
|
||||
*/
|
||||
private function normalizePath($path)
|
||||
{
|
||||
return str_replace('/', DIRECTORY_SEPARATOR, $path);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user