# How OfficeCLI's HTML Rendering Engine Works for AI Document "Seeing"

> Discover how OfficeCLI transforms Office docs into HTML for AI document seeing. Learn about its powerful rendering engine and visual AI capabilities.

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

---

**OfficeCLI converts Word, PowerPoint, and Excel files into self-contained HTML previews that AI models can consume as visual representations of document content.**

OfficeCLI is an open-source command-line tool that bridges binary Office documents and AI systems. Its HTML rendering engine transforms `.docx`, `.pptx`, and `.xlsx` files into browser-ready pages, enabling AI models to "see" document structure, layout, and visual elements without requiring Microsoft Office or proprietary viewers.

## Command Dispatch: The Entry Point to HTML Generation

The rendering pipeline begins when you invoke `officecli view <file> --html`. In [`CommandBuilder.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/CommandBuilder.cs) (lines 1979-2014), the `view` verb with `html` mode triggers `CommandBuilder.RenderViaRegistry`:

```csharp
// Request a full HTML preview from the CLI
var html = CommandBuilder.RenderViaRegistry(
    handler: pptHandler,      // PowerPointHandler instance
    mode: "pptx",
    options: new RenderOptions());

```

This dispatch layer routes the request to a **handler-specific implementation** based on document type. Each handler—`PowerPointHandler`, `WordHandler`, or `ExcelHandler`—implements its own HTML generation strategy while sharing common utilities from [`Core/HtmlPreviewHelper.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/Core/HtmlPreviewHelper.cs) and [`Core/ColorMath.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/Core/ColorMath.cs).

## Handler-Specific HTML Generation

### PowerPoint HTML Rendering

The [`PowerPointHandler.HtmlPreview.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.HtmlPreview.cs) file contains two core methods for AI document seeing:

- **`ViewAsHtml`** (lines 72-94): Builds a complete, standalone HTML file with all slides
- **`RenderSlideHtml`** (lines 300-340): Returns a single slide's HTML for incremental updates

```csharp
// Incrementally refresh a single slide (used by the watch server)
var slideHtml = pptHandler.RenderSlideHtml(slideNumber);

```

The PowerPoint handler produces **absolutely-positioned slide containers** that preserve the original pixel-perfect layout. Each slide renders as a `<div class="slide-container">` with computed CSS positioning based on EMU-to-point conversion via `Units.EmuToPt`.

### Word HTML Rendering

The [`WordHandler.HtmlPreview.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.HtmlPreview.cs) assembles document previews from:

- Body content with paragraph and run-level formatting
- Headers and footers
- Tables with merged cells and borders
- Floating and inline shapes
- Mathematical formulas via OMML-to-KaTeX conversion

Both handlers enforce **culture-invariant numeric formatting** at entry via `InvariantCultureScope.Enter()` to prevent locale-dependent decimal separators from corrupting CSS values.

## The Rendering Pipeline: From Binary to Browser-Ready HTML

### CSS Variable System and Slide Dimensions

The engine emits **CSS custom properties** for design-time dimensions:

```css
:root {
  --slide-design-w: 720pt;
  --slide-design-h: 540pt;
}

```

These variables, generated in `GenerateCss`, enable responsive scaling while preserving the original aspect ratio.

### Theme-Aware Font Resolution

OfficeCLI implements **CJK fallback font resolution** through `ResolveDocCjkFallbackStatic`. This analyzes the presentation's theme to select appropriate East Asian fonts when documents lack explicit `lang` attributes—critical for accurate AI document seeing across multilingual content.

### Background Rendering Chain

The `GetSlideBackgroundCss` method walks a **three-level inheritance hierarchy**:

1. Slide-level background (`<p:bgPr>` or `<p:bgRef>`)
2. Layout-level default
3. Slide-master fallback

Supported fill types include solid colors, gradients, tiled images with stretch/crop modes, and pattern fills.

### Text Default Cascade

`GetTextDefaults` computes **inherited typography** by merging:

- Theme font definitions (major/minor fonts)
- Presentation default text styles
- Slide-master level formatting

This produces a computed `font-family`, `font-size`, and `color` for each text run.

### Element-by-Element Rendering

The `RenderSlideElements` method processes:

| Element | Rendering Approach |
|--------|------------------|
| Shapes | Absolutely-positioned `<div>` with inline CSS |
| Pictures | Base64-encoded data URI via `BlipToDataUri` |
| Tables | Nested `<table>` structures with computed cell styles |
| Charts | SVG or image fallback based on complexity |
| SmartArt | Decomposed to shapes and connectors |
| 3D Models | Three.js integration with dynamic import |
| Groups | Recursive rendering with transform inheritance |

## Embedded Assets for Rich Content

### KaTeX Math Rendering

When a slide contains `<m:oMath>` elements, OfficeCLI injects **KaTeX CSS and JavaScript** from [`Core/KatexAssets.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/Core/KatexAssets.cs). The engine uses CDN fallbacks with local embedded copies for offline operation.

### Three.js 3D Support

3D models reference a dynamic import map defined in `Core.ThreeAssets.ImportMapJson`, enabling GLTF/GLB rendering directly in the preview without external dependencies.

### Client-Side Interactivity

The embedded [`Resources.preview.js`](https://github.com/iOfficeAI/OfficeCLI/blob/main/Resources.preview.js) (injected via `GenerateScript`) provides:

- Keyboard navigation between slides
- Lazy KaTeX loading on visible math elements
- Mutation observer for watch-mode incremental updates

## Incremental Updates via Server-Sent Events

For live editing workflows, [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs) pushes **partial HTML fragments** to connected clients:

```csharp
// Server-side: Push slide update to client
var watchMessage = new WatchMessage {
    Action = "replace",
    SlideNumber = 5,
    Html = pptHandler.RenderSlideHtml(5)
};

```

The client replaces the corresponding `<div class="slide-container">` without full page reload—essential for real-time AI-assisted editing.

## Embedding HTML in AI Prompts

The generated HTML is designed for direct consumption by multimodal AI systems:

```csharp
string prompt = $"Here is the document preview:\n\n{html}\n\nAnswer the question based on the content above.";

```

The **self-contained** nature—base64 images, embedded CSS, no external network requests—ensures reliable rendering across AI platforms.

## Summary

- OfficeCLI's HTML rendering engine transforms binary Office documents into browser-compatible previews through handler-specific implementations in [`PowerPointHandler.HtmlPreview.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/PowerPointHandler.HtmlPreview.cs) and [`WordHandler.HtmlPreview.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/WordHandler.HtmlPreview.cs)
- The pipeline enforces culture-invariant formatting, theme-aware font resolution, and three-level background inheritance
- Elements render as absolutely-positioned HTML with base64-encoded assets for complete self-containment
- Incremental `RenderSlideHtml` updates enable real-time collaboration via Server-Sent Events from [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs)
- KaTeX and Three.js integration supports mathematical and 3D content without external dependencies

## Frequently Asked Questions

### Does OfficeCLI require Microsoft Office to generate HTML previews?

No. OfficeCLI parses `.docx`, `.pptx`, and `.xlsx` files directly using the Open XML SDK and custom handlers. The HTML rendering is entirely self-contained, producing standalone files that work in any modern browser or AI pipeline.

### How does the incremental slide update feature work?

When a document is being edited, [`ResidentServer.cs`](https://github.com/iOfficeAI/OfficeCLI/blob/main/ResidentServer.cs) detects changes and calls `RenderSlideHtml` for modified slides only. It pushes a `WatchMessage` with action `replace` via Server-Sent Events. The client JavaScript swaps the corresponding `<div class="slide-container">` element without reloading the full page, enabling sub-second visual feedback.

### Why are CSS variables used for slide dimensions instead of fixed pixel values?

CSS custom properties (`--slide-design-w`, `--slide-design-h`) allow responsive scaling while preserving the original aspect ratio. They also enable the client-side JavaScript to compute positioning for elements that render after initial page load, such as lazy-loaded KaTeX formulas or dynamically injected slide notes.