diff --git a/README.md b/README.md index e9baf19..dd99e89 100644 --- a/README.md +++ b/README.md @@ -270,7 +270,6 @@ $excel->save('simple.xlsx'); ``` - ### Adding Notes There are currently two types of comments in Excel - **comments** and **notes** @@ -280,17 +279,17 @@ You can add notes to any cells using method ```addNote()``` ```php -$sheet1->writeCell('Text to A1'); -$sheet1->addNote('A1', 'This is a note for cell A1'); +$sheet->writeCell('Text to A1'); +$sheet->addNote('A1', 'This is a note for cell A1'); -$sheet1->writeCell('Text to B1')->addNote('This is a note for B1'); -$sheet1->writeTo('C4', 'Text to C4')->addNote('Note for C1'); +$sheet->writeCell('Text to B1')->addNote('This is a note for B1'); +$sheet->writeTo('C4', 'Text to C4')->addNote('Note for C1'); // If you specify a range of cells, then the note will be added to the left top cell -$sheet1->addNote('E4:F8', "This note\nwill added to E4"); +$sheet->addNote('E4:F8', "This note\nwill added to E4"); // You can split text into multiple lines -$sheet1->addNote('D7', "Line 1\nLine 2"); +$sheet->addNote('D7', "Line 1\nLine 2"); ``` @@ -302,7 +301,7 @@ You can change some note options. Allowed options of a note are: ```php -$sheet1->addNote('A1', 'This is a note for cell A1', ['width' => '200pt', 'height' => '100pt', 'fill_color' => '#ffcccc']); +$sheet->addNote('A1', 'This is a note for cell A1', ['width' => '200pt', 'height' => '100pt', 'fill_color' => '#ffcccc']); // Parameters "width" and "height" can be numeric, by default these values are in points // The "fill_color" parameter can be shortened @@ -311,17 +310,17 @@ $noteStyle = [ 'height' => 100, // equivalent to '100pt' 'fill_color' => 'fcc', // equivalent to '#ffcccc' ]; -$sheet1->writeCell('Text to B1')->addNote('This is a note for B1', $noteStyle); +$sheet->writeCell('Text to B1')->addNote('This is a note for B1', $noteStyle); // This note is visible when the Excel workbook is displayed -$sheet1->addNote('C8', 'This note is always visible', ['show' => true]); +$sheet->addNote('C8', 'This note is always visible', ['show' => true]); ``` Also, you can use rich text in notes ```php $richText = new \avadim\FastExcelWriter\RichText('here is red and blue text'); -$sheet1->addNote('C8', $richText); +$sheet->addNote('C8', $richText); ``` For more information on using rich text, see here: [Using Rich Text](/docs/03-writing.md#using-rich-text) @@ -331,29 +330,40 @@ For more information on using rich text, see here: [Using Rich Text](/docs/03-wr You can insert image to sheet from local file, URL or image string in base64 ```php +$sheet->addImage($cell, $imageFile, $imageStyle); + // Insert an image to the cell A1 from local path -$sheet1->addImage('A1', 'path/to/file'); +$sheet->addImage('A1', 'path/to/file'); // Insert an image to the cell A1 from URL -$sheet1->addImage('A1', 'https://site.com/image.jpg'); +$sheet->addImage('A1', 'https://site.com/image.jpg'); // Insert an image to the cell A1 from base64 string -$sheet1->addImage('A1', 'data:image/jpeg;base64,/9j/4AAQ...'); +$sheet->addImage('A1', 'data:image/jpeg;base64,/9j/4AAQ...'); // Insert an image to the cell B2 and set with to 150 pixels (height will change proportionally) -$sheet1->addImage('B2', 'path/to/file', ['width' => 150]); +$sheet->addImage('B2', 'path/to/file', ['width' => 150]); // Set height to 150 pixels (with will change proportionally) -$sheet1->addImage('C3', 'path/to/file', ['height' => 150]); +$sheet->addImage('C3', 'path/to/file', ['height' => 150]); // Set size in pixels -$sheet1->addImage('D4', 'path/to/file', ['width' => 150, 'height' => 150]); +$sheet->addImage('D4', 'path/to/file', ['width' => 150, 'height' => 150]); // Add hyperlink to the image -$sheet1->addImage('D4', 'path/to/file', ['width' => 150, 'height' => 150, 'hyperlink' => 'https://www.google.com/']); - +$sheet->addImage('D4', 'path/to/file', ['width' => 150, 'height' => 150, 'hyperlink' => 'https://www.google.com/']); ``` +Available keys of image style: +* 'width' -- width of image +* 'height' -- height of image +* 'hyperlink' -- URL of hyperlink +* 'x' -- offset in pixels relative to the left border of the cell +* 'y' -- offset in pixels relative to the top border of the cell + +**IMPORTANT:** in MS Excel, value 'x' cannot be greater than the column width of the parent cell, +and value 'y' cannot be greater than the row height + ## Shared Strings By default, strings are written directly to sheets. This increases the file size a little, diff --git a/composer.json b/composer.json index e816d4b..88d65d3 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ "require-dev": { "phpunit/phpunit": "^9.0", "ext-fileinfo": "*", - "avadim/fast-excel-reader": "^2.19" + "avadim/fast-excel-reader": "^2.22" }, "scripts": { "test": "vendor/bin/phpunit tests" diff --git a/src/FastExcelWriter/Sheet.php b/src/FastExcelWriter/Sheet.php index cec9ee3..418ab24 100644 --- a/src/FastExcelWriter/Sheet.php +++ b/src/FastExcelWriter/Sheet.php @@ -2744,9 +2744,6 @@ protected function _setCellData($cellAddress, $value, $styles = null, ?bool $mer } if ($value !== null) { - if (is_callable($value)) { - $value = $value($this); - } if (is_scalar($value) || ($value instanceof RichText) // it's a formula & value ['=A1+B2', 123] @@ -2754,9 +2751,12 @@ protected function _setCellData($cellAddress, $value, $styles = null, ?bool $mer ) { $this->cells['values'][$rowIdx][$colIdx] = $value; } + elseif (is_callable($value)) { + $this->cells['values'][$rowIdx][$colIdx] = $value($this); + } else { $addr = Excel::cellAddress($colIdx + 1, $rowIdx + 1); - Exception::throwNew('Value for cell %s must be scalar', $addr); + Exception::throwNew('Value for cell %s must be scalar or callable', $addr); } if ($changeCurrent) { $this->currentRowIdx = $rowIdx; @@ -3516,6 +3516,8 @@ public function addImage(string $cell, string $imageFile, ?array $imageStyle = [ $imageData['cell'] = $cell; $imageData['row_index'] = $rowIdx; $imageData['col_index'] = $colIdx; + $imageData['x'] = $imageStyle['x'] ?? 0; + $imageData['y'] = $imageStyle['y'] ?? 0; if (!empty($imageStyle['width']) || !empty($imageStyle['height'])) { if (!empty($imageStyle['width']) && empty($imageStyle['height'])) { $ratio = $imageStyle['width'] / $imageData['width']; diff --git a/src/FastExcelWriter/Writer/Writer.php b/src/FastExcelWriter/Writer/Writer.php index 39dd399..f2d4931 100644 --- a/src/FastExcelWriter/Writer/Writer.php +++ b/src/FastExcelWriter/Writer/Writer.php @@ -898,6 +898,8 @@ protected function _writeDrawingFile(string $entry, array $imageList, array $cha $objectId = $image['id']; $rId = $image['r_id']; $baseName = $image['original']; + $x = Excel::pixelsToEMU($image['x']); + $y = Excel::pixelsToEMU($image['y']); $width = Excel::pixelsToEMU($image['width']); $height = Excel::pixelsToEMU($image['height']); @@ -905,9 +907,9 @@ protected function _writeDrawingFile(string $entry, array $imageList, array $cha $fileWriter->startElement('xdr:from'); $fileWriter->writeElement("{$image['col_index']}"); - $fileWriter->writeElement('0'); + $fileWriter->writeElement("{$x}"); $fileWriter->writeElement("{$image['row_index']}"); - $fileWriter->writeElement('0'); + $fileWriter->writeElement("{$y}"); $fileWriter->endElement(); $fileWriter->writeElement(""); @@ -940,7 +942,14 @@ protected function _writeDrawingFile(string $entry, array $imageList, array $cha $fileWriter->startElement('xdr:spPr'); $fileWriter->writeElement(""); - $fileWriter->endElement(); + /* !! + $fileWriter->startElement('a:xfrm'); + $fileWriter->writeElement(""); + $fileWriter->writeElement(""); + $fileWriter->endElement(); // + $fileWriter->writeElement(""); + */ + $fileWriter->endElement(); // $fileWriter->endElement(); diff --git a/tests/FastExcelWriterTest.php b/tests/FastExcelWriterTest.php index e9f3e10..5aaf521 100644 --- a/tests/FastExcelWriterTest.php +++ b/tests/FastExcelWriterTest.php @@ -23,6 +23,7 @@ protected function getValue($cell) return $this->cells[$m[2]][$m[1]]['v'] ?? null; } + protected function getValues($cells): array { $result = []; @@ -33,6 +34,7 @@ protected function getValues($cells): array return $result; } + protected function getStyle($cell, $flat = false): array { preg_match('/^(\w+)(\d+)$/', strtoupper($cell), $m); @@ -55,6 +57,7 @@ protected function getStyle($cell, $flat = false): array return []; } + protected function defaultStyle(): array { return [ @@ -127,10 +130,12 @@ public function testExcelWriter0() ->writeCell('A1') ->writeCell('B1') ->nextCell() // C1 - ->writeCell('D1') + ->writeCell(fn($sheet) => $sheet->getCurrentCell()) // D1 ->nextCell() // E1 ->nextCell() // F1 - ->writeCell('G1') + ->writeCell(function($sheet) { + return $sheet->getCurrentCol() . $sheet->getCurrentRow(); + }) // G1 ->writeTo('F1', 'F1'); ; // write row 2 go to row 3 @@ -283,7 +288,8 @@ public function testExcelWriter1() $this->cells = []; } - protected function makeTestFile2($testFileName) + + protected function makeTestFile2($testFileName): ExcelReader { // PREPARE DEMO DATA $lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua'; @@ -398,6 +404,7 @@ protected function makeTestFile2($testFileName) return $this->saveCheckRead($excel, $testFileName); } + public function testExcelWriter2() { $testFileName = __DIR__ . '/test2.xlsx'; @@ -541,6 +548,7 @@ public function testExcelWriter3() unlink($testFileName); } + public function testExcelWriter4() { $testFileName = __DIR__ . '/test4.xlsx'; @@ -589,6 +597,7 @@ public function testExcelWriter4() unlink($testFileName); } + public function testExcelWriter5() { $testFileName = __DIR__ . '/test5.xlsx'; @@ -606,8 +615,8 @@ public function testExcelWriter5() $sheet->writeRow([1, 11, 111])->applyFontStyleBold(); $sheet->writeRow([2, 22, 222]); $sheet->writeCell(3); - $sheet->writeCell(33); - $sheet->writeCell(333); + $sheet->writeCell('33'); + $sheet->writeCell(333.3); $sheet = $excel->sheet('Demo2'); $sheet->writeHeader(['AAA', 'BBB', 'CCC'])->applyFontStyleBold(); @@ -618,7 +627,10 @@ public function testExcelWriter5() $this->assertEquals([1, 11, 111], $this->getValues(['c3', 'd3', 'e3'])); $this->assertEquals([2, 22, 222], $this->getValues(['c4', 'd4', 'e4'])); - $this->assertEquals([3, 33, 333], $this->getValues(['c5', 'd5', 'e5'])); + + $this->assertTrue(3 === $this->getValue('c5')); + $this->assertTrue('33' === $this->getValue('d5')); + $this->assertTrue(333.3 === $this->getValue('e5')); $cells = $this->excelReader->sheet('Demo2')->readCellsWithStyles(); $this->assertEquals('Century', $cells['A1']['s']['font']['font-name']); @@ -626,6 +638,7 @@ public function testExcelWriter5() unlink($testFileName); } + public function testExcelWriterMergedCells() { $testFileName = __DIR__ . '/test_merged.xlsx'; @@ -669,6 +682,7 @@ public function testExcelWriterMergedCells() unlink($testFileName); } + public function testExcelWriterNotesAndImages() { $testFileName = __DIR__ . '/test_notes_images.xlsx'; @@ -730,6 +744,7 @@ public function testExcelWriterNotesAndImages() unlink($testFileName); } + public function testExcelWriterSingleValue() { $testFileName = __DIR__ . '/test_single.xlsx'; @@ -770,6 +785,7 @@ public function testExcelWriterSingleValue() unlink($testFileName); } + public function testCharts() { $testFileName = __DIR__ . '/test_charts.xlsx';