Files
sam-api/app/Services/ExportService.php
kent a1aa8726af feat: 공통 모듈 추가 (엑셀 내보내기, 계정과목 일괄변경)
Phase 0 - 공통 모듈:
- ExportService.php 생성 (Maatwebsite/Excel 기반 엑셀 내보내기)
- BulkUpdateAccountCodeRequest.php 생성 (계정과목 일괄변경 유효성 검사)

Phase 1 - 계정과목 일괄변경:
- WithdrawalController/Service: bulkUpdateAccountCode 메서드 추가
- DepositController/Service: bulkUpdateAccountCode 메서드 추가
- POST /v1/withdrawals/bulk-update-account-code
- POST /v1/deposits/bulk-update-account-code

Phase 2 - 엑셀 내보내기:
- AttendanceController/Service: export, getExportData 메서드 추가
- SalaryController/Service: export, getExportData 메서드 추가
- GET /v1/attendances/export
- GET /v1/salaries/export

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-15 17:14:04 +09:00

130 lines
3.5 KiB
PHP

<?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'],
],
],
];
}
}