|
|
|
|
@ -6,6 +6,7 @@
|
|
|
|
|
namespace App\Exports;
|
|
|
|
|
|
|
|
|
|
use App\Exceptions\ErrorException;
|
|
|
|
|
use App\Models\CourseType;
|
|
|
|
|
use Illuminate\Support\Collection;
|
|
|
|
|
use Maatwebsite\Excel\Concerns\FromCollection;
|
|
|
|
|
use Maatwebsite\Excel\Concerns\WithStyles;
|
|
|
|
|
@ -21,6 +22,7 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
public $data;
|
|
|
|
|
public $hasUsersField = false;
|
|
|
|
|
public $hasProjectUsersField = false;
|
|
|
|
|
public $hasHistoryCoursesField = false;
|
|
|
|
|
public $totalColumns = 0;
|
|
|
|
|
public $totalRows = 0;
|
|
|
|
|
public $expandedFields = [];
|
|
|
|
|
@ -45,6 +47,15 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
'pm_amount' => '投资金额',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// 历史课程信息子列定义
|
|
|
|
|
const HISTORY_COURSES_SUB_COLUMNS = [
|
|
|
|
|
'hc_course_type' => '课程体系',
|
|
|
|
|
'hc_course_name' => '课程名称',
|
|
|
|
|
'hc_signs_pass' => '培养人数未去重',
|
|
|
|
|
'hc_signs_pass_unique' => '培养人数去重',
|
|
|
|
|
'hc_course_signs_pass' => '课程培养人数',
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
public function __construct($data, $exportFields)
|
|
|
|
|
{
|
|
|
|
|
// 需要导出的字段。格式:['name'=>'名字','user.sex'=>'性别']
|
|
|
|
|
@ -81,6 +92,13 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
$this->expandedFields[$subField] = $subLabel;
|
|
|
|
|
$index++;
|
|
|
|
|
}
|
|
|
|
|
} elseif (str_contains($field, 'history_courses')) {
|
|
|
|
|
$this->hasHistoryCoursesField = true;
|
|
|
|
|
// 展开历史课程信息为多列
|
|
|
|
|
foreach (self::HISTORY_COURSES_SUB_COLUMNS as $subField => $subLabel) {
|
|
|
|
|
$this->expandedFields[$subField] = $subLabel;
|
|
|
|
|
$index++;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$this->expandedFields[$field] = $label;
|
|
|
|
|
$index++;
|
|
|
|
|
@ -94,7 +112,7 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
*/
|
|
|
|
|
private function needsDoubleHeader()
|
|
|
|
|
{
|
|
|
|
|
return $this->hasUsersField || $this->hasProjectUsersField;
|
|
|
|
|
return $this->hasUsersField || $this->hasProjectUsersField || $this->hasHistoryCoursesField;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -130,8 +148,12 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
$widths[$letter] = 18;
|
|
|
|
|
} elseif (str_contains($field, 'partners')) {
|
|
|
|
|
$widths[$letter] = 50;
|
|
|
|
|
} elseif (str_contains($field, 'hc_course_type') || str_contains($field, 'hc_course_name')) {
|
|
|
|
|
$widths[$letter] = 25;
|
|
|
|
|
} elseif (str_contains($field, 'hc_')) {
|
|
|
|
|
$widths[$letter] = 18;
|
|
|
|
|
} elseif (str_contains($field, 'history_courses')) {
|
|
|
|
|
// 历史课程信息通常较长,适当放宽列宽
|
|
|
|
|
// 历史课程信息通常较长,适当放宽列宽(如果没有展开的情况)
|
|
|
|
|
$widths[$letter] = 40;
|
|
|
|
|
} elseif (str_contains($field, 'all_course')) {
|
|
|
|
|
$widths[$letter] = 40;
|
|
|
|
|
@ -266,6 +288,13 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
$sheet->mergeCells("{$startCol}1:{$endCol}1");
|
|
|
|
|
$sheet->setCellValue("{$startCol}1", $label);
|
|
|
|
|
$index += count(self::PROJECT_USERS_SUB_COLUMNS);
|
|
|
|
|
} elseif (str_contains($field, 'history_courses')) {
|
|
|
|
|
// 历史课程信息列:合并第一行的多个单元格
|
|
|
|
|
$startCol = $this->getColumnLetter($index);
|
|
|
|
|
$endCol = $this->getColumnLetter($index + count(self::HISTORY_COURSES_SUB_COLUMNS) - 1);
|
|
|
|
|
$sheet->mergeCells("{$startCol}1:{$endCol}1");
|
|
|
|
|
$sheet->setCellValue("{$startCol}1", $label);
|
|
|
|
|
$index += count(self::HISTORY_COURSES_SUB_COLUMNS);
|
|
|
|
|
} else {
|
|
|
|
|
// 其他列:合并第一行和第二行
|
|
|
|
|
$col = $this->getColumnLetter($index);
|
|
|
|
|
@ -305,6 +334,10 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
foreach (self::PROJECT_USERS_SUB_COLUMNS as $subLabel) {
|
|
|
|
|
$header1[] = '';
|
|
|
|
|
}
|
|
|
|
|
} elseif (str_contains($field, 'history_courses')) {
|
|
|
|
|
foreach (self::HISTORY_COURSES_SUB_COLUMNS as $subLabel) {
|
|
|
|
|
$header1[] = '';
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$header1[] = '';
|
|
|
|
|
}
|
|
|
|
|
@ -322,6 +355,10 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
foreach (self::PROJECT_USERS_SUB_COLUMNS as $subLabel) {
|
|
|
|
|
$header2[] = $subLabel;
|
|
|
|
|
}
|
|
|
|
|
} elseif (str_contains($field, 'history_courses')) {
|
|
|
|
|
foreach (self::HISTORY_COURSES_SUB_COLUMNS as $subLabel) {
|
|
|
|
|
$header2[] = $subLabel;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
$header2[] = '';
|
|
|
|
|
}
|
|
|
|
|
@ -333,11 +370,11 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
$expandedRows = $this->getExpandedRows($info);
|
|
|
|
|
if (empty($expandedRows)) {
|
|
|
|
|
// 没有展开数据,输出一行空数据
|
|
|
|
|
$row = $this->buildExpandedRow($info, [], []);
|
|
|
|
|
$row = $this->buildExpandedRow($info, [], [], []);
|
|
|
|
|
$newList[] = $row;
|
|
|
|
|
} else {
|
|
|
|
|
foreach ($expandedRows as $expandedRow) {
|
|
|
|
|
$row = $this->buildExpandedRow($info, $expandedRow['users'] ?? [], $expandedRow['project_users'] ?? []);
|
|
|
|
|
$row = $this->buildExpandedRow($info, $expandedRow['users'] ?? [], $expandedRow['project_users'] ?? [], $expandedRow['history_courses'] ?? []);
|
|
|
|
|
$newList[] = $row;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -400,15 +437,17 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
{
|
|
|
|
|
$usersData = $this->hasUsersField ? $this->getUsersExpanded($info) : [];
|
|
|
|
|
$projectUsersData = $this->hasProjectUsersField ? $this->getProjectUsersExpanded($info) : [];
|
|
|
|
|
$historyCoursesData = $this->hasHistoryCoursesField ? $this->getHistoryCoursesExpanded($info) : [];
|
|
|
|
|
|
|
|
|
|
// 计算最大行数
|
|
|
|
|
$maxRows = max(count($usersData), count($projectUsersData), 1);
|
|
|
|
|
$maxRows = max(count($usersData), count($projectUsersData), count($historyCoursesData), 1);
|
|
|
|
|
|
|
|
|
|
$result = [];
|
|
|
|
|
for ($i = 0; $i < $maxRows; $i++) {
|
|
|
|
|
$result[] = [
|
|
|
|
|
'users' => $usersData[$i] ?? [],
|
|
|
|
|
'project_users' => $projectUsersData[$i] ?? [],
|
|
|
|
|
'history_courses' => $historyCoursesData[$i] ?? [],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -436,6 +475,51 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取展开的历史课程数据(每条历史课程一行)
|
|
|
|
|
*/
|
|
|
|
|
private function getHistoryCoursesExpanded($info)
|
|
|
|
|
{
|
|
|
|
|
if (empty($info['history_courses']) || !is_array($info['history_courses'])) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$result = [];
|
|
|
|
|
foreach ($info['history_courses'] as $item) {
|
|
|
|
|
// 获取课程体系名称
|
|
|
|
|
$courseTypeName = '';
|
|
|
|
|
if (isset($item['type_detail']) && isset($item['type_detail']['name'])) {
|
|
|
|
|
// 关联数据可能是 type_detail(下划线形式)
|
|
|
|
|
$courseTypeName = $item['type_detail']['name'];
|
|
|
|
|
} elseif (isset($item['typeDetail']) && isset($item['typeDetail']['name'])) {
|
|
|
|
|
// 关联数据可能是 typeDetail(驼峰形式)
|
|
|
|
|
$courseTypeName = $item['typeDetail']['name'];
|
|
|
|
|
} elseif (isset($item['type'])) {
|
|
|
|
|
// 如果只有类型ID,尝试查询类型名称
|
|
|
|
|
$typeId = $item['type'];
|
|
|
|
|
try {
|
|
|
|
|
$courseType = CourseType::find($typeId);
|
|
|
|
|
if ($courseType) {
|
|
|
|
|
$courseTypeName = $courseType->name;
|
|
|
|
|
} else {
|
|
|
|
|
$courseTypeName = $typeId; // 如果查询不到,显示ID
|
|
|
|
|
}
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
$courseTypeName = $typeId; // 查询失败,显示ID
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$result[] = [
|
|
|
|
|
'hc_course_type' => $courseTypeName,
|
|
|
|
|
'hc_course_name' => $item['course_name'] ?? '',
|
|
|
|
|
'hc_signs_pass' => $item['course_type_signs_pass'] ?? 0,
|
|
|
|
|
'hc_signs_pass_unique' => $item['course_type_signs_pass_unique'] ?? 0,
|
|
|
|
|
'hc_course_signs_pass' => $item['course_signs_pass'] ?? 0,
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取展开的学员数据(每个学员每条课程一行)
|
|
|
|
|
*/
|
|
|
|
|
@ -481,7 +565,7 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
/**
|
|
|
|
|
* 构建包含展开数据的行
|
|
|
|
|
*/
|
|
|
|
|
private function buildExpandedRow($info, $userData, $projectUserData)
|
|
|
|
|
private function buildExpandedRow($info, $userData, $projectUserData, $historyCourseData = [])
|
|
|
|
|
{
|
|
|
|
|
$row = [];
|
|
|
|
|
foreach ($this->fields as $field => $label) {
|
|
|
|
|
@ -495,15 +579,17 @@ class CommonExport implements FromCollection, WithStyles, WithColumnWidths, With
|
|
|
|
|
foreach (array_keys(self::PROJECT_USERS_SUB_COLUMNS) as $subField) {
|
|
|
|
|
$row[] = $projectUserData[$subField] ?? '';
|
|
|
|
|
}
|
|
|
|
|
} elseif (str_contains($field, 'history_courses')) {
|
|
|
|
|
// 填充历史课程信息列
|
|
|
|
|
foreach (array_keys(self::HISTORY_COURSES_SUB_COLUMNS) as $subField) {
|
|
|
|
|
$row[] = $historyCourseData[$subField] ?? '';
|
|
|
|
|
}
|
|
|
|
|
} elseif (str_contains($field, 'idcard')) {
|
|
|
|
|
$row[] = ' ' . $this->getDotValue($info, $field);
|
|
|
|
|
} elseif (str_contains($field, 'all_course')) {
|
|
|
|
|
$row[] = $this->allCourse($info);
|
|
|
|
|
} elseif (str_contains($field, 'partners')) {
|
|
|
|
|
$row[] = $this->partners($info);
|
|
|
|
|
} elseif (str_contains($field, 'history_courses')) {
|
|
|
|
|
// 历史课程信息字段,格式化为多行文本
|
|
|
|
|
$row[] = $this->historyCourses($info);
|
|
|
|
|
} else {
|
|
|
|
|
$row[] = $this->getDotValue($info, $field);
|
|
|
|
|
}
|
|
|
|
|
|