# How the OfficeCLI Built-In HTML Rendering Engine Visualizes Office Documents

> Discover how the OfficeCLI HTML rendering engine visualizes Office documents. Learn about its pluggable architecture and format handlers for high-fidelity previews without Office installation.

- Repository: [OfficeAI/OfficeCLI](https://github.com/iofficeai/OfficeCLI)
- Tags: internals
- Published: 2026-07-25

---

**OfficeCLI's built-in HTML rendering engine converts .docx, .xlsx, and .pptx files into browser-ready previews using a pluggable architecture with `IRenderer` interfaces, a priority-based registry, and format-specific handlers that generate high-fidelity HTML without requiring Microsoft Office installation.**

The [iOfficeAI/OfficeCLI](https://github.com/iOfficeAI/OfficeCLI) repository provides a self-contained, cross-platform command-line tool for Office document manipulation. At its core lies the **OfficeCLI built-in HTML rendering engine**, which enables deterministic document visualization through a zero-dependency pipeline that works in Docker containers, CI pipelines, and headless environments.

## Architecture of the Rendering Engine

The rendering system is built upon three architectural pillars that decouple document handling from output generation.

### The IRenderer Interface Contract

All rendering backends implement the `IRenderer` interface defined in [`src/officecli/Core/Rendering/IRenderer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/Rendering/IRenderer.cs). This contract specifies:

- **Capabilities**: A `RenderCapabilities` property declaring supported formats (docx, xlsx, pptx), output kinds (HTML, SVG, PNG), and priority level
- **Availability Gate**: An `IsAvailable` boolean for runtime dependency checks
- **Render Method**: A single `Render(IRenderInput input, RenderOptions options)` method that receives format-agnostic input and returns structured output

Built-in renderers register at **priority 0**, allowing external plugins to override them by registering higher-priority implementations.

### RendererRegistry Resolution Logic

The `RendererRegistry` class in [`src/officecli/Core/Rendering/RendererRegistry.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/Rendering/RendererRegistry.cs) maintains a prioritized list of `IRenderer` instances. When a command like `officecli view report.docx html` executes, the registry resolves the best renderer by matching:

1. Document format (`.docx`, `.xlsx`, `.pptx`)
2. Requested output kind (`Html`, `Svg`, `Screenshot`)
3. Renderer priority (highest wins)

This resolution happens through `RendererRegistry.Resolve`, which returns the first compatible renderer sorted by descending priority.

### Basic Renderer Adapters

The built-in engine uses thin, stateless wrappers located in [`src/officecli/Handlers/Rendering/BasicRenderers.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Rendering/BasicRenderers.cs):

- **WordBasicRenderer**: Delegates to `WordHandler.ViewAsHtml`
- **ExcelBasicRenderer**: Delegates to `ExcelHandler.ViewAsHtml`  
- **PptBasicRenderer**: Delegates to `PowerPointHandler.ViewAsHtml` or `ViewAsSvg`

These adapters ensure **byte-identical output** with the existing document handlers while conforming to the `IRenderer` contract.

## Document-to-HTML Conversion Pipeline

The rendering flow transforms raw OpenXML into browser-ready markup through a seven-stage process.

### Stage 1: CLI Parsing to HandlerRenderInput

When you execute a view command:

```bash
officecli view report.docx html --page 1 -o /tmp/report.html

```

The CLI constructs a `RenderOptions` object from flags (`--page`, `--grid`, `--viewport`), then creates a `HandlerRenderInput` containing a reference to the appropriate document handler (`WordHandler`, `ExcelHandler`, or `PowerPointHandler`) and the parsed OpenXML model.

### Stage 2: Registry Resolution

`RendererRegistry.Resolve` selects the renderer matching the document format and requested output. For HTML output of a Word document, it returns `WordBasicRenderer` unless a higher-priority plugin is registered.

### Stage 3: HTML Generation in WordHandler

For Word documents, `WordBasicRenderer.Render` invokes `WordHandler.ViewAsHtml` from [`src/officecli/Handlers/Word/WordHandler.HtmlPreview.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Word/WordHandler.HtmlPreview.cs). This method performs the heavy lifting:

- **Page Layout**: Reads `<w:sectPr>` elements to compute page dimensions, margins, and borders, emitting per-page CSS (`width`, `padding`, `background`)
- **Typography**: Gathers document-declared fonts and emits `@font-face` rules, lazily loading missing fonts from Google Fonts via OfficeCLI's mirrored CDN
- **Headers/Footers**: Resolves section-level header/footer parts, substitutes `PAGE`/`NUMPAGES` fields, and injects them per page
- **Images**: Embeds binary image data as data-URIs and renders Mermaid diagrams to PNG via `MermaidImageRenderer`
- **Charts**: Transforms OpenXML chart data into inline SVG using `ChartSvgRenderer` from [`src/officecli/Core/Chart/ChartSvgRenderer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Core/Chart/ChartSvgRenderer.cs), preserving theme colors and legends
- **Footnotes**: Collects notes and places them on pages containing references
- **Pagination**: Injects a client-side `_wordInit` script that measures page-body height, splits overflowing content, repeats table headers, and adjusts for tall headers

### Stage 4: Excel and PowerPoint Handling

- **Excel**: `ExcelHandler.ViewAsHtml` renders worksheets as HTML tables with CSS grid styling
- **PowerPoint**: `PowerPointHandler.ViewAsHtml` (from [`src/officecli/Handlers/Pptx/PowerPointHandler.HtmlPreview.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/src/officecli/Handlers/Pptx/PowerPointHandler.HtmlPreview.cs)) generates slide-based HTML or SVG vector output when `RenderOutputKind.Svg` is requested, including 3-D model placeholders

## Advanced Rendering Features

Beyond static HTML generation, the engine supports dynamic visualization and screenshot capabilities.

### Chart-to-SVG Conversion

The `ChartSvgRenderer` class processes OpenXML chart definitions (`<c:chart>`) into scalable vector graphics. It handles:

- Theme color extraction from document themes
- Axis scaling and legend positioning
- Data point styling and label rendering

This ensures charts appear identical to their Office-rendered counterparts without requiring external image generation.

### Screenshot Generation with Headless Chromium

When requesting PNG output:

```bash
officecli view deck.pptx screenshot --page 1 -o slide1.png

```

The engine pipes the generated HTML through a headless Chromium instance (embedded via Playwright or similar) to produce pixel-perfect PNG renders per page. This operates entirely within the CLI binary without external browser installations.

### Live Preview via Watch Mode

The `officecli watch` command starts a local HTTP server (default port 26315) that maintains the document in memory:

```bash
officecli watch presentation.pptx

```

When mutations occur (e.g., `officecli add presentation.pptx / --type slide`), the server:
1. Re-renders HTML via the registry pipeline
2. Pushes updates to connected browsers via Server-Sent Events ([`watch-sse-core.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/watch-sse-core.js))
3. Refreshes the preview without file reload

## Extending the Rendering Engine

Third-party developers can replace or augment the built-in engine through the plugin architecture.

### Custom Renderer Implementation

Create a class implementing `IRenderer` with higher priority than the built-in adapters:

```csharp
// MySvgRenderer.cs
public sealed class MySvgRenderer : IRenderer 
{
    public RenderCapabilities Capabilities => new() 
    {
        Name = "my-svg-renderer",
        Priority = 10,  // Higher than built-in priority 0
        SupportedFormats = new[] { "docx" },
        SupportedOutputs = RenderOutputKind.Svg,
        SupportsWatch = false,
    };
    
    public bool IsAvailable => true;
    
    public RenderResult Render(IRenderInput input, RenderOptions options) 
    {
        // Custom SVG conversion logic
        return RenderResult.Svg("<svg>...</svg>");
    }
}

// Register at startup
RendererRegistry.Default.Register(new MySvgRenderer());

```

Because this plugin registers at priority 10, `RendererRegistry.Resolve` selects it over `WordBasicRenderer` for SVG output of .docx files.

## Summary

- **OfficeCLI's rendering engine** uses an `IRenderer` abstraction with a priority-based `RendererRegistry` to select the best backend for each document format and output type
- **Basic renderers** in [`BasicRenderers.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/BasicRenderers.cs) act as thin adapters forwarding to `WordHandler`, `ExcelHandler`, and `PowerPointHandler` view methods
- **HTML generation** handles complex layout including headers/footers, fonts, charts (via `ChartSvgRenderer`), footnotes, and client-side pagination scripts
- **Screenshot mode** utilizes headless Chromium to convert HTML to PNG without external dependencies
- **Watch mode** provides live document previews via an embedded HTTP server with Server-Sent Event updates
- **Zero Office installation required**: The engine relies solely on the embedded .NET runtime and OpenXML SDK

## Frequently Asked Questions

### Does OfficeCLI require Microsoft Office to render HTML?

No. The OfficeCLI built-in HTML rendering engine operates entirely through the OpenXML SDK and embedded .NET runtime. It parses the raw .docx, .xlsx, and .pptx files directly without COM interop or external Office installations, making it suitable for Docker containers and CI/CD pipelines.

### What output formats does the rendering engine support?

The engine supports three primary output kinds defined in the `IRenderer` interface: **HTML** (self-contained browser documents), **SVG** (vector graphics for PowerPoint slides and charts), and **Screenshot** (PNG images generated via headless Chromium). The specific availability depends on the document handler and renderer implementation.

### How does the rendering engine handle complex Word documents with headers and footers?

The `WordHandler.ViewAsHtml` method in [`WordHandler.HtmlPreview.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.HtmlPreview.cs) resolves section-level header and footer parts from the OpenXML `<w:sectPr>` elements. It substitutes field codes like `PAGE` and `NUMPAGES` with actual values, injects the content into per-page containers, and uses a client-side pagination script to adjust layout when content overflows page boundaries.

### Can I replace the built-in HTML renderer with a custom implementation?

Yes. Implement the `IRenderer` interface with a `Priority` value higher than 0 (the built-in priority) and register it via `RendererRegistry.Default.Register()`. The registry will automatically select your renderer for compatible formats and output types, allowing you to override HTML generation logic or add support for new export formats like PDF.