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
- Pass an absolute path (e.g. via realpath()) to an existing file
- Check is_file(), is_readable() and filesize() > 0 before inserting
- Prefer the Drawing/MemoryDrawing API (PNG/JPEG) instead of the deprecated insertBitmap()
- 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
- Always resolve image paths with realpath() before use
- Copy user-supplied images to your own storage before referencing them in exports
- Prefer the Drawing API (PNG/JPEG) over the deprecated insertBitmap()
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
- $bitmap doesn't contain enough data.\n
- $bitmap isn't a 24bit true color bitmap.\n
- $bitmap: compression not supported in bitmap image.\n
- $bitmap doesn't appear to be a valid bitmap image.\n
- $bitmap: largest image width supported is 65k.\n
AI-assisted analysis of PHPOffice/PhpSpreadsheet@65b080eef4 (2026-08-17).
Data as JSON: /api/errors/df98a5bec1c850de.
Report an issue: GitHub.