Skip to content

O3O DocBuilder and conversion

o3oscript for presentations

Every operation of a type = slides script: slide size, shared style, four layouts, multi-level bullets, images, backgrounds and speaker notes, each with a parameter table and an example.

On this page

A type = "slides" script builds a deck of 1 to 500 slides in the slides array. Save formats: pptx, odp, pdf.

Size and shared style: slide_size, slide_style#

Root key and the slide_style object

  • slide_size16:9 | 4:3optionalDefault: 16:9
    Slide aspect ratio.
  • slide_style.fontstringoptional
    Shared font.
  • slide_style.title_color#RRGGBBoptional
    Title colour.
  • slide_style.text_color#RRGGBBoptional
    Body text colour.
  • slide_style.background#RRGGBBoptional
    Default background.
  • slide_style.title_sizenumber 4–400 (pt)optional
    Title font size.
  • slide_style.text_sizenumber 4–400 (pt)optional
    Body font size.
JSON16:9 with orange titles
{
  "slide_size": "16:9",
  "slide_style": {
    "font": "Liberation Sans",
    "title_color": "#C04A1B",
    "text_color": "#222222",
    "background": "#FFFFFF",
    "title_size": 36,
    "text_size": 22
  }
}

Slides: slide#

The slide object

  • layouttitle | title_content | title_only | blankoptionalDefault: title_content
    Layout, see the table below.
  • titlestring, ≤ 500optional
    Slide title.
  • subtitlestring, ≤ 1000optional
    Subtitle, used with the title layout.
  • bulletsarray, 1–50optional
    Bullets.
  • imageobjectoptional
    One image on the slide.
  • notesstring, ≤ 20,000optional
    Speaker notes.
  • background#RRGGBBoptional
    Background of this slide only.
layoutUsed for
titleTitle slide: title and subtitle.
title_contentTitle and bulleted content (default).
title_onlyTitle only, the rest left free for an image.
blankEmpty slide.
JSONTitle slide
{
  "layout": "title",
  "title": "Báo cáo quý III năm 2026",
  "subtitle": "Phòng Kinh doanh · 30/09/2026",
  "notes": "Giới thiệu người trình bày và mục tiêu buổi họp."
}

Bullets: bullets#

Each bullet

  • textstring, ≤ 2000required
    Text. A bullet can also be a plain string.
  • levelinteger 0–4optionalDefault: 0
    Indent level; 0 is the outermost.
  • boldbooleanoptional
    Bold.
JSONMulti-level content
{
  "layout": "title_content",
  "title": "Kết quả chính",
  "bullets": [
    "Doanh thu tăng so với quý II",
    {
      "text": "Khu vực phía Bắc dẫn đầu",
      "level": 1
    },
    {
      "text": "Cần đẩy mạnh kênh đối tác",
      "bold": true
    }
  ],
  "notes": "Nhấn mạnh kết quả của khu vực phía Bắc.",
  "background": "#F7F9FC"
}

Images on slides#

The slide image object

  • srcobjectrequired
    Image source {"url"} or {"base64", "mime"}, same as in text documents.
  • xnumber (mm)optional
    Horizontal position.
  • ynumber (mm)optional
    Vertical position.
  • widthnumber (mm)optional
    Width.
  • heightnumber (mm)optional
    Height.
  • altstring, ≤ 1000optional
    Alternative text.
JSONTitle only with a positioned image
{
  "layout": "title_only",
  "title": "Sơ đồ triển khai",
  "image": {
    "src": {
      "url": "https://example.com/images/so-do-trien-khai.png"
    },
    "x": 20,
    "y": 40,
    "width": 200,
    "height": 110,
    "alt": "Sơ đồ triển khai ba máy chủ"
  }
}
Coming soon

Slide transitions, custom slide masters and charts.

Complete example: product introduction#

gioi-thieu.json builds three slides: a title slide, multi-level content and a slide with a base64 image (so the example runs offline). The script has 12 units: the slide count plus the total number of bullets.

JSONgioi-thieu.json
{
  "o3oscript": 1,
  "type": "slides",
  "meta": {
    "title": "Giới thiệu O3O Office Online",
    "author": "Công ty Cổ phần O3O",
    "lang": "vi-VN"
  },
  "slide_size": "16:9",
  "slide_style": {
    "font": "Liberation Sans",
    "title_color": "#C04A1B",
    "text_color": "#222222",
    "background": "#FFFFFF",
    "title_size": 36,
    "text_size": 22
  },
  "slides": [
    {
      "layout": "title",
      "title": "O3O Office Online",
      "subtitle": "Bộ soạn thảo văn bản, bảng tính và trình chiếu chạy trên máy chủ của chính bạn",
      "notes": "Chào mừng. Bài trình bày dài khoảng 5 phút."
    },
    {
      "layout": "title_content",
      "title": "Ba thành phần",
      "bullets": [
        "Trình soạn thảo cộng tác ngay trong trình duyệt",
        {
          "text": "Đấu vào Nextcloud qua giao thức WOPI",
          "level": 1
        },
        {
          "text": "Hoặc nhúng thẳng vào ứng dụng bằng O3O.Editor",
          "level": 1
        },
        "DocBuilder: dựng và chuyển đổi tài liệu qua API",
        {
          "text": "Kịch bản o3oscript dạng JSON",
          "level": 1
        },
        {
          "text": "Bản cộng đồng miễn phí 50 kết nối đồng thời",
          "bold": true
        }
      ],
      "notes": "Nhấn mạnh: dữ liệu nằm trên máy chủ của khách hàng."
    },
    {
      "layout": "title_content",
      "title": "Ba ứng dụng, ba màu",
      "bullets": [
        "Xanh dương: văn bản",
        "Cam: trình chiếu",
        "Xanh lá: bảng tính"
      ],
      "image": {
        "src": {
          "base64": "iVBORw0KGgoAAAANSUhEUgAAAKAAAABaCAIAAACwpMoFAAAAsUlEQVR42u3RMQ0AIAwAwapgIYhhZccMyhiRhoA6aC55BX8x9lXhwgLAAizAAizAAizAgAVYgAVYgAVYgAELsAALsAALsAALMGABFmABFmABVgJ+q6twgAELsAALsAALsAADFmABFmABFmABBizAAizAAizAAizAgAVYgAVYgAVYGbidqcIBBizAAizAAizAAgxYgAVYgAVYgAUYsAALsAALsAALsAADFmABFmABFmClPpawm2fxo+U6AAAAAElFTkSuQmCC",
          "mime": "image/png"
        },
        "alt": "Ba dải màu của ba ứng dụng"
      },
      "notes": "Ảnh minh hoạ là ba dải màu thương hiệu, nhúng dạng base64 để ví dụ chạy được khi không có mạng."
    }
  ],
  "save": [
    {
      "format": "pptx",
      "filename": "gioi-thieu.pptx"
    }
  ]
}
Build the deck as pptx
curl -sS http://localhost:8080/v1/build \
  -H "Authorization: Bearer O3O_DEMO_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @gioi-thieu.json \
  -o gioi-thieu.pptx -w "HTTP %{http_code}\n"
import { readFile, writeFile } from "node:fs/promises";

const BASE_URL = "http://localhost:8080";
const HEADERS = { Authorization: "Bearer O3O_DEMO_KEY" };

const script = JSON.parse(await readFile("gioi-thieu.json", "utf8"));

const res = await fetch(`${BASE_URL}/v1/build`, {
  method: "POST",
  headers: { ...HEADERS, "Content-Type": "application/json" },
  body: JSON.stringify(script),
  signal: AbortSignal.timeout(90_000),
});
if (!res.ok) throw new Error(`${res.status}: ${await res.text()}`);
await writeFile("gioi-thieu.pptx", Buffer.from(await res.arrayBuffer()));
import json

import requests

BASE_URL = "http://localhost:8080"
HEADERS = {"Authorization": "Bearer O3O_DEMO_KEY"}

with open("gioi-thieu.json", encoding="utf-8") as f:
    script = json.load(f)

r = requests.post(f"{BASE_URL}/v1/build", headers=HEADERS, json=script, timeout=90)
if not r.ok:
    raise RuntimeError(f"{r.status_code}: {r.text}")
with open("gioi-thieu.pptx", "wb") as fh:
    fh.write(r.content)
<?php
$payload = file_get_contents("gioi-thieu.json");

$ch = curl_init("http://localhost:8080/v1/build");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ["Authorization: Bearer O3O_DEMO_KEY", "Content-Type: application/json"],
    CURLOPT_POSTFIELDS => $payload,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 90,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
if ($body === false || $status >= 400) {
    throw new RuntimeException("HTTP $status: " . ($body === false ? curl_error($ch) : $body));
}
file_put_contents("gioi-thieu.pptx", $body);
using System.Net.Http.Headers;
using System.Text;

using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(90) };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "O3O_DEMO_KEY");

var json = await File.ReadAllTextAsync("gioi-thieu.json");
using var res = await http.PostAsync("http://localhost:8080/v1/build",
    new StringContent(json, Encoding.UTF8, "application/json"));
if (!res.IsSuccessStatusCode)
    throw new HttpRequestException($"{(int)res.StatusCode}: {await res.Content.ReadAsStringAsync()}");
await File.WriteAllBytesAsync("gioi-thieu.pptx", await res.Content.ReadAsByteArrayAsync());