Skip to content

Commit

Permalink
Fixed/changed how zip/xlsx is written to specified output. Moved cols…
Browse files Browse the repository at this point in the history
… xml generation to sheet class. (#31)
  • Loading branch information
nimmneun committed Sep 10, 2016
1 parent d02a95b commit 6a4ba0d
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 39 deletions.
65 changes: 39 additions & 26 deletions src/OneSheet/Finalizer.php
Expand Up @@ -51,20 +51,31 @@ public function __construct(Sheet $sheet, Styler $styler, SheetFile $sheetFile)
/**
* Finalize the xlsx file.
*
* @param string $fileName
* @throws \RuntimeException
* @param resource $output
*/
public function finalize($fileName)
public function finalize($output)
{
$this->zip->open($fileName, \ZipArchive::CREATE);
$zipFileUrl = sys_get_temp_dir() . '/' . uniqid();

$this->fillZipWithFileContents($zipFileUrl);
if (!$this->zip->close()) {
throw new \RuntimeException('Failed to close zip file!');
}

$this->copyToOutputAndCleanup($output, $zipFileUrl);
}

/**
* Add all file and string contents to zip file.
*
* @param string $zipFileUrl
*/
private function fillZipWithFileContents($zipFileUrl)
{
$this->zip->open($zipFileUrl, \ZipArchive::CREATE);
$this->finalizeSheet();
$this->finalizeStyles();
$this->finalizeDefaultXmls();

if (!$this->zip->close()) {
throw new \RuntimeException('Failed to save xlsx file!');
}
}

/**
Expand All @@ -77,27 +88,10 @@ private function finalizeSheet()
$this->sheetFile->fwrite(SheetXml::HEADER_XML);
$this->sheetFile->fwrite($this->sheet->getDimensionXml());
$this->sheetFile->fwrite($this->sheet->getSheetViewsXml());
$this->writeColumnWidths();
$this->sheetFile->fwrite($this->sheet->getColsXml());
$this->zip->addFile($this->sheetFile->getFilePath(), 'xl/worksheets/sheet1.xml');
}

/**
* Write column widths xml string.
*/
private function writeColumnWidths()
{
if (0 < count($this->sheet->getColumnWidths())) {
$this->sheetFile->fwrite('<cols>');
foreach ($this->sheet->getColumnWidths() as $columnNumber => $columnWidth) {
$this->sheetFile->fwrite(
sprintf(SheetXml::COLUMN_XML, ($columnNumber + 1), ($columnNumber + 1),
$columnWidth)
);
}
$this->sheetFile->fwrite('</cols>');
}
}

/**
* Write style xml file.
*/
Expand All @@ -119,4 +113,23 @@ private function finalizeDefaultXmls()
$this->zip->addFromString('xl/_rels/workbook.xml.rels', DefaultXml::XL_RELS_WORKBOOK);
$this->zip->addFromString('xl/workbook.xml', DefaultXml::XL_WORKBOOK);
}

/**
* Write zip/xlsx contents to specified output
* and unlink/delete files.
*
* @param resource $output
* @param string $zipFileUrl
*/
private function copyToOutputAndCleanup($output, $zipFileUrl)
{
$zipFilePointer = fopen($zipFileUrl, 'r');
if (!stream_copy_to_stream($zipFilePointer, $output)
|| !fclose($zipFilePointer)
|| !fclose($output)
|| !unlink($zipFileUrl)
) {
throw new \RuntimeException("Failed to copy stream and clean up!");
}
}
}
26 changes: 23 additions & 3 deletions src/OneSheet/Sheet.php
Expand Up @@ -243,7 +243,7 @@ private function updateColumnWidths($value, $cellIndex, Style $style)
}

/**
* Return xml string for dimension.
* Return <dimension> xml string.
*
* @return string
*/
Expand All @@ -255,8 +255,7 @@ public function getDimensionXml()
}

/**
* Return sheetViews xml containing the freeze pane.
* <sheetViews> Currently leads to random excel crashes :-/
* Return <sheetViews> xml containing the freeze pane.
*
* @return string
*/
Expand All @@ -268,4 +267,25 @@ public function getSheetViewsXml()

return sprintf(SheetXml::SHEETVIEWS_XML, array_pop($m) - 1, $this->freezePaneCellId);
}

/**
* Return <cols> xml for column widths or an empty string,
* if there are no column widths.
*
* @return string
*/
public function getColsXml()
{
$colsXml = '';

if (0 !== count($this->getColumnWidths())) {
foreach ($this->getColumnWidths() as $columnIndex => $columnWidth) {
$columnNumber = $columnIndex + 1;
$colsXml .= sprintf(SheetXml::COLUMN_XML, $columnNumber, $columnNumber, $columnWidth);
}
$colsXml = sprintf('<cols>%s</cols>', $colsXml);
}

return $colsXml;
}
}
23 changes: 13 additions & 10 deletions src/OneSheet/Writer.php
Expand Up @@ -29,6 +29,11 @@ class Writer
*/
private $sheet;

/**
* @var
*/
private $output;

/**
* Writer constructor.
*/
Expand Down Expand Up @@ -135,16 +140,16 @@ public function addRow(array $row, Style $style = null)
}

/**
* Send xlsx to browser and unlink file.
* Wrap things up and send xlsx to browser.
*
* @param string $fileName
*/
public function writeToBrowser($fileName = 'report.xlsx')
{
$this->writeToFile($fileName);
if (is_readable($fileName)) {
$this->sendToBrowserAndUnlink($fileName);
}
$this->output = fopen('php://output', 'w');
$finalizer = new Finalizer($this->sheet, $this->styler, $this->sheetFile);
$this->sendHeaders($fileName);
$finalizer->finalize($this->output);
}

/**
Expand All @@ -154,23 +159,21 @@ public function writeToBrowser($fileName = 'report.xlsx')
*/
public function writeToFile($fileName = 'report.xlsx')
{
$this->output = fopen($fileName, 'w');
$finalizer = new Finalizer($this->sheet, $this->styler, $this->sheetFile);
$finalizer->finalize($fileName);
$finalizer->finalize($this->output);
}

/**
* Output headers & content and unlink the xlsx file eventually.
*
* @param string $fileName
*/
private function sendToBrowserAndUnlink($fileName)
private function sendHeaders($fileName)
{
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment; filename="' . $fileName . '"');
header('Content-Length: ' . filesize($fileName));
header('Cache-Control: max-age=0');
header('Pragma: public');
echo readfile($fileName);
unlink($fileName);
}
}

0 comments on commit 6a4ba0d

Please sign in to comment.