PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.7.1
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.7.1
4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 All 149 releases
visualizer / vendor / phpoffice / phpspreadsheet / src / PhpSpreadsheet / Shared / Xls.php

Xls.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.7.1, at vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Xls.php

284 lines 11.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace PhpOffice\PhpSpreadsheet\Shared;
4
5 use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
6 use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
7
8 class Xls
9 {
10 /**
11 * Get the width of a column in pixels. We use the relationship y = ceil(7x) where
12 * x is the width in intrinsic Excel units (measuring width in number of normal characters)
13 * This holds for Arial 10.
14 *
15 * @param Worksheet $sheet The sheet
16 * @param string $col The column
17 *
18 * @return int The width in pixels
19 */
20 public static function sizeCol($sheet, $col = 'A')
21 {
22 // default font of the workbook
23 $font = $sheet->getParent()->getDefaultStyle()->getFont();
24
25 $columnDimensions = $sheet->getColumnDimensions();
26
27 // first find the true column width in pixels (uncollapsed and unhidden)
28 if (isset($columnDimensions[$col]) and $columnDimensions[$col]->getWidth() != -1) {
29 // then we have column dimension with explicit width
30 $columnDimension = $columnDimensions[$col];
31 $width = $columnDimension->getWidth();
32 $pixelWidth = Drawing::cellDimensionToPixels($width, $font);
33 } elseif ($sheet->getDefaultColumnDimension()->getWidth() != -1) {
34 // then we have default column dimension with explicit width
35 $defaultColumnDimension = $sheet->getDefaultColumnDimension();
36 $width = $defaultColumnDimension->getWidth();
37 $pixelWidth = Drawing::cellDimensionToPixels($width, $font);
38 } else {
39 // we don't even have any default column dimension. Width depends on default font
40 $pixelWidth = Font::getDefaultColumnWidthByFont($font, true);
41 }
42
43 // now find the effective column width in pixels
44 if (isset($columnDimensions[$col]) and !$columnDimensions[$col]->getVisible()) {
45 $effectivePixelWidth = 0;
46 } else {
47 $effectivePixelWidth = $pixelWidth;
48 }
49
50 return $effectivePixelWidth;
51 }
52
53 /**
54 * Convert the height of a cell from user's units to pixels. By interpolation
55 * the relationship is: y = 4/3x. If the height hasn't been set by the user we
56 * use the default value. If the row is hidden we use a value of zero.
57 *
58 * @param Worksheet $sheet The sheet
59 * @param int $row The row index (1-based)
60 *
61 * @return int The width in pixels
62 */
63 public static function sizeRow($sheet, $row = 1)
64 {
65 // default font of the workbook
66 $font = $sheet->getParent()->getDefaultStyle()->getFont();
67
68 $rowDimensions = $sheet->getRowDimensions();
69
70 // first find the true row height in pixels (uncollapsed and unhidden)
71 if (isset($rowDimensions[$row]) and $rowDimensions[$row]->getRowHeight() != -1) {
72 // then we have a row dimension
73 $rowDimension = $rowDimensions[$row];
74 $rowHeight = $rowDimension->getRowHeight();
75 $pixelRowHeight = (int) ceil(4 * $rowHeight / 3); // here we assume Arial 10
76 } elseif ($sheet->getDefaultRowDimension()->getRowHeight() != -1) {
77 // then we have a default row dimension with explicit height
78 $defaultRowDimension = $sheet->getDefaultRowDimension();
79 $rowHeight = $defaultRowDimension->getRowHeight();
80 $pixelRowHeight = Drawing::pointsToPixels($rowHeight);
81 } else {
82 // we don't even have any default row dimension. Height depends on default font
83 $pointRowHeight = Font::getDefaultRowHeightByFont($font);
84 $pixelRowHeight = Font::fontSizeToPixels($pointRowHeight);
85 }
86
87 // now find the effective row height in pixels
88 if (isset($rowDimensions[$row]) and !$rowDimensions[$row]->getVisible()) {
89 $effectivePixelRowHeight = 0;
90 } else {
91 $effectivePixelRowHeight = $pixelRowHeight;
92 }
93
94 return $effectivePixelRowHeight;
95 }
96
97 /**
98 * Get the horizontal distance in pixels between two anchors
99 * The distanceX is found as sum of all the spanning columns widths minus correction for the two offsets.
100 *
101 * @param Worksheet $sheet
102 * @param string $startColumn
103 * @param int $startOffsetX Offset within start cell measured in 1/1024 of the cell width
104 * @param string $endColumn
105 * @param int $endOffsetX Offset within end cell measured in 1/1024 of the cell width
106 *
107 * @return int Horizontal measured in pixels
108 */
109 public static function getDistanceX(Worksheet $sheet, $startColumn = 'A', $startOffsetX = 0, $endColumn = 'A', $endOffsetX = 0)
110 {
111 $distanceX = 0;
112
113 // add the widths of the spanning columns
114 $startColumnIndex = Coordinate::columnIndexFromString($startColumn);
115 $endColumnIndex = Coordinate::columnIndexFromString($endColumn);
116 for ($i = $startColumnIndex; $i <= $endColumnIndex; ++$i) {
117 $distanceX += self::sizeCol($sheet, Coordinate::stringFromColumnIndex($i));
118 }
119
120 // correct for offsetX in startcell
121 $distanceX -= (int) floor(self::sizeCol($sheet, $startColumn) * $startOffsetX / 1024);
122
123 // correct for offsetX in endcell
124 $distanceX -= (int) floor(self::sizeCol($sheet, $endColumn) * (1 - $endOffsetX / 1024));
125
126 return $distanceX;
127 }
128
129 /**
130 * Get the vertical distance in pixels between two anchors
131 * The distanceY is found as sum of all the spanning rows minus two offsets.
132 *
133 * @param Worksheet $sheet
134 * @param int $startRow (1-based)
135 * @param int $startOffsetY Offset within start cell measured in 1/256 of the cell height
136 * @param int $endRow (1-based)
137 * @param int $endOffsetY Offset within end cell measured in 1/256 of the cell height
138 *
139 * @return int Vertical distance measured in pixels
140 */
141 public static function getDistanceY(Worksheet $sheet, $startRow = 1, $startOffsetY = 0, $endRow = 1, $endOffsetY = 0)
142 {
143 $distanceY = 0;
144
145 // add the widths of the spanning rows
146 for ($row = $startRow; $row <= $endRow; ++$row) {
147 $distanceY += self::sizeRow($sheet, $row);
148 }
149
150 // correct for offsetX in startcell
151 $distanceY -= (int) floor(self::sizeRow($sheet, $startRow) * $startOffsetY / 256);
152
153 // correct for offsetX in endcell
154 $distanceY -= (int) floor(self::sizeRow($sheet, $endRow) * (1 - $endOffsetY / 256));
155
156 return $distanceY;
157 }
158
159 /**
160 * Convert 1-cell anchor coordinates to 2-cell anchor coordinates
161 * This function is ported from PEAR Spreadsheet_Writer_Excel with small modifications.
162 *
163 * Calculate the vertices that define the position of the image as required by
164 * the OBJ record.
165 *
166 * +------------+------------+
167 * | A | B |
168 * +-----+------------+------------+
169 * | |(x1,y1) | |
170 * | 1 |(A1)._______|______ |
171 * | | | | |
172 * | | | | |
173 * +-----+----| BITMAP |-----+
174 * | | | | |
175 * | 2 | |______________. |
176 * | | | (B2)|
177 * | | | (x2,y2)|
178 * +---- +------------+------------+
179 *
180 * Example of a bitmap that covers some of the area from cell A1 to cell B2.
181 *
182 * Based on the width and height of the bitmap we need to calculate 8 vars:
183 * $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2.
184 * The width and height of the cells are also variable and have to be taken into
185 * account.
186 * The values of $col_start and $row_start are passed in from the calling
187 * function. The values of $col_end and $row_end are calculated by subtracting
188 * the width and height of the bitmap from the width and height of the
189 * underlying cells.
190 * The vertices are expressed as a percentage of the underlying cell width as
191 * follows (rhs values are in pixels):
192 *
193 * x1 = X / W *1024
194 * y1 = Y / H *256
195 * x2 = (X-1) / W *1024
196 * y2 = (Y-1) / H *256
197 *
198 * Where: X is distance from the left side of the underlying cell
199 * Y is distance from the top of the underlying cell
200 * W is the width of the cell
201 * H is the height of the cell
202 *
203 * @param Worksheet $sheet
204 * @param string $coordinates E.g. 'A1'
205 * @param int $offsetX Horizontal offset in pixels
206 * @param int $offsetY Vertical offset in pixels
207 * @param int $width Width in pixels
208 * @param int $height Height in pixels
209 *
210 * @return array
211 */
212 public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height)
213 {
214 list($column, $row) = Coordinate::coordinateFromString($coordinates);
215 $col_start = Coordinate::columnIndexFromString($column);
216 $row_start = $row - 1;
217
218 $x1 = $offsetX;
219 $y1 = $offsetY;
220
221 // Initialise end cell to the same as the start cell
222 $col_end = $col_start; // Col containing lower right corner of object
223 $row_end = $row_start; // Row containing bottom right corner of object
224
225 // Zero the specified offset if greater than the cell dimensions
226 if ($x1 >= self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_start))) {
227 $x1 = 0;
228 }
229 if ($y1 >= self::sizeRow($sheet, $row_start + 1)) {
230 $y1 = 0;
231 }
232
233 $width = $width + $x1 - 1;
234 $height = $height + $y1 - 1;
235
236 // Subtract the underlying cell widths to find the end cell of the image
237 while ($width >= self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_end))) {
238 $width -= self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_end));
239 ++$col_end;
240 }
241
242 // Subtract the underlying cell heights to find the end cell of the image
243 while ($height >= self::sizeRow($sheet, $row_end + 1)) {
244 $height -= self::sizeRow($sheet, $row_end + 1);
245 ++$row_end;
246 }
247
248 // Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell
249 // with zero height or width.
250 if (self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_start)) == 0) {
251 return;
252 }
253 if (self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_end)) == 0) {
254 return;
255 }
256 if (self::sizeRow($sheet, $row_start + 1) == 0) {
257 return;
258 }
259 if (self::sizeRow($sheet, $row_end + 1) == 0) {
260 return;
261 }
262
263 // Convert the pixel values to the percentage value expected by Excel
264 $x1 = $x1 / self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_start)) * 1024;
265 $y1 = $y1 / self::sizeRow($sheet, $row_start + 1) * 256;
266 $x2 = ($width + 1) / self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_end)) * 1024; // Distance to right side of object
267 $y2 = ($height + 1) / self::sizeRow($sheet, $row_end + 1) * 256; // Distance to bottom of object
268
269 $startCoordinates = Coordinate::stringFromColumnIndex($col_start) . ($row_start + 1);
270 $endCoordinates = Coordinate::stringFromColumnIndex($col_end) . ($row_end + 1);
271
272 $twoAnchor = [
273 'startCoordinates' => $startCoordinates,
274 'startOffsetX' => $x1,
275 'startOffsetY' => $y1,
276 'endCoordinates' => $endCoordinates,
277 'endOffsetX' => $x2,
278 'endOffsetY' => $y2,
279 ];
280
281 return $twoAnchor;
282 }
283 }
284