Skip to content

Commit e28db92

Browse files
committed
Add startRow/startColumn to ExcelSheet
1 parent f61e767 commit e28db92

File tree

3 files changed

+63
-32
lines changed

3 files changed

+63
-32
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ Property | Description
7171
`formatters` (optional) | An array of value formatters for specific columns. Each must be a valid PHP callable whith the signature `function formatter($value, $row, $data)` where `$value` is the cell value to format, `$row` is the 0-based row index and `$data` is the current row data from the `data` configuration. The callbacks must be indexed either by column name (e.g. `H`) or by the 0-based column index.
7272
`styles` (optional) | An array of style configuration indexed by cell coordinates or a range.
7373
`callbacks` (optional) | An array of callbacks indexed by column that should be called after rendering a cell, e.g. to apply further complex styling. Each must be a valid PHP callable with the signature `function callback($cell, $col, $row)` where `$cell` is the current `PHPExcel_Cell` object and `$col` and `$row` are the 0-based column and row indices respectively.
74+
`startColumn` (optional) | The start column name or its 0-based index. When this is set, the 0-based offset is added to all numeric keys used anywhere in this class. Columns referenced by name will stay unchanged. Default is 'A'.
75+
`startRow` (optional) | The start row. Default is 1.
7476

7577
### ActiveExcelSheet
7678

src/ActiveExcelSheet.php

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ public function getFormats()
132132
{
133133
if ($this->_formats === null) {
134134
$this->_formats = [];
135-
$attrs = $this->getAttributes();
136-
$types = $this->getColumnTypes();
135+
$attrs = $this->normalizeIndex($this->getAttributes());
136+
$types = $this->normalizeIndex($this->getColumnTypes());
137137
foreach ($attrs as $c => $attr) {
138138
switch ($types[$c]->type) {
139139
case 'date':
@@ -182,8 +182,8 @@ public function getFormatters()
182182
{
183183
if ($this->_formatters === null) {
184184
$this->_formatters = [];
185-
$attrs = $this->getAttributes();
186-
$types = $this->getColumnTypes();
185+
$attrs = $this->normalizeIndex($this->getAttributes());
186+
$types = $this->normalizeIndex($this->getColumnTypes());
187187
foreach ($attrs as $c => $attr) {
188188
switch ($types[$c]->type) {
189189
case 'date':
@@ -251,7 +251,6 @@ protected function getColumnTypes()
251251
$this->_columnTypes = array_map(function ($attr) use ($model) {
252252
return self::getType($model, $attr);
253253
}, $this->getAttributes());
254-
255254
}
256255
return $this->_columnTypes;
257256
}
@@ -275,9 +274,9 @@ protected function renderRow($data, $row, $formats, $formatters, $callbacks, $ty
275274
* from DB to application timezone.
276275
*
277276
* @param string $value the datetime value
278-
* @return int timezone offset in seconds
279-
* @see [[yii\i18n\Formatter::defaultTimeZone]]
280-
* @see [[yii\base\Application::timeZone]]
277+
* @return int timezone offset in seconds
278+
* @see [[yii\i18n\Formatter::defaultTimezone]]
279+
* @see [[yii\i18n\Formatter::timezone]]
281280
*/
282281
protected function toExcelTime($value)
283282
{

src/ExcelSheet.php

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@
88
*/
99
class ExcelSheet extends Object
1010
{
11+
/**
12+
* @var int|string the start column name or its 0-based index. When this is
13+
* set, the 0-based offset is added to all numeric keys used anywhere in
14+
* this class. Columns referenced by name will stay unchanged. Default is
15+
* 'A'.
16+
*/
17+
public $startColumn = 'A';
18+
19+
/**
20+
* @var int the start row. Default is 1.
21+
*/
22+
public $startRow = 1;
23+
1124
protected $_sheet;
1225
protected $_data;
1326
protected $_titles;
@@ -16,7 +29,7 @@ class ExcelSheet extends Object
1629
protected $_formatters;
1730
protected $_styles = [];
1831
protected $_callbacks;
19-
protected $_row = 1;
32+
protected $_row;
2033

2134
/**
2235
* @param PHPExcel_WorkSheet $sheet
@@ -53,16 +66,16 @@ public function setData($value)
5366
}
5467

5568
/**
56-
* @return string[]|null|false the column titles indexed by 0-based column
57-
* index. If empty, `null` or `false`, no titles will be generated.
69+
* @return string[]|null|false the column titles indexed by column name or
70+
* 0-based index. If empty, `null` or `false`, no titles will be generated.
5871
*/
5972
public function getTitles()
6073
{
6174
return $this->_titles;
6275
}
6376

6477
/**
65-
* @param string[]|null|false $value the column titles indexed by 1-based
78+
* @param string[]|null|false $value the column titles indexed by 0-based
6679
* column index. If empty or `false`, no titles will be generated.
6780
*/
6881
public function setTitles($value)
@@ -171,6 +184,7 @@ public function setCallbacks($value)
171184
*/
172185
public function render()
173186
{
187+
$this->_row = $this->startRow;
174188
$this->renderStyles();
175189
$this->renderTitle();
176190
$this->renderRows();
@@ -191,9 +205,10 @@ protected function renderStyles()
191205
*/
192206
protected function renderTitle()
193207
{
194-
$titles = $this->getTitles();
208+
$titles = $this->normalizeIndex($this->getTitles());
195209
if ($titles) {
196-
$col = 0;
210+
$keys = array_keys($titles);
211+
$col = array_shift($keys);
197212
foreach ($titles as $title) {
198213
$this->_sheet->setCellValueByColumnAndRow($col++, $this->_row, $title);
199214
}
@@ -206,10 +221,10 @@ protected function renderTitle()
206221
*/
207222
protected function renderRows()
208223
{
209-
$formats = self::normalizeIndex($this->getFormats());
210-
$formatters = self::normalizeIndex($this->getFormatters());
211-
$callbacks = self::normalizeIndex($this->getCallbacks());
212-
$types = self::normalizeIndex($this->getTypes());
224+
$formats = $this->normalizeIndex($this->getFormats());
225+
$formatters = $this->normalizeIndex($this->getFormatters());
226+
$callbacks = $this->normalizeIndex($this->getCallbacks());
227+
$types = $this->normalizeIndex($this->getTypes());
213228

214229
foreach ($this->getData() as $data) {
215230
$this->renderRow($data, $this->_row++, $formats, $formatters, $callbacks, $types);
@@ -229,41 +244,56 @@ protected function renderRows()
229244
protected function renderRow($data, $row, $formats, $formatters, $callbacks, $types)
230245
{
231246
foreach (array_values($data) as $i => $value) {
232-
if (isset($formatters[$i]) && is_callable($formatters[$i])) {
233-
$value = call_user_func($formatters[$i], $value, $row, $data);
247+
$col = $i + self::normalizeColumn($this->startColumn);
248+
if (isset($formatters[$col]) && is_callable($formatters[$col])) {
249+
$value = call_user_func($formatters[$col], $value, $row, $data);
234250
}
235-
if (isset($types[$i])) {
236-
$this->_sheet->setCellValueExplicitByColumnAndRow($i, $row, $value, $types[$i]);
251+
if (isset($types[$col])) {
252+
$this->_sheet->setCellValueExplicitByColumnAndRow($col, $row, $value, $types[$col]);
237253
} else {
238-
$this->_sheet->setCellValueByColumnAndRow($i, $row, $value);
254+
$this->_sheet->setCellValueByColumnAndRow($col, $row, $value);
239255
}
240-
if (isset($formats[$i])) {
256+
if (isset($formats[$col])) {
241257
$this->_sheet
242-
->getStyleByColumnAndRow($i, $row)
258+
->getStyleByColumnAndRow($col, $row)
243259
->getNumberFormat()
244-
->setFormatCode($formats[$i]);
260+
->setFormatCode($formats[$col]);
245261
}
246-
if (isset($callbacks[$i]) && is_callable($callbacks[$i])) {
247-
$cell = $this->_sheet->getCellByColumnAndRow($i, $row);
248-
call_user_func($callbacks[$i], $cell, $i, $row);
262+
if (isset($callbacks[$col]) && is_callable($callbacks[$col])) {
263+
$cell = $this->_sheet->getCellByColumnAndRow($col, $row);
264+
call_user_func($callbacks[$col], $cell, $col, $row);
249265
}
250266
}
251267
}
252268

253269
/**
254-
* @param array $data
270+
* @param array $data any data indexed by 0-based colum index or by column name.
255271
* @return array the array with alphanumeric column keys (A, B, C, ...)
256272
* converted to numeric indices
257273
*/
258-
protected static function normalizeIndex($data)
274+
protected function normalizeIndex($data)
259275
{
260276
if (!is_array($data)) {
261277
return $data;
262278
}
263279
$result = [];
264280
foreach ($data as $k => $v) {
265-
$result[is_string($k) ? \PHPExcel_Cell::columnIndexFromString($k)-1 : $k] = $v;
281+
$result[self::normalizeColumn($k)] = $v;
266282
}
267283
return $result;
268284
}
285+
286+
/**
287+
* @param int|string $column the column either as int or as string. If
288+
* numeric, the startColumn offset will be added.
289+
* @return int the normalized numeric column index (0-based).
290+
*/
291+
public function normalizeColumn($column)
292+
{
293+
if (is_string($column)) {
294+
return \PHPExcel_Cell::columnIndexFromString($column) - 1;
295+
} else {
296+
return $column + self::normalizeColumn($this->startColumn);
297+
}
298+
}
269299
}

0 commit comments

Comments
 (0)