Skip to content

Adopt image fix from upstream PR #2876 (Issue #1804) #24

@protobi-pieter

Description

@protobi-pieter

Source

Adopt PR exceljs#2876 from exceljs#2876
Also implemented in: https://github.com/Catscratch/exceljs (commit a55ca28)

Problem

When adding the same image multiple times non-consecutively, ExcelJS adds the wrong image reference.

Example:

const img1 = wb.addImage({ filename: 'image1.png', extension: 'PNG' });
const img2 = wb.addImage({ filename: 'image2.jpg', extension: 'JPEG' });

ws.addImage(img2, 'A1:A1');  // Image 2 ✅
ws.addImage(img1, 'A3:A3');  // Image 1 ✅
ws.addImage(img1, 'A5:A5');  // Should be Image 1, but becomes Image 2! ❌

Root Cause

In lib/xlsx/xform/sheet/worksheet-xform.js, the code only tracks preImageId but not the corresponding relationship ID (rIdImage). When the same image is reused after another image, the relationship ID lookup fails.

Solution

PR exceljs#2876 fixes this by:

  1. Adding preRIdImage to track the relationship ID alongside preImageId
  2. Using this.preRIdImage when the same image ID is detected
  3. Storing both preImageId and preRIdImage for next iteration

Changes:

// Before:
let rIdImage = this.preImageId === medium.imageId ? 
  drawingRelsHash[medium.imageId] : 
  drawingRelsHash[drawing.rels.length];

// After:
let rIdImage = this.preImageId === medium.imageId ? 
  this.preRIdImage : 
  drawingRelsHash[drawing.rels.length];

// And store it:
this.preRIdImage = rIdImage;

Benefits

  • ✅ Fixes incorrect image references when reusing images
  • ✅ Maintains correct relationship IDs in OOXML
  • ✅ Enables proper image caching/reuse patterns
  • ✅ Has comprehensive test coverage

Attribution

Original PR author: wwwxy80s (@wwwxy80s)

Related

Plan

  1. ✅ Create this tracking issue
  2. Apply changes to our fork
  3. Add/update test coverage
  4. Comment on upstream PR Fix error of adding image in certain situations exceljs/exceljs#2876 about adoption

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions