Repository navigation
Conversation
`writeDrawing` always wrote images as `xdr:twoCellAnchor`. When `anchor.to` was absent it made up the bottom-right corner as `from` plus 3 columns and 5 rows. `width`/`height` only reached the picture's `<a:ext>`, which Excel and LibreOffice ignore under a two-cell anchor, so a 200 x 40 px logo was stretched over a 3 x 5 cell box. Reading the file back returned a `to` the caller never gave. An image with no `to` is now written as `xdr:oneCellAnchor`: `xdr:from`, `<xdr:ext cx cy>` from `width`/`height` (or the existing default size), the same `xdr:pic`, and `xdr:clientData`. This is Excel's "Move but don't size with cells". The reader already parses `oneCellAnchor`, so the image reads back with only `from` and the size it was written with. Images with `anchor.to` are still written as `twoCellAnchor`, byte for byte as before. Rendering change: an image written without `anchor.to` now shows at its `width`/`height` (or the default 3000000 x 2000000 EMU, about 315 x 210 px) instead of filling 3 columns x 5 rows. It also no longer resizes with those cells. Pass `anchor.to` to keep the old stretched layout. Text boxes and charts still invent a `to` when it is absent. They are left for a follow-up: the reader takes text boxes only from `twoCellAnchor`, and charts have no size field. Closes productdevbook#598
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Merge Risk: ⚪ Minimal · up to
|
Closes #598
What was wrong
writeDrawingalways wrote images asxdr:twoCellAnchor. Whenanchor.towas absent, it made up the bottom-right corner asfromplus 3 columns and 5 rows.width/heightonly reached the picture's<a:ext>, which Excel and LibreOffice ignore under a two-cell anchor. So the image was stretched over a 3 × 5 cell box whatever size it was given.This is the issue's reproduction, a 200 × 40 px logo at B2 with no
to:Reading the file back with
readXlsx:Why the tests didn't catch it
test/images.test.tshad a test called "uses default to anchor when not specified" that asserted the inventedto(col 4, row 7 for an image at col 1, row 2). The test pinned the bug. TheoneCellAnchortests intest/one-cell-anchor.test.tsonly read hand-built files, so nothing checked what the writer produces for an image withoutto. The write → read parity register's image probe always passed ato.What landed
src/xlsx/drawing-writer.ts: whenanchor.tois absent, the image is written asxdr:oneCellAnchor. It holdsxdr:from, then<xdr:ext cx cy>fromwidth/height× 9525 EMU (or the existing default of 3000000 × 2000000 EMU), then the samexdr:picand<xdr:clientData/>. Both anchor kinds share onepic. Whentois given, thetwoCellAnchoroutput is byte-identical to before, and a test pins the full string.parseOneCellAnchoralready returns{ from }plus the size fromxdr:ext, so the image reads back as written. The comment inreader.tsthat said hucre always writestwoCellAnchor(hucre's own XLSX output is not fully readable by hucre — eight write-only fields #407) is updated.SheetImage.anchorandwidth/heightnow say which anchor each case is written as and where the size goes.anchor.tonow shows at itswidth/height, or at the default size of about 315 × 210 px. It no longer fills 3 columns × 5 rows, and it no longer resizes with those cells. Callers who want the old stretched layout can passanchor.to. This is in the commit body, which is where release notes come from.totest inimages.test.tsnow expects aoneCellAnchorwith the defaultext.one-cell-anchor.test.tscover:from, ext, pic, clientDatatowidth/heightare absentaltText/titlesurviving in the one-cell formtwoCellAnchorwhentois givenopenXlsx→saveXlsxto.Eight tests fail against
main: the correctedimages.test.tstest, the parity register, and six of the seven new tests. The seventh is the byte-identicaltwoCellAnchorguard, which already passed.bun run testpasses on Node 24 (lint, typecheck, and 240 files with 10,705 tests).Not in this PR: text boxes and charts still invent a
towhen it is absent (+3/+3 and +8/+15). Text boxes need reader work first, because the reader takes text boxes only fromtwoCellAnchor. Charts have no size field to put in anext. Both are left for a follow-up.README and
docs/PARITY.mdnever described the 3 × 5 default, so they don't need changes.Checked in Excel
In Excel for Mac, with a 200 × 40 px image anchored at B2 with no
to, written bymainand by this branch. Both files open without a repair prompt. Size and placement are as Excel itself reports them:a:extsize was ignored, as the issue says.So Excel sizes a
oneCellAnchorpicture fromxdr:ext.Not verified
Summary by CodeRabbit
New Features
Bug Fixes
Documentation