Add the ability to add columns width (#1)

This commit is contained in:
Eliurkis Diaz 2019-05-14 14:57:22 -04:00 committed by GitHub
parent a420e3fffa
commit 298819c01d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 147 additions and 38 deletions

View File

@ -1,14 +1,34 @@
{
"name": "box/spout",
"name": "smart145/spout",
"description": "PHP Library to read and write spreadsheet files (CSV, XLSX and ODS), in a fast and scalable way",
"type": "library",
"keywords": ["php","read","write","csv","xlsx","ods","odf","open","office","excel","spreadsheet","scale","memory","stream","ooxml"],
"keywords": [
"php",
"read",
"write",
"csv",
"xlsx",
"ods",
"odf",
"open",
"office",
"excel",
"spreadsheet",
"scale",
"memory",
"stream",
"ooxml"
],
"license": "Apache-2.0",
"homepage": "https://www.github.com/box/spout",
"homepage": "https://www.github.com/smart145/spout",
"authors": [
{
"name": "Adrien Loison",
"email": "adrien@box.com"
},
{
"name": "Dariel Ramos",
"email": "vdariel90@gmail.com"
}
],
"require": {
@ -38,5 +58,4 @@
"php": "5.4.0"
}
}
}

View File

@ -26,13 +26,13 @@ class ODS implements EscaperInterface
// 'ENT_DISALLOWED' ensures that invalid characters in the given document type are replaced.
// Otherwise control characters like a vertical tab "\v" will make the XML document unreadable by the XML processor
// @link https://github.com/box/spout/issues/329
$replacedString = htmlspecialchars($string, ENT_NOQUOTES | ENT_DISALLOWED, 'UTF-8');
$replacedString = htmlspecialchars($string, ENT_NOQUOTES | ENT_DISALLOWED);
} else {
// We are on hhvm or any other engine that does not support ENT_DISALLOWED.
//
// @NOTE: Using ENT_NOQUOTES as only XML entities ('<', '>', '&') need to be encoded.
// Single and double quotes can be left as is.
$escapedString = htmlspecialchars($string, ENT_NOQUOTES, 'UTF-8');
$escapedString = htmlspecialchars($string, ENT_NOQUOTES);
// control characters values are from 0 to 1F (hex values) in the ASCII table
// some characters should not be escaped though: "\t", "\r" and "\n".

View File

@ -44,7 +44,7 @@ class XLSX implements EscaperInterface
$escapedString = $this->escapeControlCharacters($string);
// @NOTE: Using ENT_NOQUOTES as only XML entities ('<', '>', '&') need to be encoded.
// Single and double quotes can be left as is.
$escapedString = htmlspecialchars($escapedString, ENT_NOQUOTES, 'UTF-8');
$escapedString = htmlspecialchars($escapedString, ENT_NOQUOTES);
return $escapedString;
}

View File

@ -3,10 +3,10 @@
namespace Box\Spout\Writer\XLSX\Internal;
use Box\Spout\Writer\Common\Internal\AbstractWorkbook;
use Box\Spout\Writer\Common\Sheet;
use Box\Spout\Writer\XLSX\Helper\FileSystemHelper;
use Box\Spout\Writer\XLSX\Helper\SharedStringsHelper;
use Box\Spout\Writer\XLSX\Helper\StyleHelper;
use Box\Spout\Writer\Common\Sheet;
/**
* Class Workbook
@ -35,6 +35,9 @@ class Workbook extends AbstractWorkbook
/** @var \Box\Spout\Writer\XLSX\Helper\StyleHelper Helper to apply styles */
protected $styleHelper;
/** @var array contain column width information */
protected $columnwidths = [];
/**
* @param string $tempFolder
* @param bool $shouldUseInlineStrings
@ -42,8 +45,13 @@ class Workbook extends AbstractWorkbook
* @param \Box\Spout\Writer\Style\Style $defaultRowStyle
* @throws \Box\Spout\Common\Exception\IOException If unable to create at least one of the base folders
*/
public function __construct($tempFolder, $shouldUseInlineStrings, $shouldCreateNewSheetsAutomatically, $defaultRowStyle)
{
public function __construct(
$tempFolder,
$shouldUseInlineStrings,
$shouldCreateNewSheetsAutomatically,
$defaultRowStyle,
$columnwidths
) {
parent::__construct($shouldCreateNewSheetsAutomatically, $defaultRowStyle);
$this->shouldUseInlineStrings = $shouldUseInlineStrings;
@ -56,6 +64,7 @@ class Workbook extends AbstractWorkbook
// This helper will be shared by all sheets
$xlFolder = $this->fileSystemHelper->getXlFolder();
$this->sharedStringsHelper = new SharedStringsHelper($xlFolder);
$this->columnwidths = $columnwidths;
}
/**
@ -86,12 +95,24 @@ class Workbook extends AbstractWorkbook
$sheet = new Sheet($newSheetIndex, $this->internalId);
$worksheetFilesFolder = $this->fileSystemHelper->getXlWorksheetsFolder();
$worksheet = new Worksheet($sheet, $worksheetFilesFolder, $this->sharedStringsHelper, $this->styleHelper, $this->shouldUseInlineStrings);
$worksheet = new Worksheet($sheet, $worksheetFilesFolder, $this->sharedStringsHelper, $this->styleHelper,
$this->shouldUseInlineStrings, $this->columnwidths);
$this->worksheets[] = $worksheet;
return $worksheet;
}
/**
* Set column width for sheet that will be created
* should only be called from the writer
*
* @param array $columnwidths
*/
public function _setColumnWidth($columnwidths)
{
$this->columnwidths = $columnwidths;
}
/**
* Closes the workbook and all its associated sheets.
* All the necessary files are written to disk and zipped together to create the XLSX file.

View File

@ -65,8 +65,14 @@ EOD;
* @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
*/
public function __construct($externalSheet, $worksheetFilesFolder, $sharedStringsHelper, $styleHelper, $shouldUseInlineStrings)
{
public function __construct(
$externalSheet,
$worksheetFilesFolder,
$sharedStringsHelper,
$styleHelper,
$shouldUseInlineStrings,
$columnwidths
) {
$this->externalSheet = $externalSheet;
$this->sharedStringsHelper = $sharedStringsHelper;
$this->styleHelper = $styleHelper;
@ -77,7 +83,7 @@ EOD;
$this->stringHelper = new StringHelper();
$this->worksheetFilePath = $worksheetFilesFolder.'/'.strtolower($this->externalSheet->getName()).'.xml';
$this->startSheet();
$this->startSheet($columnwidths);
}
/**
@ -86,12 +92,24 @@ EOD;
* @return void
* @throws \Box\Spout\Common\Exception\IOException If the sheet data file cannot be opened for writing
*/
protected function startSheet()
protected function startSheet($columnwidths = null)
{
$this->sheetFilePointer = fopen($this->worksheetFilePath, 'w');
$this->throwIfSheetFilePointerIsNotAvailable();
fwrite($this->sheetFilePointer, self::SHEET_XML_FILE_HEADER);
if (!empty($columnwidths)) {
foreach ($columnwidths as $c) {
fwrite($this->sheetFilePointer,
'<cols><col min="'.$c['min'].
'" max="'.$c['max'].
'" width="'.$c['width'].
'" customWidth="1"/></cols>'
);
}
}
fwrite($this->sheetFilePointer, '<sheetData>');
}
@ -162,6 +180,7 @@ EOD;
protected function isEmptyRow($dataRow)
{
$numCells = count($dataRow);
// using "reset()" instead of "$dataRow[0]" because $dataRow can be an associative array
return ($numCells === 1 && CellHelper::isEmpty(reset($dataRow)));
}
@ -215,11 +234,14 @@ EOD;
if (CellHelper::isNonEmptyString($cellValue)) {
$cellXML .= $this->getCellXMLFragmentForNonEmptyString($cellValue);
} else if (CellHelper::isBoolean($cellValue)) {
} else {
if (CellHelper::isBoolean($cellValue)) {
$cellXML .= ' t="b"><v>'.intval($cellValue).'</v></c>';
} else if (CellHelper::isNumeric($cellValue)) {
} else {
if (CellHelper::isNumeric($cellValue)) {
$cellXML .= '><v>'.$cellValue.'</v></c>';
} else if (empty($cellValue)) {
} else {
if (empty($cellValue)) {
if ($this->styleHelper->shouldApplyStyleOnEmptyCell($styleId)) {
$cellXML .= '/>';
} else {
@ -230,6 +252,9 @@ EOD;
} else {
throw new InvalidArgumentException('Trying to add a value with an unsupported type: '.gettype($cellValue));
}
}
}
}
return $cellXML;
}

View File

@ -30,6 +30,9 @@ class Writer extends AbstractMultiSheetsWriter
/** @var Internal\Workbook The workbook for the XLSX file */
protected $book;
/** @var array contain column width information */
protected $columnwidths = [];
/**
* Sets a custom temporary folder for creating intermediate files/folders.
* This must be set before opening the writer.
@ -44,6 +47,7 @@ class Writer extends AbstractMultiSheetsWriter
$this->throwIfWriterAlreadyOpened('Writer must be configured before opening it.');
$this->tempFolder = $tempFolder;
return $this;
}
@ -61,6 +65,45 @@ class Writer extends AbstractMultiSheetsWriter
$this->throwIfWriterAlreadyOpened('Writer must be configured before opening it.');
$this->shouldUseInlineStrings = $shouldUseInlineStrings;
return $this;
}
/**
* Clear all column width specification
* @return Writer
*/
public function clearColumnWidth()
{
$this->columnwidths = [];
if ($this->book) {
$this->book->_setColumnWidth($this->columnwidths);
}
return $this;
}
/**
* Add a width definition for the next sheet that will be generated
* @param number $width column width
* @param number $min column position ( A=1 ) where this width should take effect
* @param number $max end of range where width take effect ( default to min )
* @return Writer
*/
public function setColumnsWidth($width, $min, $max = null)
{
if ($max === null) {
$max = $min;
}
$this->columnwidths[] = [
'width' => $width,
'min' => $min,
'max' => $max,
];
if ($this->book) {
$this->book->_setColumnWidth($this->columnwidths);
}
return $this;
}
@ -74,7 +117,8 @@ class Writer extends AbstractMultiSheetsWriter
{
if (!$this->book) {
$tempFolder = ($this->tempFolder) ?: sys_get_temp_dir();
$this->book = new Workbook($tempFolder, $this->shouldUseInlineStrings, $this->shouldCreateNewSheetsAutomatically, $this->defaultRowStyle);
$this->book = new Workbook($tempFolder, $this->shouldUseInlineStrings,
$this->shouldCreateNewSheetsAutomatically, $this->defaultRowStyle, $this->columnwidths);
$this->book->addNewSheetAndMakeItCurrent();
}
}