Merge pull request #59 from box/fix_xlsx_writer_on_windows

Fix XLSX Writer on Windows plaftorms
This commit is contained in:
Adrien Loison 2015-07-01 15:29:10 -07:00
commit 503ba97e9d
9 changed files with 29 additions and 38 deletions

View File

@ -36,7 +36,7 @@ class FileSystemHelper
{ {
$this->throwIfOperationNotInBaseFolder($parentFolderPath); $this->throwIfOperationNotInBaseFolder($parentFolderPath);
$folderPath = $parentFolderPath . DIRECTORY_SEPARATOR . $folderName; $folderPath = $parentFolderPath . '/' . $folderName;
$wasCreationSuccessful = mkdir($folderPath, 0777, true); $wasCreationSuccessful = mkdir($folderPath, 0777, true);
if (!$wasCreationSuccessful) { if (!$wasCreationSuccessful) {
@ -60,7 +60,7 @@ class FileSystemHelper
{ {
$this->throwIfOperationNotInBaseFolder($parentFolderPath); $this->throwIfOperationNotInBaseFolder($parentFolderPath);
$filePath = $parentFolderPath . DIRECTORY_SEPARATOR . $fileName; $filePath = $parentFolderPath . '/' . $fileName;
$wasCreationSuccessful = file_put_contents($filePath, $fileContents); $wasCreationSuccessful = file_put_contents($filePath, $fileContents);
if (!$wasCreationSuccessful) { if (!$wasCreationSuccessful) {

View File

@ -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() protected function getSharedStringsFilePath()
{ {
$sharedStringsXmlFilePath = str_replace('/', DIRECTORY_SEPARATOR, self::SHARED_STRINGS_XML_FILE_PATH); return 'zip://' . $this->filePath . '#' . self::SHARED_STRINGS_XML_FILE_PATH;
return 'zip://' . $this->filePath . '#' . $sharedStringsXmlFilePath;
} }
/** /**
@ -250,7 +249,7 @@ class SharedStringsHelper
protected function getSharedStringTempFilePath($sharedStringIndex) protected function getSharedStringTempFilePath($sharedStringIndex)
{ {
$numTempFile = intval($sharedStringIndex / self::MAX_NUM_STRINGS_PER_TEMP_FILE); $numTempFile = intval($sharedStringIndex / self::MAX_NUM_STRINGS_PER_TEMP_FILE);
return $this->tempFolder . DIRECTORY_SEPARATOR . 'sharedstrings' . $numTempFile; return $this->tempFolder . '/sharedstrings' . $numTempFile;
} }
/** /**

View File

@ -186,8 +186,7 @@ class WorksheetHelper
*/ */
protected function getFileAsXMLElementWithNamespace($xmlFilePath, $mainNamespace) protected function getFileAsXMLElementWithNamespace($xmlFilePath, $mainNamespace)
{ {
$normalizedXmlFilePath = str_replace('/', DIRECTORY_SEPARATOR, $xmlFilePath); $xmlContents = $this->globalFunctionsHelper->file_get_contents('zip://' . $this->filePath . '#' . $xmlFilePath);
$xmlContents = $this->globalFunctionsHelper->file_get_contents('zip://' . $this->filePath . '#' . $normalizedXmlFilePath);
$xmlElement = new \SimpleXMLElement($xmlContents); $xmlElement = new \SimpleXMLElement($xmlContents);
$xmlElement->registerXPathNamespace('ns', $mainNamespace); $xmlElement->registerXPathNamespace('ns', $mainNamespace);

View File

@ -33,12 +33,11 @@ class Worksheet
/** /**
* @return string Path of the XML file containing the worksheet data, * @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() public function getDataXmlFilePath()
{ {
$dataXmlFilePath = ltrim($this->dataXmlFilePath, '/'); return ltrim($this->dataXmlFilePath, '/');
return str_replace('/', DIRECTORY_SEPARATOR, $dataXmlFilePath);
} }
/** /**

View File

@ -36,7 +36,7 @@ EOD;
*/ */
public function __construct($xlFolder) 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->sharedStringsFilePointer = fopen($sharedStringsFilePath, 'w');
$this->throwIfSharedStringsFilePointerIsNotAvailable(); $this->throwIfSharedStringsFilePointerIsNotAvailable();

View File

@ -33,18 +33,30 @@ class ZipHelper
*/ */
protected function addFolderToZip($zip, $folderPath) 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); $itemIterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folderPath, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
foreach ($itemIterator as $itemInfo) { foreach ($itemIterator as $itemInfo) {
$itemRealPath = realpath($itemInfo->getPathname()); $itemRealPath = $this->getNormalizedRealPath($itemInfo->getPathname());
$itemLocalPath = str_replace($folderRealPath, '', $itemRealPath); $itemLocalPath = str_replace($folderRealPath, '', $itemRealPath);
if ($itemInfo->isFile()) { if ($itemInfo->isFile()) {
$zip->addFile($itemInfo->getPathname(), $itemLocalPath); $zip->addFile($itemRealPath, $itemLocalPath);
} else if ($itemInfo->isDir()) { } else if ($itemInfo->isDir()) {
$zip->addEmptyDir($itemLocalPath); $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);
}
} }

View File

@ -56,7 +56,7 @@ EOD;
$this->stringsEscaper = new \Box\Spout\Common\Escaper\XLSX(); $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(); $this->startSheet();
} }

View File

@ -90,18 +90,9 @@ class SheetTest extends \PHPUnit_Framework_TestCase
*/ */
private function assertSheetNameEquals($expectedName, $resourcePath, $message = '') private function assertSheetNameEquals($expectedName, $resourcePath, $message = '')
{ {
$pathToWorkbookFile = $resourcePath . $this->normalizePath('#xl/workbook.xml'); $pathToWorkbookFile = $resourcePath . '#xl/workbook.xml';
$xmlContents = file_get_contents('zip://' . $pathToWorkbookFile); $xmlContents = file_get_contents('zip://' . $pathToWorkbookFile);
$this->assertContains('<sheet name="' . $expectedName . '"', $xmlContents, $message); $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);
}
} }

View File

@ -408,7 +408,7 @@ class XLSXTest extends \PHPUnit_Framework_TestCase
private function assertInlineDataWasWrittenToSheet($fileName, $sheetIndex, $inlineData, $message = '') private function assertInlineDataWasWrittenToSheet($fileName, $sheetIndex, $inlineData, $message = '')
{ {
$resourcePath = $this->getGeneratedResourcePath($fileName); $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); $xmlContents = file_get_contents('zip://' . $pathToSheetFile);
$this->assertContains((string)$inlineData, $xmlContents, $message); $this->assertContains((string)$inlineData, $xmlContents, $message);
@ -424,7 +424,7 @@ class XLSXTest extends \PHPUnit_Framework_TestCase
private function assertInlineDataWasNotWrittenToSheet($fileName, $sheetIndex, $inlineData, $message = '') private function assertInlineDataWasNotWrittenToSheet($fileName, $sheetIndex, $inlineData, $message = '')
{ {
$resourcePath = $this->getGeneratedResourcePath($fileName); $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); $xmlContents = file_get_contents('zip://' . $pathToSheetFile);
$this->assertNotContains((string)$inlineData, $xmlContents, $message); $this->assertNotContains((string)$inlineData, $xmlContents, $message);
@ -439,18 +439,9 @@ class XLSXTest extends \PHPUnit_Framework_TestCase
private function assertSharedStringWasWritten($fileName, $sharedString, $message = '') private function assertSharedStringWasWritten($fileName, $sharedString, $message = '')
{ {
$resourcePath = $this->getGeneratedResourcePath($fileName); $resourcePath = $this->getGeneratedResourcePath($fileName);
$pathToSharedStringsFile = $resourcePath . $this->normalizePath('#xl/sharedStrings.xml'); $pathToSharedStringsFile = $resourcePath . '#xl/sharedStrings.xml';
$xmlContents = file_get_contents('zip://' . $pathToSharedStringsFile); $xmlContents = file_get_contents('zip://' . $pathToSharedStringsFile);
$this->assertContains($sharedString, $xmlContents, $message); $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);
}
} }