PHPOffice/PhpSpreadsheet · error · PhpOffice\PhpSpreadsheet\Writer\Exception

Couldn't import $bitmap

Error message

Couldn't import $bitmap

What it means

Writer\Xls\Worksheet::processBitmap() - reached via the deprecated insertBitmap() - opens the given path with fopen('rb'). If the open fails (file missing, unreadable, or path invalid) or the file is exactly 0 bytes, this exception aborts the operation. It is the pre-check before any BMP header parsing happens.

Source

Thrown at src/PhpSpreadsheet/Writer/Xls/Worksheet.php:2465

    /**
     * Convert a 24 bit bitmap into the modified internal format used by Windows.
     * This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the
     * MSDN library.
     *
     * @deprecated 5.5.0 No replacement.
     *
     * @param string $bitmap The bitmap to process
     *
     * @return array{0: int, 1: int, 2: int, 3: string} Data and properties of the bitmap
     *
     * @codeCoverageIgnore
     */
    public function processBitmap(string $bitmap): array
    {
        // Open file.
        $bmp_fd = @fopen($bitmap, 'rb');
        if ($bmp_fd === false || 0 === (int) filesize($bitmap)) {
            throw new WriterException("Couldn't import $bitmap");
        }

        // Slurp the file into a string.
        $data = (string) fread($bmp_fd, (int) filesize($bitmap));

        // Check that the file is big enough to be a bitmap.
        if (strlen($data) <= 0x36) {
            throw new WriterException("$bitmap doesn't contain enough data.\n");
        }

        // The first 2 bytes are used to identify the bitmap.

        $identity = unpack('A2ident', $data);
        if ($identity === false || $identity['ident'] != 'BM') {
            throw new WriterException("$bitmap doesn't appear to be a valid bitmap image.\n");
        }

        // Remove bitmap data: ID.

View on GitHub (pinned to 65b080eef4)

Solutions

  1. Pass an absolute path (e.g. via realpath()) to an existing file
  2. Check is_file(), is_readable() and filesize() > 0 before inserting
  3. Prefer the Drawing/MemoryDrawing API (PNG/JPEG) instead of the deprecated insertBitmap()
  4. Restore the missing file or fix filesystem permissions

Example fix

// before
$worksheetWriter->insertBitmap(1, 1, $relativePath);

// after
$path = realpath($relativePath);
if ($path === false || !is_readable($path) || filesize($path) === 0) {
    throw new InvalidArgumentException("Image not readable: $relativePath");
}
$worksheetWriter->insertBitmap(1, 1, $path);
Defensive patterns

Strategy: validation

Validate before calling

function assertBitmapReadable(string $path): void
{
    if (!is_file($path) || !is_readable($path)) {
        throw new InvalidArgumentException("Image missing or unreadable: $path");
    }
    if (filesize($path) === 0) {
        throw new InvalidArgumentException("Image file is empty: $path");
    }
}

assertBitmapReadable($bitmapPath);
$worksheetWriter->insertBitmap($row, $col, realpath($bitmapPath));

Try / catch

try {
    $worksheetWriter->insertBitmap($row, $col, $path);
} catch (\PhpOffice\PhpSpreadsheet\Writer\Exception $e) {
    if (str_contains($e->getMessage(), "Couldn't import")) {
        // log and continue without the image rather than losing the whole export
        error_log("Skipping missing image: $path");
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Calling insertBitmap($row, $col, '/path/img.bmp') where the path does not exist, lacks read permission, or points to an empty (0-byte) file; relative paths resolved against an unexpected current working directory.

Common situations: User-uploaded image deleted or moved before the write; CLI vs web cwd differences producing broken relative paths; permission changes on storage mounts.

Related errors


AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17). Data as JSON: /api/errors/df98a5bec1c850de. Report an issue: GitHub.