Skip to content

Commit

Permalink
Allow CSV escape character to be set
Browse files Browse the repository at this point in the history
  • Loading branch information
rdarcy1 authored and Frederic Delaunay committed Oct 29, 2018
1 parent 1875495 commit dd312ea
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- Support to read Xlsm templates with form elements, macros, printer settings, protected elements and back compatibility drawing, and save result without losing important elements of document - [#435](https://github.com/PHPOffice/PhpSpreadsheet/issues/435)
- Expose sheet title maximum length as `Worksheet::SHEET_TITLE_MAXIMUM_LENGTH` - [#482](https://github.com/PHPOffice/PhpSpreadsheet/issues/482)
- Allow escape character to be set in CSV reader – [#492](https://github.com/PHPOffice/PhpSpreadsheet/issues/492)

### Fixed

Expand Down
35 changes: 33 additions & 2 deletions src/PhpSpreadsheet/Reader/Csv.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ class Csv extends BaseReader
*/
private $contiguousRow = -1;

/**
* The character that can escape the enclosure.
*
* @var string
*/
private $escapeCharacter = '\\';

/**
* Create a new CSV Reader instance.
*/
Expand Down Expand Up @@ -254,7 +261,7 @@ public function listWorksheetInfo($pFilename)
$worksheetInfo[0]['totalColumns'] = 0;

// Loop through each line of the file in turn
while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure)) !== false) {
while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure, $this->escapeCharacter)) !== false) {
++$worksheetInfo[0]['totalRows'];
$worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1);
}
Expand Down Expand Up @@ -326,7 +333,7 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
}

// Loop through each line of the file in turn
while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure)) !== false) {
while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure, $this->escapeCharacter)) !== false) {
$columnLetter = 'A';
foreach ($rowData as $rowDatum) {
if ($rowDatum != '' && $this->readFilter->readCell($columnLetter, $currentRow)) {
Expand Down Expand Up @@ -458,6 +465,30 @@ public function getContiguous()
return $this->contiguous;
}

/**
* Set escape backslashes.
*
* @param string $escapeCharacter
*
* @return $this
*/
public function setEscapeCharacter($escapeCharacter)
{
$this->escapeCharacter = $escapeCharacter;

return $this;
}

/**
* Get escape backslashes.
*
* @return string
*/
public function getEscapeCharacter()
{
return $this->escapeCharacter;
}

/**
* Can the current IReader read the file?
*
Expand Down
15 changes: 15 additions & 0 deletions tests/PhpSpreadsheetTests/Reader/CsvTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,19 @@ public function providerCanLoad()
[true, '../samples/Reader/sampleData/example2.csv'],
];
}

public function testEscapeCharacters()
{
$reader = (new Csv())->setEscapeCharacter('"');
$worksheet = $reader->load(__DIR__ . '/../../data/Reader/CSV/backslash.csv')
->getActiveSheet();

$expected = [
['field 1', 'field 2\\'],
['field 3\\', 'field 4'],
];

$this->assertSame('"', $reader->getEscapeCharacter());
$this->assertSame($expected, $worksheet->toArray());
}
}
2 changes: 2 additions & 0 deletions tests/data/Reader/CSV/backslash.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"field 1","field 2\"
"field 3\","field 4"

0 comments on commit dd312ea

Please sign in to comment.