Skip to content

feat: 新增 word-builder-swift — Swift fluent API 直接寫 .docx(類 docx.js) #71

@kiki830621

Description

@kiki830621

Problem

Original text(來自對話 2026-04-06):
「我其實想要做的就是也能做到 nodejs 那種寫 word 的程式而已」
「我其實今天看到有人用 js 結果做出很漂亮的 word,我很驚訝」
「好,所以我要用 word-builder-swift 吧」
— Source: 2026-04-06 設計討論對話

使用者希望 macdoc 生態中擁有類似 Node.js docx.js 的能力 — 用程式碼直接建構 .docx 檔案,取代手動操作 Word 或透過 che-word-mcp 的互動式 tool calls。

目前 macdoc 的 ooxml-swift 已具備完整的 OOXML writer 能力(DocxWriter + Document/Paragraph/Run/Table/Image model),但僅作為內部 converter 後端(md-to-word, html-to-word, tex-to-docx)使用,沒有對外暴露成「直接可用的 builder API」。

Type

feature

Expected

使用者可以在 Swift code 裡這樣寫:

import WordBuilderSwift

let doc = Document()
    .heading(1, "Q1 季報")
    .paragraph { p in
        p.text("營收成長 ")
        p.text("15%", bold: true)
    }
try doc.write(to: URL(fileURLWithPath: "report.docx"))

Actual

目前若要用 Swift 寫 .docx,必須直接 import OOXMLSwift 並手動建構 model:

import OOXMLSwift

var doc = WordDocument()
var props = ParagraphProperties()
props.style = "Heading1"
doc.appendParagraph(Paragraph(text: "Q1 季報", properties: props))

let runs: [Run] = [
    Run(text: "營收成長 "),
    Run(text: "15%", properties: RunProperties(bold: true))
]
doc.appendParagraph(Paragraph(runs: runs))
try DocxWriter.write(doc, to: url)

需要手動建 RunProperties() / ParagraphProperties()、記住 style 名稱字串("Heading1")、沒有 fluent chaining,學習曲線較高。

Impact

Positive:

  • 降低「用 Swift 程式化產生 .docx」的門檻,對齊 docx.js 的開發者體驗
  • 為 macdoc 補上一個新的 source format:不是文件格式,而是「Swift code 作為來源」
  • 可作為 md-to-word / html-to-word 等 converter 內部的共用 builder 層,未來可重構集中化

Risks / Open Questions:

  • 需要先用 ooxml-swift 現有 API 寫幾份真實範例,才知道 wrapper 該長什麼樣(避免先寫抽象、後發現不合身)
  • 可能不需要新 package,僅寫 USAGE.md + 範例就足夠(待驗證)
  • 命名是否沿用 *-mac 街道命名原則(e.g., word-builder-mac

Exploration Summary

已探勘 ooxml-swiftmd-to-word-swift 現況:

檢查項 狀態
DocxWriter.write(_:to:) public API ✅ 已存在
WordDocument / Paragraph / Run / Table / Image / Style model ✅ 完整
ParagraphProperties / RunProperties(bold/italic/color/font/alignment...) ✅ 完整
document.appendParagraph(_:) ✅ 存在
對外 fluent builder API ❌ 缺

預估 wrapper 厚度:~200-400 行 Swift(薄層糖衣)

相關檔案

  • packages/ooxml-swift/Sources/OOXMLSwift/IO/DocxWriter.swift (534 行,寫入入口)
  • packages/ooxml-swift/Sources/OOXMLSwift/Models/Document.swift (1997 行)
  • packages/ooxml-swift/Sources/OOXMLSwift/Models/Paragraph.swift (322 行)
  • packages/ooxml-swift/Sources/OOXMLSwift/Models/Run.swift (206 行)
  • packages/md-to-word-swift/Sources/MDToWord/MarkdownASTWalker.swift (使用範例,L90 / L104 / L124)
  • packages/md-to-word-swift/Sources/MDToWord/MarkdownToWordConverter.swift (L33 呼叫 DocxWriter.write)

Proposed Approaches

選項 做法 成本
A. 零 package 寫 USAGE.md + 3-5 個真實範例到 ooxml-swift README 0
B. 薄 wrapper 新 package word-builder-swift,只加 fluent builder + helper ~300 行
C. 厚 wrapper B + 重構 md-to-word / html-to-word 改用 builder ~800 行 + 改現有 converter

建議路徑:先走 A 驗證真實使用情境,做 3-5 份「漂亮的 .docx」出來,用過幾次再決定要不要做 B。避免先寫抽象、後發現不合身。

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions