Skip to content

feat: embed cell <img> as floating images in exported excel - #2

Open
sibinc wants to merge 1 commit into
linways:masterfrom
sibinc:feat/cell-image-export
Open

feat: embed cell <img> as floating images in exported excel#2
sibinc wants to merge 1 commit into
linways:masterfrom
sibinc:feat/cell-image-export

Conversation

@sibinc

@sibinc sibinc commented Jun 9, 2026

Copy link
Copy Markdown

Problem

Images placed inside table cells (<td>/<th>) — college logos, header/banner images, signatures, seals, student photos, QR codes — were silently dropped from the exported Excel. htmldecode() strips every tag (including <img>), so the cell became empty text and no image was ever embedded. This affects 100+ report templates that render an <img> into a header cell and export via TableToExcel.convert(...).

Fix

Add image support in the library itself (one place), so no template or caller changes are needed:

  • src/parser.jsparseDomToTable now receives the workbook. For each cell, addCellImages() finds every <img>, reads the already-loaded DOM image through a <canvas> → PNG base64, and embeds it with wb.addImage() + ws.addImage() anchored (oneCell) to the cell's top-left, sized from the img's width/height. Cell text alongside the image is still exported. Wrapped in try/catch — unloaded or cross-origin-tainted images are skipped so a single bad image never breaks the export.
  • src/tableToExcel.js — threads the workbook into parseDomToTable.
  • convert() stays synchronous (canvas reads are sync for loaded, same-origin images), so existing callers are untouched.

Tests

  • Updated existing parser test call sites to the new signature.
  • Added an image-cell sample + test (graceful-degradation path).
  • 30/30 passing.

Notes for reviewers

  • Images are read from the rendered DOM, so the report must be visible before export.
  • Because a canvas is used, images must be same-origin or served with CORS headers; otherwise that single image is skipped (rest of the sheet still exports).
  • dist/ bundle is rebuilt in this PR. Deploying to consumers (e.g. examcontroller-ui) requires publishing a new package version and bumping it there.

Images inside table cells (logos, college headers/banners, signs, seals,
student photos, QR codes) were stripped by htmldecode and never reached the
exported sheet. Add image support in the parser so every <img> in a cell is
read from the loaded DOM image via a canvas and embedded with exceljs
addImage, anchored to that cell. convert() stays synchronous and templates
need no changes.

- parser.js: thread workbook through, add addCellImages/getImageDataUrl,
  defensively skip unloaded/cross-origin-tainted images
- tableToExcel.js: pass workbook into parseDomToTable
- tests: update call sites to new signature, add image cell test + sample
- README: document image behaviour and CORS caveat
- dist: rebuild bundle
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant