Bỏ qua, tới nội dung
Tài liệu APIv1

O3O DocBuilder và chuyển đổi

o3oscript cho trình chiếu

Mọi thao tác của kịch bản type = slides: khổ trang chiếu, kiểu chung, bốn bố cục, gạch đầu dòng nhiều cấp, ảnh, màu nền và ghi chú người trình bày, mỗi thao tác có bảng tham số và ví dụ.

Trong trang này

Kịch bản type = "slides" dựng một bộ trình chiếu gồm 1 tới 500 trang chiếu trong mảng slides. Định dạng lưu: pptx, odp, pdf.

Khổ và kiểu chung: slide_size, slide_style#

Khoá ở gốc và đối tượng slide_style

  • slide_size16:9 | 4:3tuỳ chọnMặc định: 16:9
    Tỷ lệ khung trang chiếu.
  • slide_style.fontstringtuỳ chọn
    Font chung.
  • slide_style.title_color#RRGGBBtuỳ chọn
    Màu tiêu đề.
  • slide_style.text_color#RRGGBBtuỳ chọn
    Màu chữ nội dung.
  • slide_style.background#RRGGBBtuỳ chọn
    Màu nền mặc định.
  • slide_style.title_sizenumber 4–400 (pt)tuỳ chọn
    Cỡ chữ tiêu đề.
  • slide_style.text_sizenumber 4–400 (pt)tuỳ chọn
    Cỡ chữ nội dung.
JSONKhổ 16:9, tiêu đề màu cam
{
  "slide_size": "16:9",
  "slide_style": {
    "font": "Liberation Sans",
    "title_color": "#C04A1B",
    "text_color": "#222222",
    "background": "#FFFFFF",
    "title_size": 36,
    "text_size": 22
  }
}

Trang chiếu: slide#

Đối tượng slide

  • layouttitle | title_content | title_only | blanktuỳ chọnMặc định: title_content
    Bố cục, xem bảng dưới.
  • titlestring, ≤ 500tuỳ chọn
    Tiêu đề trang chiếu.
  • subtitlestring, ≤ 1000tuỳ chọn
    Phụ đề, dùng với bố cục title.
  • bulletsarray, 1–50tuỳ chọn
    Gạch đầu dòng.
  • imageobjecttuỳ chọn
    Một ảnh trên trang chiếu.
  • notesstring, ≤ 20.000tuỳ chọn
    Ghi chú của người trình bày.
  • background#RRGGBBtuỳ chọn
    Màu nền riêng của trang chiếu này.
layoutDùng cho
titleTrang bìa: titlesubtitle.
title_contentTiêu đề và nội dung gạch đầu dòng (mặc định).
title_onlyChỉ tiêu đề, phần dưới để trống cho ảnh.
blankTrang trống.
JSONTrang bìa
{
  "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."
}

Gạch đầu dòng: bullets#

Mỗi gạch đầu dòng

  • textstring, ≤ 2000bắt buộc
    Chữ. Gạch đầu dòng cũng có thể là một chuỗi trơn.
  • levelinteger 0–4tuỳ chọnMặc định: 0
    Cấp thụt vào; 0 là cấp ngoài cùng.
  • boldbooleantuỳ chọn
    Chữ đậm.
JSONNội dung nhiều cấp
{
  "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"
}

Ảnh trên trang chiếu#

Đối tượng image của slide

  • srcobjectbắt buộc
    Nguồn ảnh {"url"} hoặc {"base64", "mime"}, như ảnh của văn bản.
  • xnumber (mm)tuỳ chọn
    Vị trí ngang của ảnh.
  • ynumber (mm)tuỳ chọn
    Vị trí dọc của ảnh.
  • widthnumber (mm)tuỳ chọn
    Bề rộng.
  • heightnumber (mm)tuỳ chọn
    Chiều cao.
  • altstring, ≤ 1000tuỳ chọn
    Chữ thay thế.
JSONChỉ tiêu đề và một ảnh đặt theo toạ độ
{
  "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ủ"
  }
}
Sắp có

Hiệu ứng chuyển trang chiếu, mẫu trang chiếu tuỳ biến và biểu đồ.

Ví dụ đầy đủ: giới thiệu sản phẩm#

gioi-thieu.json dựng ba trang chiếu: trang bìa, nội dung nhiều cấp và một trang có ảnh nhúng base64 (để ví dụ chạy được khi không có mạng). Kịch bản có 12 đơn vị: số trang chiếu cộng tổng số gạch đầu dòng.

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"
    }
  ]
}
Dựng bộ trình chiếu ra 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());