Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/PHPOffice/PhpSpreadsheet/llms.txt

Use this file to discover all available pages before exploring further.

Introduction

PhpSpreadsheet allows you to add images and drawings to worksheets. You can insert images from files, URLs, or create in-memory images using GD.

Adding Images from Files

Basic Image Insertion

use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;

$drawing = new Drawing();
$drawing->setName('Logo');
$drawing->setDescription('Company Logo');
$drawing->setPath('./images/logo.jpg');
$drawing->setHeight(36);
$drawing->setWorksheet($spreadsheet->getActiveSheet());

Positioning Images

Cell Coordinates

Position an image at a specific cell:
$drawing->setCoordinates('B15');

Offsets

Add pixel offsets to fine-tune positioning:
$drawing->setCoordinates('B15');
$drawing->setOffsetX(110);  // Horizontal offset in pixels
$drawing->setOffsetY(20);   // Vertical offset in pixels

Complete Example

use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;

$drawing = new Drawing();
$drawing->setName('Paid Stamp');
$drawing->setDescription('Paid stamp image');
$drawing->setPath('./images/paid.png');
$drawing->setCoordinates('B15');
$drawing->setOffsetX(110);
$drawing->setOffsetY(10);
$drawing->setHeight(50);
$drawing->setWorksheet($spreadsheet->getActiveSheet());

Image Properties

Size and Dimensions

// Set height (width adjusts proportionally)
$drawing->setHeight(100);

// Set width (height adjusts proportionally)
$drawing->setWidth(200);

// Set both dimensions (may distort image)
$drawing->setWidth(200);
$drawing->setHeight(100);

Rotation

// Rotate image (degrees)
$drawing->setRotation(25);

Shadow Effects

$drawing->getShadow()->setVisible(true);
$drawing->getShadow()->setDirection(45);
$drawing->getShadow()->setDistance(10);

In-Memory Images (GD)

Creating Images with GD

Create images dynamically without saving to disk:
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;

// Create an image using GD
$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot initialize GD image');
$textColor = imagecolorallocate($gdImage, 255, 255, 255);
imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor);

// Add the in-memory image to worksheet
$drawing = new MemoryDrawing();
$drawing->setName('In-Memory Image');
$drawing->setDescription('Dynamically created image');
$drawing->setCoordinates('A1');
$drawing->setImageResource($gdImage);
$drawing->setRenderingFunction(
    MemoryDrawing::RENDERING_JPEG
);
$drawing->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT);
$drawing->setHeight(36);
$drawing->setWorksheet($spreadsheet->getActiveSheet());
GD images are memory-intensive. Use them sparingly in production environments.

Rendering Functions

Available rendering functions for MemoryDrawing:
MemoryDrawing::RENDERING_DEFAULT  // PNG
MemoryDrawing::RENDERING_PNG      // PNG
MemoryDrawing::RENDERING_GIF      // GIF
MemoryDrawing::RENDERING_JPEG     // JPEG

Creating Images from Strings or Streams

From String Data

Create a drawing from binary image data:
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;

$imageString = file_get_contents('path/to/image.png');
$drawing = MemoryDrawing::fromString($imageString);
$drawing->setWorksheet($spreadsheet->getActiveSheet());

From Stream

Create a drawing from a stream (e.g., S3 bucket):
$imageStream = fopen('s3://bucket/image.png', 'r');
$drawing = MemoryDrawing::fromStream($imageStream);
$drawing->setWorksheet($spreadsheet->getActiveSheet());
Both methods create temporary files and are memory-intensive processes.

Reading Images from Worksheets

Extracting Images

Extract all images from a worksheet and save them:
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;

$i = 0;

foreach ($spreadsheet->getActiveSheet()->getDrawingCollection() as $drawing) {
    if ($drawing instanceof MemoryDrawing) {
        // Handle in-memory images
        ob_start();
        call_user_func(
            $drawing->getRenderingFunction(),
            $drawing->getImageResource()
        );
        $imageContents = ob_get_contents();
        ob_end_clean();
        
        switch ($drawing->getMimeType()) {
            case MemoryDrawing::MIMETYPE_PNG:
                $extension = 'png';
                break;
            case MemoryDrawing::MIMETYPE_GIF:
                $extension = 'gif';
                break;
            case MemoryDrawing::MIMETYPE_JPEG:
                $extension = 'jpg';
                break;
        }
    } else {
        // Handle file-based images
        if ($drawing->getPath()) {
            $zipReader = fopen($drawing->getPath(), 'r');
            $imageContents = '';
            while (!feof($zipReader)) {
                $imageContents .= fread($zipReader, 1024);
            }
            fclose($zipReader);
            $extension = $drawing->getExtension();
        }
    }
    
    $filename = '00_Image_' . ++$i . '.' . $extension;
    file_put_contents($filename, $imageContents);
}

Image Anchoring

Move and Size with Cells

Control how images behave when rows/columns are resized:
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;

$drawing = new Drawing();
$drawing->setPath('./images/logo.png');
$drawing->setCoordinates('B2');

// Options:
// 1. Move and size with cells
$drawing->setResizeProportional(true);

// 2. Move but don't size with cells (default)
$drawing->setResizeProportional(false);

// 3. Don't move or size with cells
$drawing->setEditAs(Drawing::EDIT_AS_ABSOLUTE);

$drawing->setWorksheet($spreadsheet->getActiveSheet());

Header/Footer Images

Adding Images to Headers/Footers

Images can be added to worksheet headers and footers (Xlsx only):
use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing;
use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooter;

$drawing = new HeaderFooterDrawing();
$drawing->setName('Logo');
$drawing->setPath('./images/logo.png');
$drawing->setHeight(36);

$spreadsheet->getActiveSheet()
    ->getHeaderFooter()
    ->addImage(
        $drawing,
        HeaderFooter::IMAGE_HEADER_LEFT
    );

Header/Footer Positions

Available positions:
HeaderFooter::IMAGE_HEADER_LEFT
HeaderFooter::IMAGE_HEADER_CENTER
HeaderFooter::IMAGE_HEADER_RIGHT
HeaderFooter::IMAGE_FOOTER_LEFT
HeaderFooter::IMAGE_FOOTER_CENTER
HeaderFooter::IMAGE_FOOTER_RIGHT
To use different images on first or even pages, call setDifferentFirst(true) or setDifferentOddEven(true) on the HeaderFooter object.

Image Formats

Supported Formats

PhpSpreadsheet supports these image formats:
  • JPEG/JPG - Joint Photographic Experts Group
  • PNG - Portable Network Graphics
  • GIF - Graphics Interchange Format
  • BMP - Bitmap

Format Recommendations

FormatBest For
PNGLogos, icons, images with transparency
JPEGPhotographs, complex images
GIFSimple graphics, animations
BMPUncompressed images (larger file size)
Add clickable hyperlinks to images (Xlsx only):
$drawing = new Drawing();
$drawing->setPath('./images/logo.png');
$drawing->setCoordinates('A1');
$drawing->setHyperlink(
    new \PhpOffice\PhpSpreadsheet\Cell\Hyperlink(
        'https://www.example.com',
        'Visit our website'
    )
);
$drawing->setWorksheet($spreadsheet->getActiveSheet());

Best Practices

Resize images before adding them to reduce file size and improve performance.
Choose the right format: PNG for logos, JPEG for photos, to balance quality and file size.
Use meaningful names and descriptions for accessibility and debugging.
In-memory images using GD are memory-intensive. Use sparingly in production.
Position images to avoid overlapping with data or other objects.

Complete Example

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;

$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();

// Add file-based image
$logo = new Drawing();
$logo->setName('Company Logo');
$logo->setDescription('Logo');
$logo->setPath('./images/logo.png');
$logo->setCoordinates('A1');
$logo->setHeight(50);
$logo->setWorksheet($worksheet);

// Add GD-based image
$gdImage = imagecreatetruecolor(200, 50);
$bgColor = imagecolorallocate($gdImage, 255, 255, 255);
$textColor = imagecolorallocate($gdImage, 0, 0, 0);
imagefill($gdImage, 0, 0, $bgColor);
imagestring($gdImage, 5, 10, 15, 'Generated Image', $textColor);

$generated = new MemoryDrawing();
$generated->setName('Generated');
$generated->setDescription('Generated image');
$generated->setCoordinates('A3');
$generated->setImageResource($gdImage);
$generated->setRenderingFunction(MemoryDrawing::RENDERING_PNG);
$generated->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT);
$generated->setHeight(50);
$generated->setWorksheet($worksheet);

// Save
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('images.xlsx');

Build docs developers (and LLMs) love