OpenOffice or LibreOffice UNO API
可以透過 Python 來處理 UNO 開放處理界面,而透過此自動化處理內容與資料,說不定是後續可以提供自動化工具的契機。
目前主要要處理很多頁面的 CSV 檔案,因此希望可以自動化處理儲存與轉換,幫助處理的 git rebase
的便利性。
UNO
在電腦技術領域中,「通用網路物件」(Universal Network Objects, UNO)是OpenOffice.org使用的元件模型。UNO基於對外介面的設計,得以使得多個元件夠過區域網路或網際網路,達成跨程式語言、跨物件模型,以及跨機器架構的相互溝通。
UNO 元件可以使用任何已定義有連結模組的程式語言去實作。目前UNO已定義有的程式語言連結有C++(但跟compiler有關)、Java和Python。程式語言連結並允許對於StarOffice Basic、OLE Automation以及.NET共同語言架構的存取,但無法作寫入元件的動作。
目前主要還是以 Apache 開發的 OpenOffice 為主的資料最多,但我記得 OpenOffice 也是台灣團隊製作的,後來被捐贈了,不過 OpenOffice 的協定可以與 LibreOffice 共同使用,我記得 LibreOffice 也是使用 OpenOffice 的標準,而 Google 自己也是依照 OpenOffice 所提供的資源,進行開發與處理製作成 Google 文件、 Google 試算表等產品,總之目前 UNO 本身是還有存在的,只是因為使用的人不多,所以應用的範圍廣泛程度不高。
- https://zh.wikipedia.org/zh-tw/OpenOffice.org
- https://wiki.openoffice.org/wiki/Python
- https://en.wikipedia.org/wiki/Universal_Network_Objects
- https://zh.wikipedia.org/zh-tw/%E9%80%9A%E7%94%A8%E7%B6%B2%E8%B7%AF%E7%89%A9%E4%BB%B6
- https://wiki.openoffice.org/wiki/Uno
- http://www.openoffice.org/api/docs/common/ref/com/sun/star/text/XTextRange.html
工具
目前看到的工具感覺也有 10 年沒有更新了,最早相關的 Python 檔案,也已經是 2010 左右,相關介紹網站與資源已經都不見了,只能從過去資料找。搭建的環境也在 ubuntu 14 ,可能會要使用容器搭建。
總之再看看了,會先嘗試 ChatGPT 與官方網站提供的教學,嘗試搭建。
查詢的資料:
- https://github.com/korcankaraokcu/UnoTagger
- https://github.com/t2y/unotools
- https://github.com/cwgaldino/pyCalc-wrapper
- https://github.com/galtonova/UNO
- https://github.com/kelsa-pi/unodit
- https://github.com/kelsa-pi/PyUNO_Workspace
- https://pypi.org/project/pyuno/
- https://wiki.openoffice.org/wiki/Python
- https://pypi.org/project/unotools/
- https://stackoverflow.com/questions/56417617/unotools-insert-image-into-document-libreoffice
- https://docs.libreoffice.org/unotools.html
開始與基本操作
要使用 LibreOffice 的指令程式將 .fodt 檔案內所有表格依序轉換為 .csv 檔案,可以按照以下步驟來實現:
-
安裝 LibreOffice:首先,確認系統中已經安裝了 LibreOffice。可以使用以下指令來安裝(適用於基於 Debian 的系統,如 Ubuntu):
sudo apt-get update sudo apt-get install libreoffice
-
編寫 Python 腳本:使用 Python 腳本來自動化這個過程。我們需要先安裝
unotools
模組,這樣就可以通過 Python 來控制 LibreOffice。pip install unotools
-
撰寫轉換腳本:編寫一個 Python 腳本,將 .fodt 檔案中的表格導出為 .csv 檔案。以下是一個範例腳本:
import uno from unohelper import Base, systemPathToFileUrl from com.sun.star.beans import PropertyValue import os def convert_fodt_tables_to_csv(input_file, output_dir): # 啟動 LibreOffice 在無頭模式 local_context = uno.getComponentContext() resolver = local_context.ServiceManager.createInstanceWithContext( "com.sun.star.bridge.UnoUrlResolver", local_context) context = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") desktop = context.ServiceManager.createInstanceWithContext( "com.sun.star.frame.Desktop", context) # 打開 .fodt 文件 input_url = systemPathToFileUrl(os.path.abspath(input_file)) properties = [PropertyValue("Hidden", 0, True, 0)] document = desktop.loadComponentFromURL(input_url, "_blank", 0, properties) # 提取表格並導出為 .csv table_count = document.getTextTables().getCount() for i in range(table_count): table = document.getTextTables().getByIndex(i) table_name = table.getName() csv_url = systemPathToFileUrl(os.path.join(output_dir, f"{table_name}.csv")) properties = [ PropertyValue("FilterName", 0, "Text - txt - csv (StarCalc)", 0), PropertyValue("FilterOptions", 0, "44,34,76,1,,0,true", 0) # 根據需要自訂 ] document.storeToURL(csv_url, properties) print(f"已導出 {table_name} 到 {csv_url}") # 關閉文件 document.close(True) if __name__ == "__main__": input_file = "path/to/your/file.fodt" # 替換為你的 .fodt 文件路徑 output_dir = "path/to/output/directory" # 替換為你想要保存 .csv 文件的資料夾 convert_fodt_tables_to_csv(input_file, output_dir)
-
啟動 LibreOffice 監聽器:在執行腳本之前,需要啟動 LibreOffice 的監聽器,讓腳本能夠連接到 LibreOffice。可以使用以下指令啟動監聽器:
soffice --headless --accept="socket,host=localhost,port=2002;urp;StarOffice.ServiceManager"
-
執行腳本:最後,執行上面的 Python 腳本,將所有表格導出為 .csv 檔案。
python convert_fodt_tables_to_csv.py
這個腳本會打開指定的 .fodt 檔案,提取其中的所有表格,並將每個表格保存為一個 .csv 檔案。你可以根據需要調整 PropertyValue
中的 FilterOptions
參數,以自訂 .csv 檔案的導出選項。
如果你遇到任何問題或有特定需求,請告訴我,我可以進一步幫助你。
FilterOptions 選項說明
FilterOptions
是 LibreOffice 在儲存或匯出檔案時,用來設定檔案格式特定選項的屬性。當我們將表格儲存為 .csv 檔案時,可以通過 FilterOptions
來指定 CSV 的分隔符號、文字限定符號、編碼等詳細設定。
在上面的範例腳本中,FilterOptions
的設置是:
PropertyValue("FilterOptions", 0, "44,34,76,1,,0,true", 0)
這段設置的含義如下:
-
44
:欄位分隔符號的 ASCII 代碼,44 代表逗號(,
)。 -
34
:文字限定符號的 ASCII 代碼,34 代表雙引號("
)。 -
76
:字元編碼,76 代表 UTF-8。 -
1
:每一列的起始行號(1 表示從第一行開始)。 -
,
:小數點的分隔符號(空表示使用系統預設)。 -
0
:匯出所有的欄位(0 表示匯出全部欄位)。 -
true
:是否保留文字格式。
以下是這些設定的更詳細說明:
-
欄位分隔符號:指定欄位之間的分隔符號,如逗號(
,
),分號(;
),或其他符號。 -
文字限定符號:指定文字資料的包圍符號,如雙引號(
"
)。 - 字元編碼:指定 CSV 檔案的編碼格式,76 代表 UTF-8。
- 起始行號:指定從哪一行開始匯出資料,通常設定為 1。
- 小數點分隔符號:指定小數點符號,空字串表示使用系統預設。
- 欄位選擇:0 表示匯出所有欄位。
-
保留文字格式:指定是否保留文字格式,
true
表示保留。
你可以根據需要調整這些選項,例如,如果你希望使用分號(;
)作為欄位分隔符號,可以將 44
改為 59
:
PropertyValue("FilterOptions", 0, "59,34,76,1,,0,true", 0)
這將產生一個使用分號分隔欄位的 .csv 檔案。
如果有更多特定需求或需進一步解釋,請告訴我,我可以提供更詳細的說明或修改腳本以符合你的需求。
參數控制
問題:我記得libreoffice 可以控制是不是要欄位內容以公式輸出,請問該怎麼改動呢?
是的,LibreOffice 的 FilterOptions
參數可以控制 CSV 檔案的導出細節,包括是否將欄位內容以公式形式輸出。這通常是在處理電子表格時需要考慮的。
在 FilterOptions
的設定中,有些選項可以用來控制這些細節。這些選項是以逗號分隔的字符串,具體格式和含義可以參考 LibreOffice 的官方文件。
一般情況下,設定 FilterOptions
來控制是否輸出公式,可以透過添加適當的選項來實現。以下是一些可能的選項:
-
Save cell formulas instead of results
:指定是否保存儲存格公式而不是結果。
根據你提到的需求,我們可以修改腳本來控制公式的輸出。這裡假設我們需要添加或調整 FilterOptions
的適當值來達到目的:
import uno
from unohelper import systemPathToFileUrl
from com.sun.star.beans import PropertyValue
import os
def convert_fodt_tables_to_csv(input_file, output_dir):
# 啟動 LibreOffice 在無頭模式
local_context = uno.getComponentContext()
resolver = local_context.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", local_context)
context = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
desktop = context.ServiceManager.createInstanceWithContext(
"com.sun.star.frame.Desktop", context)
# 打開 .fodt 文件
input_url = systemPathToFileUrl(os.path.abspath(input_file))
properties = [PropertyValue("Hidden", 0, True, 0)]
document = desktop.loadComponentFromURL(input_url, "_blank", 0, properties)
# 提取表格並導出為 .csv
table_count = document.getTextTables().getCount()
for i in range(table_count):
table = document.getTextTables().getByIndex(i)
table_name = table.getName()
csv_url = systemPathToFileUrl(os.path.join(output_dir, f"{table_name}.csv"))
properties = [
PropertyValue("FilterName", 0, "Text - txt - csv (StarCalc)", 0),
PropertyValue("FilterOptions", 0, "44,34,76,1,,0,true,true", 0) # 增加導出公式
]
document.storeToURL(csv_url, properties)
print(f"已導出 {table_name} 到 {csv_url}")
# 關閉文件
document.close(True)
if __name__ == "__main__":
input_file = "path/to/your/file.fodt" # 替換為你的 .fodt 文件路徑
output_dir = "path/to/output/directory" # 替換為你想要保存 .csv 文件的資料夾
convert_fodt_tables_to_csv(input_file, output_dir)
在這個範例中,FilterOptions
最後一個 true
表示保存公式。如果你只想保存公式而不顯示計算結果,可以將其設為 true
,如果不需要則設為 false
。
請注意,上述腳本假設已正確安裝和配置了 LibreOffice 以及 Python 的 unotools
模組。運行之前,確保啟動了 LibreOffice 的監聽器:
soffice --headless --accept="socket,host=localhost,port=2002;urp;StarOffice.ServiceManager"
這樣,你應該可以成功將 .fodt 檔案中的表格導出為 .csv 檔案,並且可以選擇是否以公式形式導出欄位內容。如果有任何問題或需要更多調整,請告訴我。