Passed
Push — master ( 8f7a40...e78bca )
by
unknown
16:52 queued 09:09
created

Workbook   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 204
Duplicated Lines 0 %

Test Coverage

Coverage 96.59%

Importance

Changes 0
Metric Value
wmc 31
eloc 83
dl 0
loc 204
ccs 85
cts 88
cp 0.9659
rs 9.92
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
B writeWorkbookProtection() 0 17 7
A writeFileVersion() 0 8 1
A writeBookViews() 0 21 6
A writeWorkbookPr() 0 11 2
A writeWorkbook() 0 44 3
A writeSheets() 0 17 2
A writeCalcPr() 0 19 6
A writeSheet() 0 14 4
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx;
4
5
use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Namespaces;
6
use PhpOffice\PhpSpreadsheet\Shared\Date;
7
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
8
use PhpOffice\PhpSpreadsheet\Spreadsheet;
9
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
10
use PhpOffice\PhpSpreadsheet\Writer\Xlsx\DefinedNames as DefinedNamesWriter;
11
12
class Workbook extends WriterPart
13
{
14
    /**
15
     * Write workbook to XML format.
16
     *
17
     * @param bool $preCalculateFormulas If true, formulas will be calculated before writing
18
     * @param ?bool $forceFullCalc If null, !$preCalculateFormulas
19
     *
20
     * @return string XML Output
21
     */
22 393
    public function writeWorkbook(Spreadsheet $spreadsheet, bool $preCalculateFormulas = false, ?bool $forceFullCalc = null): string
23
    {
24
        // Create XML writer
25 393
        if ($this->getParentWriter()->getUseDiskCaching()) {
26
            $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
27
        } else {
28 393
            $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY);
29
        }
30
31
        // XML header
32 393
        $objWriter->startDocument('1.0', 'UTF-8', 'yes');
33
34
        // workbook
35 393
        $objWriter->startElement('workbook');
36 393
        $objWriter->writeAttribute('xmlns', Namespaces::MAIN);
37 393
        $objWriter->writeAttribute('xmlns:r', Namespaces::SCHEMA_OFFICE_DOCUMENT);
38
39
        // fileVersion
40 393
        $this->writeFileVersion($objWriter);
41
42
        // workbookPr
43 393
        $this->writeWorkbookPr($objWriter, $spreadsheet);
44
45
        // workbookProtection
46 393
        $this->writeWorkbookProtection($objWriter, $spreadsheet);
47
48
        // bookViews
49 393
        if ($this->getParentWriter()->getOffice2003Compatibility() === false) {
50 393
            $this->writeBookViews($objWriter, $spreadsheet);
51
        }
52
53
        // sheets
54 393
        $this->writeSheets($objWriter, $spreadsheet);
55
56
        // definedNames
57 393
        (new DefinedNamesWriter($objWriter, $spreadsheet))->write();
58
59
        // calcPr
60 393
        $this->writeCalcPr($objWriter, $preCalculateFormulas, $forceFullCalc);
61
62 393
        $objWriter->endElement();
63
64
        // Return
65 393
        return $objWriter->getData();
66
    }
67
68
    /**
69
     * Write file version.
70
     */
71 393
    private function writeFileVersion(XMLWriter $objWriter): void
72
    {
73 393
        $objWriter->startElement('fileVersion');
74 393
        $objWriter->writeAttribute('appName', 'xl');
75 393
        $objWriter->writeAttribute('lastEdited', '4');
76 393
        $objWriter->writeAttribute('lowestEdited', '4');
77 393
        $objWriter->writeAttribute('rupBuild', '4505');
78 393
        $objWriter->endElement();
79
    }
80
81
    /**
82
     * Write WorkbookPr.
83
     */
84 393
    private function writeWorkbookPr(XMLWriter $objWriter, Spreadsheet $spreadsheet): void
85
    {
86 393
        $objWriter->startElement('workbookPr');
87
88 393
        if ($spreadsheet->getExcelCalendar() === Date::CALENDAR_MAC_1904) {
89
            $objWriter->writeAttribute('date1904', '1');
90
        }
91
92 393
        $objWriter->writeAttribute('codeName', 'ThisWorkbook');
93
94 393
        $objWriter->endElement();
95
    }
96
97
    /**
98
     * Write BookViews.
99
     */
100 393
    private function writeBookViews(XMLWriter $objWriter, Spreadsheet $spreadsheet): void
101
    {
102
        // bookViews
103 393
        $objWriter->startElement('bookViews');
104
105
        // workbookView
106 393
        $objWriter->startElement('workbookView');
107
108 393
        $objWriter->writeAttribute('activeTab', (string) $spreadsheet->getActiveSheetIndex());
109 393
        $objWriter->writeAttribute('autoFilterDateGrouping', ($spreadsheet->getAutoFilterDateGrouping() ? 'true' : 'false'));
110 393
        $objWriter->writeAttribute('firstSheet', (string) $spreadsheet->getFirstSheetIndex());
111 393
        $objWriter->writeAttribute('minimized', ($spreadsheet->getMinimized() ? 'true' : 'false'));
112 393
        $objWriter->writeAttribute('showHorizontalScroll', ($spreadsheet->getShowHorizontalScroll() ? 'true' : 'false'));
113 393
        $objWriter->writeAttribute('showSheetTabs', ($spreadsheet->getShowSheetTabs() ? 'true' : 'false'));
114 393
        $objWriter->writeAttribute('showVerticalScroll', ($spreadsheet->getShowVerticalScroll() ? 'true' : 'false'));
115 393
        $objWriter->writeAttribute('tabRatio', (string) $spreadsheet->getTabRatio());
116 393
        $objWriter->writeAttribute('visibility', $spreadsheet->getVisibility());
117
118 393
        $objWriter->endElement();
119
120 393
        $objWriter->endElement();
121
    }
122
123
    /**
124
     * Write WorkbookProtection.
125
     */
126 393
    private function writeWorkbookProtection(XMLWriter $objWriter, Spreadsheet $spreadsheet): void
127
    {
128 393
        if ($spreadsheet->getSecurity()->isSecurityEnabled()) {
129 11
            $objWriter->startElement('workbookProtection');
130 11
            $objWriter->writeAttribute('lockRevision', ($spreadsheet->getSecurity()->getLockRevision() ? 'true' : 'false'));
131 11
            $objWriter->writeAttribute('lockStructure', ($spreadsheet->getSecurity()->getLockStructure() ? 'true' : 'false'));
132 11
            $objWriter->writeAttribute('lockWindows', ($spreadsheet->getSecurity()->getLockWindows() ? 'true' : 'false'));
133
134 11
            if ($spreadsheet->getSecurity()->getRevisionsPassword() != '') {
135 1
                $objWriter->writeAttribute('revisionsPassword', $spreadsheet->getSecurity()->getRevisionsPassword());
136
            }
137
138 11
            if ($spreadsheet->getSecurity()->getWorkbookPassword() != '') {
139 4
                $objWriter->writeAttribute('workbookPassword', $spreadsheet->getSecurity()->getWorkbookPassword());
140
            }
141
142 11
            $objWriter->endElement();
143
        }
144
    }
145
146
    /**
147
     * Write calcPr.
148
     *
149
     * @param bool $preCalculateFormulas If true, formulas will be calculated before writing
150
     */
151 393
    private function writeCalcPr(XMLWriter $objWriter, bool $preCalculateFormulas, ?bool $forceFullCalc): void
152
    {
153 393
        $objWriter->startElement('calcPr');
154
155
        //    Set the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc
156
        //  If MS Excel does do a recalc, then users opening a file in MS Excel will be prompted to save on exit
157
        //     because the file has changed
158 393
        $objWriter->writeAttribute('calcId', '999999');
159 393
        $objWriter->writeAttribute('calcMode', 'auto');
160
        //    fullCalcOnLoad isn't needed if we will calculate before writing
161 393
        $objWriter->writeAttribute('calcCompleted', ($preCalculateFormulas) ? '1' : '0');
162 393
        $objWriter->writeAttribute('fullCalcOnLoad', ($preCalculateFormulas) ? '0' : '1');
163 393
        if ($forceFullCalc === null) {
164 3
            $objWriter->writeAttribute('forceFullCalc', $preCalculateFormulas ? '0' : '1');
165
        } else {
166 390
            $objWriter->writeAttribute('forceFullCalc', $forceFullCalc ? '1' : '0');
167
        }
168
169 393
        $objWriter->endElement();
170
    }
171
172
    /**
173
     * Write sheets.
174
     */
175 393
    private function writeSheets(XMLWriter $objWriter, Spreadsheet $spreadsheet): void
176
    {
177
        // Write sheets
178 393
        $objWriter->startElement('sheets');
179 393
        $sheetCount = $spreadsheet->getSheetCount();
180 393
        for ($i = 0; $i < $sheetCount; ++$i) {
181
            // sheet
182 393
            $this->writeSheet(
183 393
                $objWriter,
184 393
                $spreadsheet->getSheet($i)->getTitle(),
185 393
                ($i + 1),
186 393
                ($i + 1 + 3),
187 393
                $spreadsheet->getSheet($i)->getSheetState()
188 393
            );
189
        }
190
191 393
        $objWriter->endElement();
192
    }
193
194
    /**
195
     * Write sheet.
196
     *
197
     * @param string $worksheetName Sheet name
198
     * @param int $worksheetId Sheet id
199
     * @param int $relId Relationship ID
200
     * @param string $sheetState Sheet state (visible, hidden, veryHidden)
201
     */
202 393
    private function writeSheet(XMLWriter $objWriter, string $worksheetName, int $worksheetId = 1, int $relId = 1, string $sheetState = 'visible'): void
203
    {
204 393
        if ($worksheetName != '') {
205
            // Write sheet
206 393
            $objWriter->startElement('sheet');
207 393
            $objWriter->writeAttribute('name', $worksheetName);
208 393
            $objWriter->writeAttribute('sheetId', (string) $worksheetId);
209 393
            if ($sheetState !== 'visible' && $sheetState != '') {
210 4
                $objWriter->writeAttribute('state', $sheetState);
211
            }
212 393
            $objWriter->writeAttribute('r:id', 'rId' . $relId);
213 393
            $objWriter->endElement();
214
        } else {
215
            throw new WriterException('Invalid parameters passed.');
216
        }
217
    }
218
}
219