Witan Render

Witan Render turns a sheet-qualified range into an image for the worksheet features it supports. Use it when an agent or CI check needs to inspect workbook layout, formatting, labels, charts, or visual regressions without opening Excel.

Use it from exec when rendering is part of a larger workbook script:

witan xlsx exec report.xlsx --code '
  await xlsx.previewStyles(wb, "Sheet1!A1:Z50")
  return { rendered: "Sheet1!A1:Z50" }
'

Output:

{
  "rendered": "Sheet1!A1:Z50"
}
/var/folders/xx/.../witan-exec-2597439692.png

Use the standalone command for direct image files, high-resolution output, WebP output, or pixel diffs:

$ witan xlsx render report.xlsx -r "Sheet1!A1:Z50"
/var/folders/xx/.../witan-render-123456.png
Sheet1!A1:Z50 | ~3328×1500px | dpr=2

The command renders the requested range only. That keeps screenshots focused on the cells a model or reviewer needs to inspect.

What Renders

The renderer aims to match Excel's raster output for the supported feature set below. It is not a full Excel UI or print engine, but the implemented worksheet, drawing, chart, and formatting paths are developed against Excel behavior and regression tests.

Area Supported Notes and gaps
Range layout Sheet-qualified ranges, gridlines, hidden rows and columns, custom row heights and column widths, merged cells, whole-row/whole-column requests bounded to used extent where possible See Styles and Layout for authoring geometry. Not a print/page-layout renderer. Frozen panes are not relevant to static range output.
Cell text layout Horizontal and vertical alignment, center-across-selection, fill alignment, wrap text, shrink-to-fit, indentation, text rotation, overflow into adjacent empty cells, rich text runs Overflow is suppressed where adjacent cells block it, matching spreadsheet display behavior.
Fonts Font family mapping, font size, color, bold, italic, underline, strikethrough, superscript, subscript, deterministic embedded font fallbacks Rendering does not depend on host-installed fonts. Witan bundles open-source equivalents for major Office fonts, such as Carlito for Calibri/Aptos, Caladea for Cambria/Constantia, Arimo for Arial/Bahnschrift, Cousine for Consolas, and Tinos for Sanskrit Text.
Fills Solid fills, linear and path gradients, pattern fills, theme/indexed/RGB color resolution Unsupported or malformed fill definitions fall back rather than blocking the render.
Borders All cell edges, diagonals, colors, and Excel border styles including hair, dotted, dashed, dash-dot, dash-dot-dot, thin, medium, medium-dashed, medium-dash-dot, medium-dash-dot-dot, thick, double, and slant-dash-dot Border rendering is part of the cell raster path, not an overlay added after export.
Number formats Excel-style numeric, date/time, fraction, scientific, accounting, currency, locale-aware built-ins, conditional sections, and color directives Values are rendered from workbook display text, including formula cached values after calculation.
Conditional formatting Supported Excel conditional formatting rules are evaluated before drawing cells See Conditional Formatting for authoring support and feature-specific render behavior.
Images Embedded raster images such as PNG, JPEG, BMP, and GIF, with z-order, rotation, and flip transforms See Images and Drawings for authoring support. EMF/WMF images are skipped. Images above the documented byte or decoded-pixel limits are skipped.
Shapes Common shapes including rectangles, rounded rectangles, ellipses, lines/connectors, triangles, and diamonds; shape fill, border, text, z-order, rotation, and flip transforms See Images and Drawings for drawing notes. Less common shape geometries may render with a rectangular fallback.
Charts Supported embedded Excel charts are rendered as part of the worksheet range See Charts for chart-family support, the chart spec model, OOXML preservation behavior, and visual verification workflow.
Sparklines Line, column, and win/loss sparklines Sparkline markers and colors are rendered from the workbook model where present.

Known gaps: EMF/WMF images are skipped; very large embedded images are skipped; and less common shape geometry can fall back to rectangles. Feature-specific rendering notes are documented on the relevant feature pages.

Fidelity and Validation

Renderer work is tested as a visual surface, not just as data extraction. The engine has unit and integration coverage for render output, chart rendering, conditional formatting, drawings, row/column geometry, rich text, and deterministic font behavior. Renderer changes are also checked with a tile visual regression workflow that renders a fixture matrix and pixel-diffs it against a baseline.

Range Targeting

Pass a sheet-qualified A1 range:

witan xlsx render report.xlsx -r "Sheet1!A1:Z50"
witan xlsx render report.xlsx -r "'My Sheet'!B5:H20"

The renderer accepts ranges within Excel worksheet bounds and the render limits below. Whole-row or whole-column style requests are resolved by the engine to the used extent where possible.

Limits

Limit Value
Device pixel ratio 1, 2, or 3
Maximum rows per render request 8192
Maximum columns per render request 2048
Maximum output dimension 65,535 px per side
Maximum output area 100,000,000 px
Maximum decoded embedded image size 100,000,000 px
Maximum embedded image bytes 10 MB

If a render fails because the requested surface is too large, reduce the range or lower --dpr.

Auto DPR

The --dpr flag controls device pixel ratio:

witan xlsx render report.xlsx -r "Sheet1!A1:F10" --dpr 3

When --dpr is omitted, the CLI uses an automatic heuristic. It estimates the range using default Excel cell geometry, selects 2 for smaller ranges, and drops to 1 when the estimated 2x image would exceed 1568 px on either axis.

Auto mode chooses only 1 or 2; request --dpr 3 explicitly for small ranges where you need extra resolution. The printed pixel dimensions are estimates based on the same default geometry, so unusual row heights or column widths may differ from the final image dimensions.

If the estimated output exceeds 1568 px on either axis, the CLI prints:

Warning: Image exceeds 1568px. Vision models may downscale, reducing detail. Consider a smaller --range.

Output

PNG is the default. WebP is available for smaller image files:

witan xlsx render report.xlsx -r "Sheet1!A1:Z50" --format webp

Every invocation prints the output path followed by a metadata line:

<image-path>
<range> | ~<width>×<height>px | dpr=<n>

If --output is omitted, the CLI writes to a temporary file. If --output points into a directory that does not exist, the CLI creates it.

Pixel Diff

Use --diff to compare a fresh render against a baseline PNG:

witan xlsx render report.xlsx -r "Sheet1!A1:F20" -o before.png
# ... edit the spreadsheet ...
witan xlsx render report.xlsx -r "Sheet1!A1:F20" --diff before.png

The diff image keeps changed pixels in full color, outlines changed regions for visibility, and desaturates unchanged areas. The metadata line appends a summary:

/var/folders/xx/.../witan-render-654321.png
Sheet1!A1:F20 | ~768×600px | dpr=2 | diff: 1,204 pixels changed (3.2%)

If nothing changed:

Sheet1!A1:F20 | ~768×600px | dpr=2 | diff: no changes

--diff requires --format png. The baseline and current render must have identical dimensions, so use the same range and DPR for both.

CLI Reference

witan xlsx render <file> [flags]
Flag Description Default
-r, --range Sheet-qualified range to render. Required. -
--dpr Device pixel ratio: 1, 2, or 3. Omit for auto mode. Auto (1 or 2)
--format Image format: png or webp. png
-o, --output Output file path. If omitted, writes to a temp file. Temp file
--diff Path to a baseline PNG image. Outputs a pixel-diff image. Requires --format png. -

Examples

# Basic render
witan xlsx render report.xlsx -r "Sheet1!A1:Z50"

# High-resolution render of a small range
witan xlsx render report.xlsx -r "Sheet1!B2:F10" --dpr 3

# Save to a specific path
witan xlsx render report.xlsx -r "Sheet1!A1:M30" -o output/table.png

# WebP output
witan xlsx render report.xlsx -r "Sheet1!A1:Z50" --format webp

# Baseline + diff workflow
witan xlsx render report.xlsx -r "Sheet1!A1:F20" -o before.png
# ... edit the spreadsheet ...
witan xlsx render report.xlsx -r "Sheet1!A1:F20" --diff before.png