Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
inxilpro committed Jul 24, 2024
1 parent e764090 commit ac3560f
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 160 deletions.
42 changes: 3 additions & 39 deletions src/CsvReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,12 @@

namespace Glhd\Linen;

use Illuminate\Support\LazyCollection;
use Illuminate\Support\Str;
use OpenSpout\Reader\CSV\Reader as OpenSpoutReader;
use UnexpectedValueException;
use OpenSpout\Reader\ReaderInterface;

class CsvReader extends Reader
{
public function collect(): LazyCollection
protected function reader(): ReaderInterface
{
return new LazyCollection(function() {
$reader = new OpenSpoutReader();
$reader->open($this->path);

try {
foreach ($reader->getSheetIterator() as $sheet) {
$columns = 0;
$headers = null;

foreach ($sheet->getRowIterator() as $row) {
if (null === $headers) {
$headers = array_map(Str::snake(...), $row->toArray());
$columns = count($headers);
continue;
}

$data = $row->toArray();
$data_columns = count($data);

if ($columns < $data_columns) {
throw new UnexpectedValueException("Expected {$columns} columns of data but got {$data_columns}");
}

if ($columns > $data_columns) {
$data = array_merge($data, array_fill(0, $columns - $data_columns, null));
}

yield array_combine($headers, $data);
}
}
} finally {
$reader->close();
}
});
return new \OpenSpout\Reader\CSV\Reader();
}
}
58 changes: 16 additions & 42 deletions src/CsvWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,18 @@

namespace Glhd\Linen;

use Generator;
use Illuminate\Contracts\Database\Query\Builder;
use Illuminate\Support\Enumerable;
use OpenSpout\Common\Entity\Row;
use OpenSpout\Writer\CSV\Options;
use OpenSpout\Writer\CSV\Writer as OpenSpoutWriter;
use OpenSpout\Writer\CSV as OpenSpout;
use OpenSpout\Writer\WriterInterface;

class CsvWriter extends Writer
{
public function __construct(
protected array|Enumerable|Generator|Builder $data,
protected bool $headers = true,
protected string $delimiter = ',',
protected string $enclosure = '"',
protected bool $bom = true,
protected bool $empty_new_line = true,
) {
parent::__construct($data, $headers);
}
protected string $delimiter = ',';

protected string $enclosure = '"';

protected bool $bom = true;

protected bool $empty_new_line = true;

public function withDelimiter(string $delimiter): static
{
Expand Down Expand Up @@ -52,20 +45,7 @@ public function withoutEmptyNewLineAtEndOfFile(): static

public function write(string $path): string
{
$options = new Options();
$options->FIELD_DELIMITER = $this->delimiter;
$options->FIELD_ENCLOSURE = $this->enclosure;
$options->SHOULD_ADD_BOM = $this->bom;

$writer = new OpenSpoutWriter($options);

$writer->openToFile($path);

foreach ($this->rows() as $row) {
$writer->addRow(Row::fromValues($row->toArray()));
}

$writer->close();
parent::write($path);

if ($this->empty_new_line) {
file_put_contents($path, rtrim(file_get_contents($path), PHP_EOL));
Expand All @@ -74,19 +54,13 @@ public function write(string $path): string
return $path;
}

protected function rows(): Generator
protected function writer(): WriterInterface
{
$source = parent::rows();

$needs_headers = $this->headers;
$options = new OpenSpout\Options();
$options->FIELD_DELIMITER = $this->delimiter;
$options->FIELD_ENCLOSURE = $this->enclosure;
$options->SHOULD_ADD_BOM = $this->bom;

foreach ($source as $row) {
if ($needs_headers) {
$needs_headers = false;
yield $row->keys()->map($this->header_formatter);
}

yield $row;
}
return new OpenSpout\Writer($options);
}
}
55 changes: 4 additions & 51 deletions src/ExcelReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,13 @@

namespace Glhd\Linen;

use Illuminate\Support\LazyCollection;
use Illuminate\Support\Str;
use OpenSpout\Reader\XLSX\Reader as OpenSpoutReader;
use UnexpectedValueException;
use OpenSpout\Reader\ReaderInterface;
use OpenSpout\Reader\XLSX as OpenSpout;

class ExcelReader extends Reader
{
public function collect(): LazyCollection
protected function reader(): ReaderInterface
{
return new LazyCollection(function() {
$reader = new OpenSpoutReader();
$reader->open($this->path);

try {
foreach ($reader->getSheetIterator() as $sheet) {
$columns = 0;
$headers = null;

foreach ($sheet->getRowIterator() as $row) {
if (null === $headers) {
$headers = array_map($this->header(...), $row->toArray());
$columns = count($headers);
continue;
}

$data = $row->toArray();
$data_columns = count($data);

if ($columns < $data_columns) {
throw new UnexpectedValueException("Expected {$columns} columns of data but got {$data_columns}");
}

if ($columns > $data_columns) {
$data = array_merge($data, array_fill(0, $columns - $data_columns, null));
}

yield array_combine($headers, $data);
}
}
} finally {
$reader->close();
}
});
}

protected function header(string $value): string
{
// If our header has no lower-case characters, we'll convert it to
// all lower-case first. This ensures that values like "NACHI ID" turn
// into "nachi_id" rather than "N_A_C_H_I_I_D".
if (! preg_match('/[a-z]/', $value)) {
$value = strtolower($value);
}

return Str::snake($value);
return new OpenSpout\Reader();
}
}
26 changes: 4 additions & 22 deletions src/ExcelWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,13 @@

namespace Glhd\Linen;

use Illuminate\Support\Collection;
use OpenSpout\Common\Entity\Row;
use OpenSpout\Writer\XLSX\Options;
use OpenSpout\Writer\XLSX\Writer as OpenSpoutWriter;
use OpenSpout\Writer\WriterInterface;
use OpenSpout\Writer\XLSX as OpenSpout;

class ExcelWriter extends Writer
{
public function write(string $path): string
protected function writer(): WriterInterface
{
$options = new Options();

$writer = new OpenSpoutWriter($options);

$writer->openToFile($path);

/** @var Collection $first_row */
$first_row = current(iterator_to_array($this->rows()));
$writer->addRow(Row::fromValues($first_row->keys()->all()));

foreach ($this->rows() as $row) {
$writer->addRow(Row::fromValues($row->toArray()));
}

$writer->close();

return $path;
return new OpenSpout\Writer(new OpenSpout\Options());
}
}
49 changes: 48 additions & 1 deletion src/Reader.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@
namespace Glhd\Linen;

use Illuminate\Support\LazyCollection;
use Illuminate\Support\Str;
use OpenSpout\Reader\ReaderInterface;
use UnexpectedValueException;

abstract class Reader
{
abstract protected function reader(): ReaderInterface;

public static function read(string $path): LazyCollection
{
return (new static($path))->collect();
Expand All @@ -16,5 +21,47 @@ public function __construct(
) {
}

abstract public function collect(): LazyCollection;
public function collect(): LazyCollection
{
return new LazyCollection(function() {
$reader = $this->reader();
$reader->open($this->path);

try {
foreach ($reader->getSheetIterator() as $sheet) {
$columns = 0;
$keys = null;

foreach ($sheet->getRowIterator() as $row) {
if (null === $keys) {
$keys = array_map($this->headerToKey(...), $row->toArray());
$columns = count($keys);
continue;
}

$data = $row->toArray();
$data_columns = count($data);

if ($columns < $data_columns) {
// TODO: Offer option to trim
throw new UnexpectedValueException("Expected {$columns} columns of data but got {$data_columns}");
}

if ($columns > $data_columns) {
$data = array_merge($data, array_fill(0, $columns - $data_columns, null));
}

yield array_combine($keys, $data);
}
}
} finally {
$reader->close();
}
});
}

protected function headerToKey(string $value): string
{
return Str::snake(strtolower($value));
}
}
43 changes: 38 additions & 5 deletions src/Writer.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
use Illuminate\Support\Facades\App;
use Illuminate\Support\LazyCollection;
use Illuminate\Support\Str;
use OpenSpout\Common\Entity\Row;
use OpenSpout\Writer\WriterInterface;

abstract class Writer
{
protected bool $headers = true;

protected Closure $header_formatter;

abstract public function write(string $path): string;
abstract protected function writer(): WriterInterface;

public static function for(array|Enumerable|Generator|Builder $data): static
{
Expand All @@ -25,7 +29,6 @@ public static function for(array|Enumerable|Generator|Builder $data): static

public function __construct(
protected array|Enumerable|Generator|Builder $data,
protected bool $headers = true,
) {
$this->header_formatter = Str::headline(...);
}
Expand All @@ -37,13 +40,33 @@ public function withoutHeaders(): static
return $this;
}

public function withOriginalKeysAsHeaders(): static
public function withHeaderFormatter(Closure $header_formatter): static
{
$this->header_formatter = static fn($key) => $key;
$this->header_formatter = $header_formatter;

return $this;
}

public function withOriginalKeysAsHeaders(): static
{
return $this->withHeaderFormatter(static fn($key) => $key);
}

public function write(string $path): string
{
$writer = $this->writer();

$writer->openToFile($path);

foreach ($this->rows() as $row) {
$writer->addRow(Row::fromValues($row->toArray()));
}

$writer->close();

return $path;
}

public function writeToHttpFile(): File
{
$path = $this->writeToTemporaryFile();
Expand All @@ -60,6 +83,7 @@ public function writeToTemporaryFile(): string
return $this->write($path);
}

/** @return Generator<Collection> */
protected function rows(): Generator
{
$source = match (true) {
Expand All @@ -69,8 +93,17 @@ protected function rows(): Generator
default => $this->data,
};

$needs_headers = $this->headers;

foreach ($source as $row) {
yield Collection::make($row);
$row = Collection::make($row);

if ($needs_headers) {
$needs_headers = false;
yield $row->keys()->map($this->header_formatter);
}

yield $row;
}
}
}

0 comments on commit ac3560f

Please sign in to comment.