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-swift 和 md-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。避免先寫抽象、後發現不合身。
Current Status
Phase: closed
Last updated: 2026-04-18 by idd-close
Key Decisions
- Scope 升級為「1:1 mirror of
npm docx (dolanmiu/docx@9.6.1)」而非薄糖衣 wrapper(原 issue Option B → C+ 變體)
reference/docx-js/ 已 clone(MIT, shallow)作為 API 對應 single source of truth
- 新 package
word-builder-swift 需獨立 repo(與 common-converter-swift / word-to-md-swift 同規格,.package(url:) 依賴)
- 交付分 3 phases:P1 core API + Packer (~500 行) / P2 styling + layout (~400 行) / P3 advanced (~300 行)
- ooxml-swift 需補
DocxWriter.writeData(_:) throws -> Data(對應 docx.js Packer.toBuffer)
- Section 模型差異(docx.js array vs ooxml-swift flat)→ word-builder-swift 對外暴露 sections array,內部扁平化
- Phase 1 shipped 2026-04-18: 46/46 tasks, 24+3 tests passing, zero code duplication verified
Scope Changes
- 從「3 選 1」(A 零 package / B 薄 wrapper / C 厚 wrapper)→ 選定 B 的加強版(scope 對齊整個 docx.js public API surface)
- ooxml-swift
DocxWriter.writeData API 已新增 + released as v0.7.0
- md-to-word / html-to-word / tex-to-docx 不重構(維持用 ooxml-swift 內部 model)
Blocking
- (none) — Phase 1 complete, Phase 2/3 deferred as scoped in diagnosis
Commits
ooxml-swift@4cf39a2 feat: DocxWriter.writeData for in-memory .docx output → released v0.7.0
word-builder-swift@b3c8862 feat: Phase 1 — 1:1 Swift mirror of docx.js 9.6.x → released v0.9.0
macdoc Package.swift + CLAUDE.md wiring — pending commit on next sync to main
Problem
使用者希望 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 裡這樣寫:
Actual
目前若要用 Swift 寫 .docx,必須直接
import OOXMLSwift並手動建構 model:需要手動建
RunProperties()/ParagraphProperties()、記住 style 名稱字串("Heading1")、沒有 fluent chaining,學習曲線較高。Impact
Positive:
Risks / Open Questions:
*-mac街道命名原則(e.g.,word-builder-mac)Exploration Summary
已探勘
ooxml-swift和md-to-word-swift現況:DocxWriter.write(_:to:)public APIWordDocument/Paragraph/Run/Table/Image/StylemodelParagraphProperties/RunProperties(bold/italic/color/font/alignment...)document.appendParagraph(_:)預估 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
word-builder-swift,只加 fluent builder + helper建議路徑:先走 A 驗證真實使用情境,做 3-5 份「漂亮的 .docx」出來,用過幾次再決定要不要做 B。避免先寫抽象、後發現不合身。
Current Status
Phase: closed
Last updated: 2026-04-18 by idd-close
Key Decisions
npm docx(dolanmiu/docx@9.6.1)」而非薄糖衣 wrapper(原 issue Option B → C+ 變體)reference/docx-js/已 clone(MIT, shallow)作為 API 對應 single source of truthword-builder-swift需獨立 repo(與 common-converter-swift / word-to-md-swift 同規格,.package(url:)依賴)DocxWriter.writeData(_:) throws -> Data(對應 docx.jsPacker.toBuffer)Scope Changes
DocxWriter.writeDataAPI 已新增 + released as v0.7.0Blocking
Commits
ooxml-swift@4cf39a2feat:DocxWriter.writeDatafor in-memory.docxoutput → released v0.7.0word-builder-swift@b3c8862feat: Phase 1 — 1:1 Swift mirror of docx.js 9.6.x → released v0.9.0macdocPackage.swift + CLAUDE.md wiring — pending commit on next sync to main