#139·anydoc

XLSX embedded images are missing from Document.assets

Author: zhangweiooyCreated Aug 25, 2026Updated Aug 29, 2026

Summary

anydoc.to_document(..., "xlsx") extracts worksheet cell content but omits embedded worksheet images from Document.assets.

This differs from #63: that issue reports assets being present for DOCX but absent from rendered Markdown. In this case, the XLSX asset is already missing from the shared Document model, so consumers cannot preserve the image bytes or create their own Markdown reference.

Environment

  • firecrawl-anydoc: 0.2.3
  • Python: 3.11.15
  • OS: Windows

Minimal reproduction

python
import tempfile
from pathlib import Path

import anydoc
from openpyxl import Workbook
from openpyxl.drawing.image import Image

PNG = bytes.fromhex(
    "89504e470d0a1a0a0000000d49484452000000010000000108060000001f15c489"
    "0000000d49444154789c6360f8cfc000000301010018dd8db10000000049454e44"
    "ae426082"
)

with tempfile.TemporaryDirectory() as directory:
    root = Path(directory)
    image_path = root / "evidence.png"
    workbook_path = root / "with-image.xlsx"
    image_path.write_bytes(PNG)

    workbook = Workbook()
    worksheet = workbook.active
    worksheet["A1"] = "visual evidence"
    worksheet.add_image(Image(str(image_path)), "B2")
    workbook.save(workbook_path)
    workbook.close()

    payload = workbook_path.read_bytes()
    document = anydoc.to_document(payload, "xlsx")

    print("format:", anydoc.format_from_path(workbook_path))
    print("assets:", len(document.assets))
    print("blocks:", len(document.blocks))
    print(anydoc.to_markdown_bytes(payload, "xlsx"))

Actual result

format: xlsx
assets: 0
blocks: 1
|  |
| --- |
| visual evidence |

The cell content is extracted, but the embedded PNG is absent from document.assets.

Expected result

document.assets should contain the embedded worksheet image, including its bytes and media type, consistently with the documented shared document model contract for embedded images.

Positional image rendering in Markdown can remain tracked separately in #63; exposing the image in Document.assets is sufficient for consumers to persist it themselves.