LibreOffice 互通性矩陣
本文件記錄 OdfKit 與 LibreOffice 26.x 的實機 headless 互通驗收範圍。
矩陣以 OdfKit.Tests/LibreOfficeInteropTests.cs 與 eng/Test-LibreOfficeInterop.ps1 為準。
執行方式
# 有 LibreOffice 26.x 時執行互通測試;找不到則略過(exit 0)
pwsh eng/Test-LibreOfficeInterop.ps1
# CI 或本機強制要求 LibreOffice
pwsh eng/Test-LibreOfficeInterop.ps1 -RequireLibreOffice
# 指定 portable 安裝路徑
$env:ODFKIT_SOFFICE_PATH = "D:\Tools\LibreOffice\program\soffice.com"
pwsh eng/Test-LibreOfficeInterop.ps1
LibreOfficeInteropTests 預設不會由一般 dotnet test 自動執行真實 LibreOffice;
專用腳本會在測試程序期間設定 ODFKIT_RUN_LIBREOFFICE_INTEROP=1,以免 unfiltered
回歸在安裝 LibreOffice 的機器上被外部 headless 轉檔拖慢。
環境變數(擇一):
| 變數 | 用途 |
|---|---|
ODFKIT_SOFFICE_PATH |
soffice 可執行檔或安裝目錄(優先) |
LIBREOFFICE_PATH |
同上,相容別名 |
需求:
- LibreOffice 26.x(
soffice --version輸出含LibreOffice 26.) - 排除
MockSoffice測試替身
矩陣
| 測試 | 來源格式 | OdfKit 建立內容 | LibreOffice 轉換 | 驗收方式 | 狀態 |
|---|---|---|---|---|---|
LibreOfficeHeadlessLoadsGeneratedDocuments |
ODT | 標題、段落、互通標記 | txt |
轉出文字含 OdfKit-LibreOffice-26-Interop-Marker |
✅ |
| 同上 | ODS | 嵌入圖表(條形圖、標題、圖例) | xlsx |
轉出 XLSX 非空 | ✅ |
| 同上 | ODP | 進場動畫(fade-in) | fodp |
轉出 XML 含 ooo-entrance-fade-in |
✅ |
| 同上 | ODG | 文字方塊互通標記 | fodg |
轉出 XML 含 OdfKit-LibreOffice-26-Interop-Marker |
✅ |
LibreOfficeHeadlessLoadsTrackedChangesOdt |
ODT | text:tracked-changes 段落與表格 |
txt / odt |
標記保留;可 accept 修訂 | ✅ |
LibreOfficeHeadlessLoadsTrackedChangesOds |
ODS | table:tracked-changes 公式變更 |
ods |
標記與修訂節點保留 | ✅ |
LibreOfficeHeadlessLoadsTemplateVariantDocuments |
OTT | 母片頁面、互通標記 | txt |
轉出文字含 OdfKit-LibreOffice-Template-Interop-Marker |
✅ |
| 同上 | OTS | 工作表互通標記 | fods |
轉出 Flat XML 含互通標記 | ✅ |
| 同上 | OTP | 標題 placeholder、文字方塊互通標記 | fodp |
轉出 Flat XML 含互通標記 | ✅ |
| 同上 | OTG | 文字方塊互通標記 | fodg |
轉出 Flat XML 含互通標記 | ✅ |
LibreOfficeHeadlessLoadsNativeFlatXmlDocuments |
FODT(原生產生,非由 ZIP 轉換) | 標題、段落、互通標記 | txt |
轉出文字含 OdfKit-LibreOffice-NativeFlat-Interop-Marker |
✅ |
| 同上 | FODS(原生產生) | 工作表互通標記 | xlsx |
轉出 XLSX 非空 | ✅ |
| 同上 | FODP(原生產生) | 文字方塊互通標記 | odp |
轉出 ODP 含互通標記 | ✅ |
| 同上 | FODG(原生產生) | 文字方塊互通標記 | png |
轉出 PNG 非空 | ✅ |
LibreOfficeHeadlessLoadsMasterDocument |
ODM | 段落、子文件參照、互通標記 | txt / odm |
LibreOffice 識別為 Writer master document(writerglobal8);轉出文字含互通標記;往返後子文件參照保留 |
✅ |
LibreOfficeHeadlessLoadsWebTemplateDocument |
OTH | 標題、段落、互通標記 | txt / odt |
LibreOffice 識別為 Writer/Web document(writerweb8_writer);轉出文字含互通標記;轉出 ODT 內容保留 |
✅ |
DatabaseSchemaPackageUsesLibreOfficeCompatibleMimeType |
ODB | 資料表、查詢、表單封裝 | (封裝層級,無 CLI 轉換) | mimetype/manifest media-type 與真實 LibreOffice 自建 ODB 完全一致;另以 UNO API desktop.loadComponentFromURL 人工驗證可成功載入 |
✅ |
LibreOfficeHeadlessExecutesManagedDocumentMacros |
ODT 1.0~1.4 | Basic 與 Python 文件巨集 | UNO script provider | 每個版本的兩個巨集各自寫出標記檔,並核對完整內容;Windows Portable 26.2.4.2 實測 | ✅ |
LibreOfficeUnoOpenPgpRealKeyBidirectionalRoundTrip |
OpenPGP ODT | 臨時 GnuPG RSA 金鑰、加密本文 | UNO 解密、修改、重新儲存 | 核對本文、LibreOffice 新增標記、wholesome OpenPGP manifest,再由 OdfKit 解密 | ✅ |
LibreOfficeHeadlessPivotTableRoundTripsOdsAndPdf |
ODS 1.4 | DataPilot 日期月份分組、列百分比、列欄總計、outline 版面、drill-down | ods / pdf |
往返後由 OdfKit 讀回 Pivot 定義;PDF 非空 | ✅ |
Apache OpenOffice 獨立驗收
ApacheOpenOfficeInteropTests 不再掛在 LibreOfficeInteropTests partial 型別下。測試使用
獨立的 ODFKIT_OPENOFFICE_PATH,並核對 Windows 檔案版本描述與公司必須是
Apache OpenOffice/Apache Software Foundation,不得誤用 LibreOffice。實機範圍包含
ODT/ODS/ODP/ODG 核心文件往返,以及進階 DataPilot ODS 往返與 PDF 匯出。
Windows 版 Apache OpenOffice 不提供可靠的 LibreOffice --convert-to CLI;測試因此啟動
限定 loopback 的 soffice headless listener,再使用 AOO 安裝包隨附的官方 Python/UNO
runtime 開啟、另存與匯出。PYTHONPATH 只設定於 bridge 子程序,不污染 runner 全域環境。
未明確要求時,沒有安裝 AOO 會略過;-RequireOpenOffice 會設定 fail-closed 模式,找不到
官方 runtime、UNO 連線失敗或路徑偽冒時皆失敗。
GitHub Actions 的手動 workflow 釘選 Apache OpenOffice 4.1.16,下載後依 Apache 官方
SHA-256 驗證。CI 使用 MSI administrative image 取得隔離的可攜執行樹,不修改 runner
的全機 Office 安裝;確認 soffice.exe 的公司為 Apache Software Foundation 後,再執行
net8.0 與 net10.0。
pwsh eng/Test-ApacheOpenOfficeInterop.ps1 `
-SofficePath "C:\Program Files (x86)\OpenOffice 4\program\soffice.exe" `
-RequireOpenOffice
已知上游限制(非 OdfKit 缺陷)
獨立(非嵌入 ODS/ODT/ODP)的 ODC/OTC/FODC 圖表文件,實測確認 LibreOffice 26.2.1 不接受 為可直接開啟的主文件:
| 格式 | 實測結果 |
|---|---|
.odc |
soffice --headless --convert-to txt 回報 source file could not be loaded |
.otc |
同上,回報 source file could not be loaded |
.fodc |
未回報錯誤,但被誤判為「Writer document」,僅原樣回顯來源 XML,並非真正剖析為圖表——不構成有效互通 |
ODF Chart 設計上即為僅可嵌入 ODS/ODT/ODP 內的子文件類型,並非獨立可開啟的主文件格式。
改以封裝結構與 schema 層級的精確驗證取代真機驗證(見
LibreOfficeInteropTests.OdfChartDocumentPackageStructureMatchesOdf14Schema),並以既有
「圖表嵌入 ODS 後由 LibreOffice 開啟」驗收(LibreOfficeHeadlessLoadsGeneratedDocuments 對
含圖表 ODS 的 xlsx 轉換)佐證嵌入式圖表的真實互通性。
獨立 OTF/FDF 公式範本與 Flat 變體同樣不被 LibreOffice 26.2.1 接受為可直接開啟的主文件:
| 格式 | 實測結果 |
|---|---|
.odf |
✅ 真機支援——LibreOffice 識別為「Math document」,使用 math8 篩選器;MathML 內容(含 mrow 群組)往返保留 |
.otf |
❌ soffice --headless --convert-to odf 回報 source file could not be loaded |
.fdf |
❌ 未回報錯誤,但被誤判為「Calc document」,以 calc_png_Export 篩選器產生與公式內容完全無關的輸出 |
ODF Formula 是唯一一個獨立 ZIP 主格式(.odf)確實有真機支援的次要格式(不同於 Chart/Image),
但其 Template/Flat 變體仍與 Chart/Image 的變體一樣不受支援。見
LibreOfficeInteropTests.LibreOfficeHeadlessLoadsFormulaDocument(.odf 真機驗收)與
OdfFormulaVariantDocumentPackageStructureMatchesOdf14Schema(.otf/.fdf 封裝結構驗證)。
獨立 ODI/OTI/FODI 影像文件同樣不被 LibreOffice 26.2.1 與 Microsoft Office 365 接受為可直接 開啟的主文件:
| 格式 | 實測結果 |
|---|---|
.odi |
❌ soffice --headless --convert-to png 回報 source file could not be loaded |
.oti |
❌ 同上,回報 source file could not be loaded |
.fodi |
❌ 未回報錯誤,但被誤判為「Writer document」,以 writer_png_Export 篩選器產生與影像內容完全無關的輸出 |
.fodi 的誤判模式與 .fodc(誤判為 Writer document)、.fdf(誤判為 Calc document)一致——
這修正了既有 ImageDocumentPackageStructureMatchesOdf14Schema 註解中原先聲稱「ODI/OTI/
FODI 一律回報 source file could not be loaded」的不準確描述(該描述對 ODI/OTI 成立,但對
FODI 並不成立)。改以封裝結構與 schema 層級的精確驗證取代真機驗證(該測試已擴充涵蓋
ODI/OTI/FODI 三者)。
ODB 資料庫文件的失效模式比 Chart/Image 更隱晦——並非乾淨的「could not be loaded」錯誤:
| 轉換目標 | 實測結果 |
|---|---|
odb(自身) |
❌ 明確回報 no export filter,非零結束碼失敗 |
txt/ods/xlsx/csv |
⚠️ 結束碼 0(看似成功),但輸出檔案經位元組層級檢查確認僅為來源 .odb 的逐位元組原樣複製,並未真正轉換——比清楚的錯誤訊息更具誤導性 |
這修正了既有 DatabaseSchemaPackageUsesLibreOfficeCompatibleMimeType 註解中原先聲稱「對既有
.odb 檔案執行 --convert-to 一律回報 source file could not be loaded」的不準確描述。改以封裝
層級 mimetype/manifest 驗證為主要自動化測試手段,並以已完成的 LibreOffice UNO API
(desktop.loadComponentFromURL)人工驗證佐證真實載入能力。
非目標(Wave 3 尚未涵蓋)
- 像素級視覺 diff(見 ooxml-visual-golden-matrix.md)
- Microsoft Word / Excel 開啟驗收
- 動畫播放、圖表樣式等編輯器行為驗證;進階 DataPilot 已涵蓋 OdfKit 物化、 LibreOffice 往返與 Apache OpenOffice 專用驗收入口
- 所有 24 種 extension 的封裝層級/互通驗收已於 Batch 1-6(2026-06-23)涵蓋完畢 (四主格式 template/flat 變體、.odm/.oth、Chart 全族、Formula 全族、Image 全族、 .odb 皆已驗證並記錄真實 LibreOffice 行為,包含已確認的上游限制);剩餘僅為本節其餘 列出的非目標項目(像素級視覺 diff、Office 開啟驗收、編輯器行為驗證)
相關測試
| 類別 | 說明 |
|---|---|
LibreOfficeInteropTests |
本矩陣的實機 headless 測試 |
ApacheOpenOfficeInteropTests |
Apache OpenOffice 四種核心格式與 DataPilot 實機 headless 測試 |
LibreOfficeScriptingInteropTests |
使用隔離 profile 實際執行 Basic/Python 文件巨集 |
TrackedChangesInteropTests |
追蹤修訂語意(非必須 LO) |
LoExtInteropTests |
loext:decorative 載入映射 |
LibreOfficeRenderer*Tests |
Extensions.Rendering 可替換 backend |