Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
### Added

- Improved the ARABIC function to also hande short-hand roman numerals
- Option for CSV files to have varying numbers of columns for each individual row

### Fixed

Expand Down
12 changes: 12 additions & 0 deletions docs/topics/reading-and-writing-to-file.md
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,18 @@ $writer->setUseBOM(true);
$writer->save("05featuredemo.csv");
```

#### Writing CSV files with varying numbers of columns

A CSV file can have a different number of columns in each row. This
differs from the default behavior when saving as a .csv in Excel, but
can be enabled in PhpSpreadsheet by using the following code:

``` php
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
$writer->setVariableColumns(true);
$writer->save("05featuredemo.csv");
```

#### Decimal and thousands separators

If the worksheet you are exporting contains numbers with decimal or
Expand Down
40 changes: 40 additions & 0 deletions src/PhpSpreadsheet/Writer/Csv.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ class Csv extends BaseWriter
*/
private $excelCompatibility = false;

/**
* Whether number of columns should be allowed to vary
* between rows, or use a fixed range based on the max
* column overall.
*
* @var bool
*/
private $variableColumns = false;

/**
* Create a new CSV.
*
Expand Down Expand Up @@ -119,6 +128,9 @@ public function save($pFilename)

// Write rows to file
for ($row = 1; $row <= $maxRow; ++$row) {
if ($this->variableColumns) {
$maxCol = $sheet->getHighestDataColumn($row);
}
// Convert the row to an array...
$cellsArray = $sheet->rangeToArray('A' . $row . ':' . $maxCol . $row, '', $this->preCalculateFormulas);
// ... and write to the file
Expand Down Expand Up @@ -280,6 +292,34 @@ public function setExcelCompatibility($pValue)
return $this;
}

/**
* Get whether number of columns should be allowed to vary
* between rows, or use a fixed range based on the max
* column overall.
*
* @return bool
*/
public function getVariableColumns()
{
return $this->variableColumns;
}

/**
* Set whether number of columns should be allowed to vary
* between rows, or use a fixed range based on the max
* column overall.
*
* @param bool $pValue Set the writer to allow variable column counts
*
* @return $this
*/
public function setVariableColumns($pValue)
{
$this->variableColumns = $pValue;

return $this;
}

/**
* Get sheet index.
*
Expand Down
36 changes: 36 additions & 0 deletions tests/PhpSpreadsheetTests/Writer/Csv/VariableColumnsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace PhpOffice\PhpSpreadsheetTests\Writer\Csv;

use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;

class VariableColumnsTest extends TestCase
{
public function testVariableColumns()
{
$spreadsheet = new Spreadsheet();
$spreadsheet->setActiveSheetIndex(0);
$spreadsheet->getActiveSheet()->setCellValue('A1', 'A1');
$spreadsheet->getActiveSheet()->setCellValue('B1', 'B1');
$spreadsheet->getActiveSheet()->setCellValue('A2', 'A2');
$spreadsheet->getActiveSheet()->setCellValue('B2', 'B2');
$spreadsheet->getActiveSheet()->setCellValue('C2', 'C2');
$spreadsheet->getActiveSheet()->setCellValue('A3', 'A3');

$filename = tempnam(File::sysGetTempDir(), 'phpspreadsheet-test');
$writer = IOFactory::createWriter($spreadsheet, 'Csv');
$writer->setVariableColumns(true);
$writer->save($filename);

$contents = file_get_contents($filename);

$rows = explode(PHP_EOL, $contents);

$this->assertEquals('"A1","B1"', $rows[0]);
$this->assertEquals('"A2","B2","C2"', $rows[1]);
$this->assertEquals('"A3"', $rows[2]);
}
}