Files
sam-api/app/Services/ExportService.php

130 lines
3.5 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
namespace App\Services;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithStyles;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Facades\Excel;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
/**
* 범용 엑셀 내보내기 서비스
*
* 여러 모듈에서 공통으로 사용할 있는 엑셀 내보내기 기능 제공
* - 근태관리 (AttendanceController)
* - 급여관리 (SalaryController)
* - 기타 데이터 내보내기가 필요한 모듈
*/
class ExportService extends Service
{
/**
* 엑셀 파일 다운로드
*
* @param array<int, array<string, mixed>> $data 내보낼 데이터 배열
* @param array<int, string> $headings 컬럼 헤더 배열
* @param string $filename 다운로드 파일명 (확장자 제외)
* @param string $sheetTitle 시트 제목
*/
public function download(
array $data,
array $headings,
string $filename,
string $sheetTitle = 'Sheet1'
): BinaryFileResponse {
$export = new GenericExport($data, $headings, $sheetTitle);
return Excel::download($export, $filename.'.xlsx');
}
/**
* 엑셀 파일 저장 (서버에 저장)
*
* @param array<int, array<string, mixed>> $data 내보낼 데이터 배열
* @param array<int, string> $headings 컬럼 헤더 배열
* @param string $path 저장 경로 (storage/app 기준)
* @param string $sheetTitle 시트 제목
*/
public function store(
array $data,
array $headings,
string $path,
string $sheetTitle = 'Sheet1'
): bool {
$export = new GenericExport($data, $headings, $sheetTitle);
return Excel::store($export, $path);
}
}
/**
* 범용 엑셀 내보내기 클래스
*
* ExportService에서 내부적으로 사용하는 Maatwebsite Excel 구현체
*/
class GenericExport implements FromArray, ShouldAutoSize, WithHeadings, WithStyles, WithTitle
{
/**
* @param array<int, array<string, mixed>> $data 내보낼 데이터
* @param array<int, string> $headings 컬럼 헤더
* @param string $sheetTitle 시트 제목
*/
public function __construct(
private readonly array $data,
private readonly array $headings,
private readonly string $sheetTitle
) {}
/**
* 데이터 배열 반환
*
* @return array<int, array<string, mixed>>
*/
public function array(): array
{
return $this->data;
}
/**
* 헤더 배열 반환
*
* @return array<int, string>
*/
public function headings(): array
{
return $this->headings;
}
/**
* 시트 제목 반환
*/
public function title(): string
{
return $this->sheetTitle;
}
/**
* 스타일 적용
*
* @return array<int|string, array<string, mixed>>
*/
public function styles(Worksheet $sheet): array
{
return [
// 헤더 행 스타일 (굵게, 배경색)
1 => [
'font' => ['bold' => true],
'fill' => [
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
'startColor' => ['rgb' => 'E2E8F0'],
],
],
];
}
}