chengkun
2025-06-05 4080b5997b38ca84b3b203c7101dcadb97b76925
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
<?php
 
namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
 
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet as ActualWorksheet;
 
class AutoFilter extends WriterPart
{
    /**
     * Write AutoFilter.
     */
    public static function writeAutoFilter(XMLWriter $objWriter, ActualWorksheet $worksheet): void
    {
        $autoFilterRange = $worksheet->getAutoFilter()->getRange();
        if (!empty($autoFilterRange)) {
            // autoFilter
            $objWriter->startElement('autoFilter');
 
            // Strip any worksheet reference from the filter coordinates
            $range = Coordinate::splitRange($autoFilterRange);
            $range = $range[0];
            //    Strip any worksheet ref
            [$ws, $range[0]] = ActualWorksheet::extractSheetTitle($range[0], true);
            $range = implode(':', $range);
 
            $objWriter->writeAttribute('ref', str_replace('$', '', $range));
 
            $columns = $worksheet->getAutoFilter()->getColumns();
            if (count($columns) > 0) {
                foreach ($columns as $columnID => $column) {
                    $colId = $worksheet->getAutoFilter()->getColumnOffset($columnID);
                    self::writeAutoFilterColumn($objWriter, $column, $colId);
                }
            }
            $objWriter->endElement();
        }
    }
 
    /**
     * Write AutoFilter's filterColumn.
     */
    public static function writeAutoFilterColumn(XMLWriter $objWriter, Column $column, int $colId): void
    {
        $rules = $column->getRules();
        if (count($rules) > 0) {
            $objWriter->startElement('filterColumn');
            $objWriter->writeAttribute('colId', "$colId");
 
            $objWriter->startElement($column->getFilterType());
            if ($column->getJoin() == Column::AUTOFILTER_COLUMN_JOIN_AND) {
                $objWriter->writeAttribute('and', '1');
            }
 
            foreach ($rules as $rule) {
                self::writeAutoFilterColumnRule($column, $rule, $objWriter);
            }
 
            $objWriter->endElement();
 
            $objWriter->endElement();
        }
    }
 
    /**
     * Write AutoFilter's filterColumn Rule.
     */
    private static function writeAutoFilterColumnRule(Column $column, Rule $rule, XMLWriter $objWriter): void
    {
        if (
            ($column->getFilterType() === Column::AUTOFILTER_FILTERTYPE_FILTER)
            && ($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_EQUAL)
            && ($rule->getValue() === '')
        ) {
            //    Filter rule for Blanks
            $objWriter->writeAttribute('blank', '1');
        } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) {
            //    Dynamic Filter Rule
            $objWriter->writeAttribute('type', $rule->getGrouping());
            $val = $column->getAttribute('val');
            if ($val !== null) {
                $objWriter->writeAttribute('val', "$val");
            }
            $maxVal = $column->getAttribute('maxVal');
            if ($maxVal !== null) {
                $objWriter->writeAttribute('maxVal', "$maxVal");
            }
        } elseif ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) {
            //    Top 10 Filter Rule
            $ruleValue = $rule->getValue();
            if (!is_array($ruleValue)) {
                $objWriter->writeAttribute('val', "$ruleValue");
            }
            $objWriter->writeAttribute('percent', (($rule->getOperator() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0'));
            $objWriter->writeAttribute('top', (($rule->getGrouping() === Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1' : '0'));
        } else {
            //    Filter, DateGroupItem or CustomFilter
            $objWriter->startElement($rule->getRuleType());
 
            if ($rule->getOperator() !== Rule::AUTOFILTER_COLUMN_RULE_EQUAL) {
                $objWriter->writeAttribute('operator', $rule->getOperator());
            }
            if ($rule->getRuleType() === Rule::AUTOFILTER_RULETYPE_DATEGROUP) {
                // Date Group filters
                $ruleValue = $rule->getValue();
                if (is_array($ruleValue)) {
                    foreach ($ruleValue as $key => $value) {
                        $objWriter->writeAttribute($key, "$value");
                    }
                }
                $objWriter->writeAttribute('dateTimeGrouping', $rule->getGrouping());
            } else {
                $ruleValue = $rule->getValue();
                if (!is_array($ruleValue)) {
                    $objWriter->writeAttribute('val', "$ruleValue");
                }
            }
 
            $objWriter->endElement();
        }
    }
}