chundev
日期:2026-03-25 環境:macOS + LibreOffice (Homebrew) + soffice –headless
用 soffice --headless --convert-to pdf 把含中文字型(如標楷體)的 .docx 轉成 PDF 時,macOS 上字型會 fallback 成預設字體。原因是 macOS 版 LibreOffice 用 CoreText 而非 fontconfig,CoreText 只認英文字型名稱(如 DFKai-SB),但 .docx 裡指定的是中文名稱(如 標楷體)。解法是在 registrymodifications.xcu 設定字型替換規則。
在自動化文件生成流程中,常需要用 LibreOffice headless 模式將 .docx 轉成 .pdf,作為 CI/CD 產出或自動驗證迴路的一環。當文件使用中文字型時,Linux 上通常只要安裝字型檔 + fc-cache -fv 就能解決,但 macOS 上同樣的做法無效。
轉出的 PDF 中文字型不正確,明顯不是指定的標楷體,而是 fallback 到了宋體或其他預設字型。
確認字型已安裝且 fontconfig 看得到:
fc-list | grep "標楷"
# /Users/xxx/Library/Fonts/Kaiu.ttf: DFKai\-SB,標楷體:style=Regular
但 LibreOffice 轉出來的 PDF 就是不用這個字型。
| 嘗試 | 做法 | 結果 | 原因 |
|---|---|---|---|
| ❌ 1 | Symlink 字型到 LibreOffice fonts 目錄 | 無效 | macOS LibreOffice 不從該目錄讀取字型 |
| ❌ 2 | 複製到 ~/.local/share/fonts/ + fc-cache -fv |
fontconfig 看到了,但 PDF 沒變 | macOS LibreOffice 不走 fontconfig |
| ❌ 3 | 清除 LibreOffice cache | 無效 | 問題不在快取 |
| ✅ 4 | 在 registrymodifications.xcu 設定字型替換 |
成功 | 正確的解法 |
LibreOffice 使用 fontconfig 處理字型解析和 fallback。fontconfig 能理解中文字型名稱別名(標楷體 → DFKai-SB),所以只要字型安裝到系統 + fc-cache -fv,就能正常運作。
LibreOffice 使用 CoreText(macOS 原生字型 API),透過 vcl/quartz/ 後端。CoreText 的字型名稱解析邏輯不同於 fontconfig:
.docx 中指定字型名稱:標楷體(中文名)DFKai-SB(英文名)標楷體 映射到 DFKai-SB → fallback這就是為什麼 fc-list 能看到字型,但 LibreOffice 就是不用。fontconfig 和 CoreText 是兩套完全獨立的系統。
~/Library/Application Support/LibreOffice/4/user/registrymodifications.xcu
在 </oor:items> 結尾標籤前加入兩段:
1. 啟用字型替換功能(預設關閉):
<item oor:path="/org.openoffice.Office.Common/Font/Substitution">
<prop oor:name="Replacement" oor:op="fuse"><value>true</value></prop>
</item>
2. 定義替換規則:
<item oor:path="/org.openoffice.Office.Common/Font/Substitution/FontPairs">
<node oor:name="標楷體" oor:op="replace">
<prop oor:name="Always" oor:op="fuse"><value>true</value></prop>
<prop oor:name="OnScreenOnly" oor:op="fuse"><value>false</value></prop>
<prop oor:name="ReplaceFont" oor:op="fuse"><value>標楷體</value></prop>
<prop oor:name="SubstituteFont" oor:op="fuse"><value>DFKai-SB</value></prop>
</node>
</item>
Tools → Options → LibreOffice → FontsApply replacement table標楷體,Replace with 欄填 DFKai-SBAlways,確認 Screen only 沒有勾選(否則 PDF 輸出不會替換)# 確保 LibreOffice 完全關閉
killall soffice.bin 2>/dev/null
sleep 1
# 重新轉換
soffice --headless --convert-to pdf --outdir /tmp document.docx
如果文件用了其他中文字型也有同樣問題,可以加入更多替換規則:
| 中文名稱(docx 內) | 英文名稱(macOS CoreText) |
|---|---|
| 標楷體 | DFKai-SB |
| 新細明體 | PMingLiU |
| 細明體 | MingLiU |
| 微軟正黑體 | Microsoft JhengHei |
| 微軟雅黑 | Microsoft YaHei |
前提是對應的 .ttf / .ttc 字型檔已安裝在系統中。
即使字型問題解決了,LibreOffice 轉出的 PDF 和 Word 開啟的 .docx 仍然會有佈局差異:
LibreOffice headless 轉 PDF 適合作為快速預覽和自動化驗證迴路(確認大方向的排版沒問題),但最終交付仍應以 Word 開啟的 .docx 為準。
fc-cache 和 fontconfig 設定對它無效.docx 裡寫的是中文名(標楷體),但 macOS CoreText 只認英文名(DFKai-SB),這個 mismatch 是問題根源OnScreenOnly 必須設 false — 否則只有螢幕顯示會替換,PDF 輸出不會