Skip to content

Commit

Permalink
feat(MineExcel): Added sorting scheme by order of attributes in the c…
Browse files Browse the repository at this point in the history
…ode (#77)

* feat(MineExcel): 新增按照属性在代码中的顺序排序方案
兼容index方案

* feat(excel): 通过excel表头的中文和dto的value匹配,获取的字段名称和值的映射关系

* 新增可以通过表头名称进行字段的映射获取数据

---------

Co-authored-by: Zds <49744633+zds-s@users.noreply.github.com>
  • Loading branch information
develop-chen and zds-s authored May 13, 2024
1 parent 6d424fc commit fcb45b3
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 20 deletions.
65 changes: 54 additions & 11 deletions src/Excel/PhpOffice.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,10 @@ public function import(MineModel $model, ?\Closure $closure = null): mixed
$sheet = $reader->load($tempFilePath);
$endCell = isset($this->property) ? $this->getColumnIndex(count($this->property)) : null;
try {
foreach ($sheet->getActiveSheet()->getRowIterator(2) as $row) {
$temp = [];
foreach ($row->getCellIterator('A', $endCell) as $index => $item) {
$propertyIndex = ord($index) - 65;
if (isset($this->property[$propertyIndex])) {
$temp[$this->property[$propertyIndex]['name']] = $item->getFormattedValue();
}
}
if (! empty($temp)) {
$data[] = $temp;
}
if ($this->orderByIndex) {
$data = $this->getDataByIndex($sheet, $endCell);
} else {
$data = $this->getDataByText($sheet, $endCell);
}
unlink($tempFilePath);
} catch (\Throwable $e) {
Expand Down Expand Up @@ -183,4 +176,54 @@ protected function yieldExcelData(array &$data): \Generator
yield $yield;
}
}

private function getDataByIndex($sheet, $endCell): array
{
$data = [];
foreach ($sheet->getActiveSheet()->getRowIterator(2) as $row) {
$temp = [];
foreach ($row->getCellIterator('A', $endCell) as $index => $item) {
$propertyIndex = ord($index) - 65;
if (isset($this->property[$propertyIndex])) {
$temp[$this->property[$propertyIndex]['name']] = $item->getFormattedValue();
}
}
if (! empty($temp)) {
$data[] = $temp;
}
}
return $data;
}

private function getDataByText($sheet, $endCell): array
{
$data = [];
// 获取展示名称到字段名的映射关系
$fieldMap = [];
foreach ($this->property as $item) {
$fieldMap[trim($item['value'])] = $item['name'];
}

$headerMap = [];
// 获取表头
// 获取表头,假设表头在第一行
$headerRow = $sheet->getActiveSheet()->getRowIterator(1, 1)->current();
foreach ($headerRow->getCellIterator('A', $endCell) as $index => $item) {
$propertyIndex = ord($index) - 65; // 获得列索引
$value = trim($item->getFormattedValue());
$headerMap[$propertyIndex] = $fieldMap[$value] ?? null; // 获取表头值
}
// 读取数据,从第二行开始
foreach ($sheet->getActiveSheet()->getRowIterator(2) as $row) {
$temp = [];
foreach ($row->getCellIterator('A', $endCell) as $index => $item) {
$propertyIndex = ord($index) - 65; // 获得列索引
if (! empty($headerMap[$propertyIndex])) { // 确保列索引存在于表头数组中
$temp[$headerMap[$propertyIndex]] = trim($item->getFormattedValue()); // 映射表头标题到对应值
}
}
$data[] = $temp;
}
return $data;
}
}
60 changes: 52 additions & 8 deletions src/Excel/XlsWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,11 @@ public function import(MineModel $model, ?\Closure $closure = null): mixed
file_put_contents($tempFilePath, $file->getStream()->getContents());
$xlsxObject = new Excel(['path' => BASE_PATH . '/runtime/']);
$data = $xlsxObject->openFile($tempFileName)->openSheet()->getSheetData();
unset($data[0]);

$importData = [];
foreach ($data as $item) {
$tmp = [];
foreach ($item as $key => $value) {
$tmp[$this->property[$key]['name']] = (string) $value;
}
$importData[] = $tmp;
if ($this->orderByIndex) {
$importData = $this->getDataByIndex($data);
} else {
$importData = $this->getDataByText($data);
}

if ($closure instanceof \Closure) {
Expand Down Expand Up @@ -178,4 +174,52 @@ public function export(string $filename, array|\Closure $closure, ?\Closure $cal

return $res;
}

private function getDataByIndex($data)
{
unset($data[0]);
$importData = [];
foreach ($data as $item) {
$tmp = [];
foreach ($item as $key => $value) {
$tmp[$this->property[$key]['name']] = (string) $value;
}
$importData[] = $tmp;
}
return $importData;
}

private function getDataByText($data): array
{
$importData = [];
// 获取展示名称到字段名的映射关系
$fieldMap = [];
foreach ($this->property as $item) {
$fieldMap[trim($item['value'])] = $item['name'];
}

$headerMap = [];
// 获取表头
foreach ($data[0] as $index => $value) {
$propertyIndex = $index; // 获得列索引
$value = trim((string) $value);
$headerMap[$propertyIndex] = $fieldMap[$value] ?? null; // 获取表头值
}

// 读取数据,从第二行开始
unset($data[0]);
foreach ($data as $row) {
$temp = [];
foreach ($row as $index => $value) {
$propertyIndex = $index; // 获得列索引
if (! empty($headerMap[$propertyIndex])) { // 确保列索引存在于表头数组中
$temp[$headerMap[$propertyIndex]] = trim((string) $value); // 映射表头标题到对应值
}
}
if (! empty($temp)) {
$importData[] = $temp;
}
}
return $importData;
}
}
20 changes: 19 additions & 1 deletion src/MineExcel.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ abstract class MineExcel

protected array $dictData = [];

/**
* 是否通过index进行排序
* 否则使用属性在代码中的位置进行排序
* 同时影响 导入和导出.
*/
protected ?bool $orderByIndex;

public function __construct(string $dto)
{
if (! (new $dto()) instanceof MineModelExcel) {
Expand Down Expand Up @@ -66,8 +73,13 @@ protected function parseProperty(): void
throw new MineException('dto annotation info is empty', 500);
}

// 判断数组中任意一行包含 index键
$this->orderByIndex = array_reduce(array_values($this->annotationMate['_p']), function ($carry, $item) {
return $carry || isset($item[self::ANNOTATION_NAME]->index);
}, false);

foreach ($this->annotationMate['_p'] as $name => $mate) {
$this->property[$mate[self::ANNOTATION_NAME]->index] = [
$tmp = [
'name' => $name,
'value' => $mate[self::ANNOTATION_NAME]->value,
'width' => $mate[self::ANNOTATION_NAME]->width ?? null,
Expand All @@ -80,6 +92,12 @@ protected function parseProperty(): void
'dictName' => empty($mate[self::ANNOTATION_NAME]->dictName) ? null : $this->getDictData($mate[self::ANNOTATION_NAME]->dictName),
'path' => $mate[self::ANNOTATION_NAME]->path ?? null,
];

if ($this->orderByIndex) {
$this->property[$mate[self::ANNOTATION_NAME]->index] = $tmp;
} else {
$this->property[] = $tmp;
}
}
ksort($this->property);
}
Expand Down

0 comments on commit fcb45b3

Please sign in to comment.