Framework for cell meta-data, implemented hyperlink support on it (for core formats - XLSX, HTM)
This commit is contained in:
parent
86d78dbc09
commit
b864f42a61
@ -38,13 +38,14 @@ abstract class AbstractWriter implements WriterInterface
|
||||
abstract protected function openWriter();
|
||||
|
||||
/**
|
||||
* Adds data to the currently openned writer.
|
||||
* Adds data to the currently opened writer.
|
||||
*
|
||||
* @param array $dataRow Array containing data to be streamed.
|
||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
||||
* @param array $metaData Array containing meta-data maps for individual cells, such as 'url'
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function addRowToWriter(array $dataRow);
|
||||
abstract protected function addRowToWriter(array $dataRow, array $metaData);
|
||||
|
||||
/**
|
||||
* Closes the streamer, preventing any additional writing.
|
||||
@ -138,15 +139,16 @@ abstract class AbstractWriter implements WriterInterface
|
||||
*
|
||||
* @param array $dataRow Array containing data to be streamed.
|
||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
||||
* @param array $metaData Array containing meta-data maps for individual cells, such as 'url'
|
||||
*
|
||||
* @return \Box\Spout\Writer\AbstractWriter
|
||||
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If this function is called before opening the writer
|
||||
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
|
||||
*/
|
||||
public function addRow(array $dataRow)
|
||||
public function addRow(array $dataRow, array $metaData = array())
|
||||
{
|
||||
if ($this->isWriterOpened) {
|
||||
$this->addRowToWriter($dataRow);
|
||||
$this->addRowToWriter($dataRow, $metaData);
|
||||
} else {
|
||||
throw new WriterNotOpenedException('The writer needs to be opened before adding row.');
|
||||
}
|
||||
|
@ -68,10 +68,11 @@ class CSV extends AbstractWriter
|
||||
*
|
||||
* @param array $dataRow Array containing data to be written.
|
||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
||||
* @param array $metaData Array containing meta-data maps for individual cells, such as 'url'
|
||||
* @return void
|
||||
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
|
||||
*/
|
||||
protected function addRowToWriter(array $dataRow)
|
||||
protected function addRowToWriter(array $dataRow, array $metaData)
|
||||
{
|
||||
$wasWriteSuccessful = fputcsv($this->filePointer, $dataRow, $this->fieldDelimiter, $this->fieldEnclosure);
|
||||
if ($wasWriteSuccessful === false) {
|
||||
|
@ -41,10 +41,11 @@ class HTM extends AbstractWriter
|
||||
*
|
||||
* @param array $dataRow Array containing data to be written.
|
||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
||||
* @param array $metaData Array containing meta-data maps for individual cells, such as 'url'
|
||||
* @return void
|
||||
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
|
||||
*/
|
||||
protected function addRowToWriter(array $dataRow)
|
||||
protected function addRowToWriter(array $dataRow, array $metaData)
|
||||
{
|
||||
$wasWriteSuccessful = true;
|
||||
if ($this->lastWrittenRowIndex == 0) {
|
||||
@ -54,9 +55,14 @@ class HTM extends AbstractWriter
|
||||
$wasWriteSuccessful = $wasWriteSuccessful && fwrite($this->filePointer, "<tbody>\n");
|
||||
}
|
||||
$wasWriteSuccessful = $wasWriteSuccessful && fwrite($this->filePointer, "<tr>\n");
|
||||
foreach ($dataRow as $cell) {
|
||||
foreach ($dataRow as $i => $cell) {
|
||||
$cell = nl2br(htmlentities($cell));
|
||||
|
||||
if (isset($metaData[$i]['url']))
|
||||
{
|
||||
$cell = '<a href="' . htmlentities($metaData[$i]['url']) . '">' . $cell . '</a>';
|
||||
}
|
||||
|
||||
if ($this->lastWrittenRowIndex == 0) {
|
||||
$wasWriteSuccessful = $wasWriteSuccessful && fwrite($this->filePointer, "\t<th>{$cell}</th>\n");
|
||||
} else
|
||||
|
@ -208,6 +208,7 @@ EOD;
|
||||
$this->xlFolder = $this->createFolder($this->rootFolder, self::XL_FOLDER_NAME);
|
||||
$this->createXlRelsFolder();
|
||||
$this->createXlWorksheetsFolder();
|
||||
$this->createXlWorksheetsRelsFolder();
|
||||
|
||||
return $this;
|
||||
}
|
||||
@ -236,6 +237,18 @@ EOD;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the "_rels" folder under the "worksheets" folder
|
||||
*
|
||||
* @return FileSystemHelper
|
||||
* @throws \Box\Spout\Common\Exception\IOException If unable to create the folder
|
||||
*/
|
||||
protected function createXlWorksheetsRelsFolder()
|
||||
{
|
||||
$this->createFolder($this->xlWorksheetsFolder, self::RELS_FOLDER_NAME);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the "styles.xml" file under the "xl" folder
|
||||
*
|
||||
|
@ -165,11 +165,12 @@ class Workbook
|
||||
*
|
||||
* @param array $dataRow Array containing data to be written.
|
||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
||||
* @param array $metaData Array containing meta-data maps for individual cells, such as 'url'
|
||||
* @return void
|
||||
* @throws \Box\Spout\Common\Exception\IOException If trying to create a new sheet and unable to open the sheet for writing
|
||||
* @throws \Box\Spout\Writer\Exception\WriterException If unable to write data
|
||||
*/
|
||||
public function addRowToCurrentWorksheet($dataRow)
|
||||
public function addRowToCurrentWorksheet($dataRow, $metaData)
|
||||
{
|
||||
$currentWorksheet = $this->getCurrentWorksheet();
|
||||
$hasReachedMaxRows = $this->hasCurrentWorkseetReachedMaxRows();
|
||||
@ -179,12 +180,12 @@ class Workbook
|
||||
// ... continue writing in a new sheet if option set
|
||||
if ($this->shouldCreateNewSheetsAutomatically) {
|
||||
$currentWorksheet = $this->addNewSheetAndMakeItCurrent();
|
||||
$currentWorksheet->addRow($dataRow);
|
||||
$currentWorksheet->addRow($dataRow, $metaData);
|
||||
} else {
|
||||
// otherwise, do nothing as the data won't be read anyways
|
||||
}
|
||||
} else {
|
||||
$currentWorksheet->addRow($dataRow);
|
||||
$currentWorksheet->addRow($dataRow, $metaData);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,9 @@ EOD;
|
||||
/** @var string Path to the XML file that will contain the sheet data */
|
||||
protected $worksheetFilePath;
|
||||
|
||||
/** @var string Path to the XML file that will contain the sheet rels data */
|
||||
protected $worksheetRelsFilePath;
|
||||
|
||||
/** @var \Box\Spout\Writer\Helper\XLSX\SharedStringsHelper Helper to write shared strings */
|
||||
protected $sharedStringsHelper;
|
||||
|
||||
@ -40,6 +43,9 @@ EOD;
|
||||
/** @var int */
|
||||
protected $lastWrittenRowIndex = 0;
|
||||
|
||||
/** @var array */
|
||||
protected $urls = array();
|
||||
|
||||
/**
|
||||
* @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
|
||||
@ -55,6 +61,7 @@ EOD;
|
||||
$this->stringsEscaper = new \Box\Spout\Common\Escaper\XLSX();
|
||||
|
||||
$this->worksheetFilePath = $worksheetFilesFolder . DIRECTORY_SEPARATOR . strtolower($this->externalSheet->getName()) . '.xml';
|
||||
$this->worksheetRelsFilePath = $worksheetFilesFolder . DIRECTORY_SEPARATOR . '_rels' . DIRECTORY_SEPARATOR . strtolower($this->externalSheet->getName()) . '.xml.rels';
|
||||
$this->startSheet();
|
||||
}
|
||||
|
||||
@ -116,10 +123,11 @@ EOD;
|
||||
*
|
||||
* @param array $dataRow Array containing data to be written.
|
||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
||||
* @param array $metaData Array containing meta-data maps for individual cells, such as 'url'
|
||||
* @return void
|
||||
* @throws \Box\Spout\Common\Exception\IOException If the data cannot be written
|
||||
*/
|
||||
public function addRow($dataRow)
|
||||
public function addRow($dataRow, array $metaData = array())
|
||||
{
|
||||
if (count($dataRow) == 0) {
|
||||
// Without this fix, we get a repair issue in regular Microsoft Excel
|
||||
@ -134,7 +142,9 @@ EOD;
|
||||
|
||||
foreach($dataRow as $cellValue) {
|
||||
$columnIndex = CellHelper::getCellIndexFromColumnIndex($cellNumber);
|
||||
$data .= ' <c' . (($rowIndex == 1) ? ' s="1"' : '') . ' r="' . $columnIndex . $rowIndex . '"';
|
||||
$cellPath = $columnIndex . $rowIndex;
|
||||
|
||||
$data .= ' <c' . (($rowIndex == 1) ? ' s="1"' : '') . ' r="' . $cellPath . '"';
|
||||
|
||||
if (empty($cellValue)) {
|
||||
$data .= '/>' . PHP_EOL;
|
||||
@ -151,6 +161,10 @@ EOD;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($metaData[$cellNumber]['url'])) {
|
||||
$this->urls[$cellPath] = $metaData[$cellNumber]['url'];
|
||||
}
|
||||
|
||||
$cellNumber++;
|
||||
}
|
||||
|
||||
@ -173,6 +187,34 @@ EOD;
|
||||
public function close()
|
||||
{
|
||||
fwrite($this->sheetFilePointer, ' </sheetData>' . PHP_EOL);
|
||||
|
||||
// Write out any hyperlinks
|
||||
if (count($this->urls) != 0) {
|
||||
fwrite($this->sheetFilePointer, ' <hyperlinks>' . PHP_EOL);
|
||||
$i = 0;
|
||||
foreach ($this->urls as $cellPath => $url) {
|
||||
$refID = 'rId' . ($i + 1);
|
||||
fwrite($this->sheetFilePointer, ' <hyperlink ref="' . $cellPath . '" r:id="' . $refID . '"/>' . PHP_EOL);
|
||||
$i++;
|
||||
}
|
||||
fwrite($this->sheetFilePointer, ' </hyperlinks>' . PHP_EOL);
|
||||
}
|
||||
|
||||
// Write rels file
|
||||
$sheetRelsFilePointer = fopen($this->worksheetRelsFilePath, 'w');
|
||||
if (!$sheetRelsFilePointer) throw new IOException('Unable to open rels sheet for writing.');
|
||||
fwrite($sheetRelsFilePointer, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' . PHP_EOL);
|
||||
fwrite($sheetRelsFilePointer, '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">' . PHP_EOL);
|
||||
$i = 0;
|
||||
foreach ($this->urls as $url) {
|
||||
$refID = 'rId' . ($i + 1);
|
||||
fwrite($sheetRelsFilePointer, '<Relationship Id="' . $refID . '" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="' . htmlentities($url) . '" TargetMode="External"/>' . PHP_EOL);
|
||||
$i++;
|
||||
}
|
||||
fwrite($sheetRelsFilePointer, '</Relationships>');
|
||||
fclose($sheetRelsFilePointer);
|
||||
|
||||
// Finish file
|
||||
fwrite($this->sheetFilePointer, '</worksheet>');
|
||||
fclose($this->sheetFilePointer);
|
||||
}
|
||||
|
@ -34,11 +34,12 @@ interface WriterInterface
|
||||
*
|
||||
* @param array $dataRow Array containing data to be streamed.
|
||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
||||
* @param array $metaData Array containing meta-data maps for individual cells, such as 'url'
|
||||
* @return \Box\Spout\Writer\WriterInterface
|
||||
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If the writer has not been opened yetthe writer
|
||||
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
|
||||
*/
|
||||
public function addRow(array $dataRow);
|
||||
public function addRow(array $dataRow, array $metaData = array());
|
||||
|
||||
/**
|
||||
* Write given data to the output. New data will be appended to end of stream.
|
||||
|
@ -129,10 +129,11 @@ class XLS extends AbstractWriter
|
||||
*
|
||||
* @param array $dataRow Array containing data to be written.
|
||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
||||
* @param array $metaData Array containing meta-data maps for individual cells, such as 'url'
|
||||
* @return void
|
||||
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
|
||||
*/
|
||||
protected function addRowToWriter(array $dataRow)
|
||||
protected function addRowToWriter(array $dataRow, array $metaData)
|
||||
{
|
||||
if ($this->row == 65536) {
|
||||
// Hit the limit. You should have chosen XLSX
|
||||
|
@ -160,14 +160,15 @@ class XLSX extends AbstractWriter
|
||||
*
|
||||
* @param array $dataRow Array containing data to be written.
|
||||
* Example $dataRow = ['data1', 1234, null, '', 'data5'];
|
||||
* @param array $metaData Array containing meta-data maps for individual cells, such as 'url'
|
||||
* @return void
|
||||
* @throws \Box\Spout\Writer\Exception\WriterNotOpenedException If the book is not created yet
|
||||
* @throws \Box\Spout\Common\Exception\IOException If unable to write data
|
||||
*/
|
||||
protected function addRowToWriter(array $dataRow)
|
||||
protected function addRowToWriter(array $dataRow, array $metaData)
|
||||
{
|
||||
$this->throwIfBookIsNotAvailable();
|
||||
$this->book->addRowToCurrentWorksheet($dataRow);
|
||||
$this->book->addRowToCurrentWorksheet($dataRow, $metaData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user