Skip to content
Merged
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
65 changes: 54 additions & 11 deletions src/office/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/office/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/office/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