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:9Tỷ lệ khung trang chiếu.slide_style.fontstringtuỳ chọnFont chung.slide_style.title_color#RRGGBBtuỳ chọnMàu tiêu đề.slide_style.text_color#RRGGBBtuỳ chọnMàu chữ nội dung.slide_style.background#RRGGBBtuỳ chọnMàu nền mặc định.slide_style.title_sizenumber 4–400 (pt)tuỳ chọnCỡ chữ tiêu đề.slide_style.text_sizenumber 4–400 (pt)tuỳ chọnCỡ chữ nội dung.
{
"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_contentBố cục, xem bảng dưới.titlestring, ≤ 500tuỳ chọnTiêu đề trang chiếu.subtitlestring, ≤ 1000tuỳ chọnPhụ đề, dùng với bố cụctitle.bulletsarray, 1–50tuỳ chọnGạch đầu dòng.imageobjecttuỳ chọnMột ảnh trên trang chiếu.notesstring, ≤ 20.000tuỳ chọnGhi chú của người trình bày.background#RRGGBBtuỳ chọnMàu nền riêng của trang chiếu này.
layout | Dùng cho |
|---|---|
title | Trang bìa: title và subtitle. |
title_content | Tiêu đề và nội dung gạch đầu dòng (mặc định). |
title_only | Chỉ tiêu đề, phần dưới để trống cho ảnh. |
blank | Trang trống. |
{
"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ộcChữ. Gạch đầu dòng cũng có thể là một chuỗi trơn.levelinteger 0–4tuỳ chọnMặc định:0Cấp thụt vào; 0 là cấp ngoài cùng.boldbooleantuỳ chọnChữ đậm.
{
"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ộcNguồn ảnh{"url"}hoặc{"base64", "mime"}, như ảnh của văn bản.xnumber (mm)tuỳ chọnVị trí ngang của ảnh.ynumber (mm)tuỳ chọnVị trí dọc của ảnh.widthnumber (mm)tuỳ chọnBề rộng.heightnumber (mm)tuỳ chọnChiều cao.altstring, ≤ 1000tuỳ chọnChữ thay thế.
{
"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.
{
"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"
}
]
}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());