Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to set custom headers (whether or not headers exist in the file) #103

Merged
merged 6 commits into from
Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from 5 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
29 changes: 25 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ SimpleExcelReader::create($pathToCsv)->getRows()
});
```

#### Reading a file without titles
#### Reading a file without headers

If the file you are reading does not contain a title row, then you should use the `noHeaderRow()` method.
If the file you are reading does not contain a header row, then you should use the `noHeaderRow()` method.

```php
// $rows is an instance of Illuminate\Support\LazyCollection
Expand All @@ -107,6 +107,25 @@ $rows = SimpleExcelReader::create($pathToCsv)
});
```

#### Manually setting the headers

If you would like to use a specific array of values for the headers, you can use the `setHeaders()` method.

```php
// $rows is an instance of Illuminate\Support\LazyCollection
$rows = SimpleExcelReader::create($pathToCsv)
->setHeaders(['email_address', 'given_name'])
kitbs marked this conversation as resolved.
Show resolved Hide resolved
->getRows()
->each(function(array $rowProperties) {
// in the first pass $rowProperties will contain
// ['email_address' => 'john@example', 'given_name' => 'john']
});
```

If your file already contains a header row, it will be ignored and replaced with your custom headers.

If your file does not contain a header row, you should also use `noHeaderRow()`, and your headers will be used instead of numeric keys, as above.

### Working with multiple sheet documents

Excel files can include multiple spreadsheets. You can select the sheet you want to use with the `fromSheet()` method.
Expand All @@ -117,10 +136,12 @@ $rows = SimpleExcelReader::create($pathToXlsx)
->getRows();
```

#### Retrieving Header Row values
#### Retrieving header row values

If you would like to retrieve the header row as an array, you can use the `getHeaders()` method.

If you have used `setHeaders()` to set custom headers, these will be returned instead of the actual headers in the file. To get the original headers from the file, use `getOriginalHeaders()`.

```php
$headers = SimpleExcelReader::create($pathToCsv)->getHeaders();

Expand Down Expand Up @@ -162,7 +183,7 @@ $rows = SimpleExcelReader::create($pathToCsv)
});
```

#### Trimming Header Row values
#### Trimming headers

If the file you are reading contains a title row, but you need to trim additional characters on the title values, then you should use the `trimHeaderRow()` method.
This functionality mimics the `trim` method, and the default characters it trims, matches that function.
Expand Down
34 changes: 30 additions & 4 deletions src/SimpleExcelReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ class SimpleExcelReader

protected int $headerOnRow = 0;

protected ?array $customHeaders = [];

protected int $skip = 0;

protected int $limit = 0;
Expand Down Expand Up @@ -78,6 +80,13 @@ public function noHeaderRow(): self
return $this;
}

public function setHeaders(array $headers): self
{
$this->customHeaders = $headers;

return $this;
}

public function useDelimiter(string $delimiter): self
{
$this->reader->setFieldDelimiter($delimiter);
Expand Down Expand Up @@ -172,6 +181,10 @@ public function getRows(): LazyCollection
public function getHeaders(): ?array
{
if (! $this->processHeader) {
if ($this->customHeaders) {
return $this->customHeaders;
}

return null;
}

Expand Down Expand Up @@ -203,6 +216,17 @@ public function getHeaders(): ?array

$this->headers = $this->processHeaderRow($headerRow->toArray());

if ($this->customHeaders) {
return $this->customHeaders;
}

return $this->headers;
}

public function getOriginalHeaders(): ?array
{
$this->getHeaders();

return $this->headers;
}

Expand Down Expand Up @@ -267,17 +291,19 @@ protected function getValueFromRow(Row $row): array
$values = $row->toArray();
ksort($values);

if (! $this->processHeader) {
$headers = $this->customHeaders ?: $this->headers;

if (! $headers) {
return $values;
}

$values = array_slice($values, 0, count($this->headers));
$values = array_slice($values, 0, count($headers));

while (count($values) < count($this->headers)) {
while (count($values) < count($headers)) {
$values[] = '';
}

return array_combine($this->headers, $values);
return array_combine($headers, $values);
}

protected function getSheet(): SheetInterface
Expand Down
117 changes: 117 additions & 0 deletions tests/SimpleExcelReaderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,123 @@ public function it_doesnt_return_headers_when_headers_are_ignored()
$this->assertEquals(null, $headers);
}

/** @test */
public function it_can_set_custom_headers_without_header()
{
$rows = SimpleExcelReader::create($this->getStubPath('rows-without-header.csv'))
->noHeaderRow()
->setHeaders(['email', 'first_name', 'last_name'])
->getRows()
->toArray();

$this->assertEquals([
[
'email' => 'john@example.com',
'first_name' => 'john',
'last_name' => 'doe',
],
[
'email' => 'mary-jane@example.com',
'first_name' => 'mary jane',
'last_name' => 'doe',
],
], $rows);
}

/** @test */
public function it_can_set_custom_headers_with_header()
{
$rows = SimpleExcelReader::create($this->getStubPath('header-and-rows.csv'))
->setHeaders(['email_address', 'given_name', 'surname'])
->getRows()
->toArray();

$this->assertEquals([
[
'email_address' => 'john@example.com',
'given_name' => 'john',
'surname' => 'doe',
],
[
'email_address' => 'mary-jane@example.com',
'given_name' => 'mary jane',
'surname' => 'doe',
],
], $rows);
}

/** @test */
public function it_can_set_custom_headers_with_header_on_row()
{
$rows = SimpleExcelReader::create($this->getStubPath('header-not-on-first-row.xlsx'))
->headerOnRow(2)
->setHeaders(['first_name', 'last_name'])
->getRows()
->toArray();

$this->assertEquals([
[
'first_name' => 'Taylor',
'last_name' => 'Otwell',
],
[
'first_name' => 'Adam',
'last_name' => 'Wathan',
],
], $rows);
}

/** @test */
public function it_can_retrieve_the_custom_headers_with_headers()
{
$headers = SimpleExcelReader::create($this->getStubPath('header-and-rows.csv'))
->setHeaders(['email_address', 'given_name', 'surname'])
->getHeaders();

$this->assertEquals([
0 => 'email_address',
1 => 'given_name',
2 => 'surname',
], $headers);
}

/** @test */
public function it_can_retrieve_the_custom_headers_without_headers()
{
$headers = SimpleExcelReader::create($this->getStubPath('rows-without-header.csv'))
->noHeaderRow()
->setHeaders(['email_address', 'given_name', 'surname'])
->getHeaders();

$this->assertEquals([
0 => 'email_address',
1 => 'given_name',
2 => 'surname',
], $headers);
}

/** @test */
public function it_can_retrieve_the_original_headers_with_custom_headers()
{
$reader = SimpleExcelReader::create($this->getStubPath('header-and-rows.csv'))
->setHeaders(['email_address', 'given_name', 'surname']);

$headers = $reader->getHeaders();
$originalHeaders = $reader->getOriginalHeaders();

$this->assertEquals([
0 => 'email_address',
1 => 'given_name',
2 => 'surname',
], $headers);

$this->assertEquals([
0 => 'email',
1 => 'first_name',
2 => 'last_name',
], $originalHeaders);
}

/** @test */
public function it_can_use_an_alternative_delimiter()
{
Expand Down
2 changes: 2 additions & 0 deletions tests/stubs/rows-without-header.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
john@example.com,john,doe
mary-jane@example.com,mary jane,doe