HeaderHandler   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 144
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 63
c 0
b 0
f 0
dl 0
loc 144
rs 10
wmc 24

3 Methods

Rating   Name   Duplication   Size   Complexity  
C setTitle() 0 71 16
A setHeader() 0 20 4
A formatHeaderTitle() 0 20 4
1
<?php
2
/**
3
 * @name: HeaderHandler
4
 * @author: JiaMeng <[email protected]>
5
 * @file: HeaderHandler.php
6
 * @Date: 2025/01/XX
7
 */
8
namespace tinymeng\spreadsheet\Excel\Handler;
9
10
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
11
use PhpOffice\PhpSpreadsheet\RichText\RichText;
12
use PhpOffice\PhpSpreadsheet\Style\Color;
13
use tinymeng\spreadsheet\Util\WorkSheetHelper;
14
15
class HeaderHandler
16
{
17
    /**
18
     * 设置主标题(第一行)
19
     * @param Worksheet $worksheet
20
     * @param string $mainTitle
21
     * @param array $fileTitle
22
     * @return int 返回标题所在行号
23
     */
24
    public static function setHeader(Worksheet $worksheet, string $mainTitle, array $fileTitle): int
25
    {
26
        $row = 1;
27
        if (!empty($mainTitle)) {
28
            $worksheet->setCellValue('A' . $row, $mainTitle);
29
            
30
            // 计算实际的标题列数
31
            $titleCount = 0;
32
            foreach ($fileTitle as $val) {
33
                if (is_array($val)) {
34
                    $titleCount += count($val); // 如果是数组,加上子项的数量
35
                } else {
36
                    $titleCount++; // 如果是单个标题,加1
37
                }
38
            }
39
            
40
            // 使用实际的标题列数来合并单元格
41
            $worksheet->mergeCells('A' . $row . ':' . WorkSheetHelper::cellName($titleCount - 1) . $row);
42
        }
43
        return $row;
44
    }
45
46
    /**
47
     * 设置表头
48
     * @param Worksheet $worksheet
49
     * @param array $fileTitle
50
     * @param int $titleRow 标题行数(合并行数)
51
     * @param array $titleConfig 标题配置
52
     * @param int $col 当前列索引
53
     * @param int $row 当前行索引
54
     * @param int|null $titleHeight 行高
55
     * @param int|null $titleWidth 列宽
56
     * @param array $requiredFields 必填字段列表
57
     * @return array ['col' => int, 'row' => int] 返回更新后的列和行
58
     */
59
    public static function setTitle(
60
        Worksheet $worksheet,
61
        array $fileTitle,
62
        int $titleRow,
63
        array $titleConfig,
64
        int $col,
65
        int $row,
66
        ?int $titleHeight = null,
67
        ?int $titleWidth = null,
68
        array $requiredFields = []
69
    ): array {
70
        if (!empty($titleConfig['title_start_row'])) {
71
            $row = $titleConfig['title_start_row'];
72
        }
73
74
        $_merge = WorkSheetHelper::cellName($col);
75
        foreach ($fileTitle as $key => $val) {
76
            if (!empty($titleHeight)) {
77
                $worksheet->getRowDimension($col)->setRowHeight($titleHeight); // 行高度
78
            }
79
            $rowName = WorkSheetHelper::cellName($col);
80
            $worksheet->getStyle($rowName . $row)->getAlignment()->setWrapText(true); // 自动换行
81
            
82
            if (is_array($val)) {
83
                $num = 1;
84
                $_cols = $col;
85
                foreach ($val as $k => $v) {
86
                    if (!isset($titleConfig['title_show']) || $titleConfig['title_show'] !== false) {
87
                        // 检查子标题是否必填
88
                        $cellValue = self::formatHeaderTitle($k, $v, $requiredFields);
89
                        $worksheet->setCellValue(WorkSheetHelper::cellName($_cols) . ($row + 1), $cellValue);
90
                    }
91
                    if (!empty($titleWidth)) {
92
                        $worksheet->getColumnDimension(WorkSheetHelper::cellName($_cols))->setWidth($titleWidth); // 列宽度
93
                    } else {
94
                        $worksheet->getColumnDimension(WorkSheetHelper::cellName($_cols))->setAutoSize(true); // 自动计算宽度
95
                    }
96
                    if ($num < count($val)) {
97
                        $col++;
98
                        $num++;
99
                    }
100
                    $_cols++;
101
                }
102
                $worksheet->mergeCells($_merge . $row . ':' . WorkSheetHelper::cellName($col) . $row);
103
                if (!isset($titleConfig['title_show']) || $titleConfig['title_show'] !== false) {
104
                    // 检查主标题是否必填(根据第一个子字段判断)
105
                    $firstSubField = reset($val);
106
                    $cellValue = self::formatHeaderTitle($key, $firstSubField, $requiredFields);
107
                    $worksheet->setCellValue($_merge . $row, $cellValue);
108
                }
109
            } else {
110
                if ($titleRow != 1) {
111
                    $worksheet->mergeCells($rowName . $row . ':' . $rowName . ($row + $titleRow - 1));
112
                }
113
                if (!isset($titleConfig['title_show']) || $titleConfig['title_show'] !== false) {
114
                    // 检查字段是否必填并格式化标题
115
                    $cellValue = self::formatHeaderTitle($key, $val, $requiredFields);
116
                    $worksheet->setCellValue($rowName . $row, $cellValue);
117
                }
118
                if (!empty($titleWidth)) {
119
                    $worksheet->getColumnDimension($rowName)->setWidth($titleWidth); // 列宽度
120
                } else {
121
                    $worksheet->getColumnDimension($rowName)->setAutoSize(true); // 自动计算宽度
122
                }
123
            }
124
            $col++;
125
            $_merge = WorkSheetHelper::cellName($col);
126
        }
127
        $row += $titleRow; // 当前行数
128
        
129
        return ['col' => $col, 'row' => $row];
130
    }
131
132
    /**
133
     * 格式化表头标题,如果字段必填则添加红色星号
134
     * @param string $title 表头标题
135
     * @param string|array $fieldName 字段名
136
     * @param array $requiredFields 必填字段列表
137
     * @return string|RichText 如果必填返回RichText对象,否则返回字符串
138
     */
139
    private static function formatHeaderTitle(string $title, $fieldName, array $requiredFields) {
140
        // 处理字段名为数组的情况
141
        if (is_array($fieldName)) {
142
            $fieldName = reset($fieldName);
143
        }
144
        
145
        // 检查字段是否必填
146
        if (!empty($requiredFields) && in_array($fieldName, $requiredFields)) {
147
            // 创建富文本对象
148
            $richText = new RichText();
149
            // 添加红色星号
150
            $redAsterisk = $richText->createTextRun('*');
151
            $redAsterisk->getFont()->setColor(new Color(Color::COLOR_RED));
152
            // 添加标题文本
153
            $richText->createText($title);
154
            return $richText;
155
        }
156
        
157
        // 非必填字段直接返回标题
158
        return $title;
159
    }
160
}
161
162