- Python 、 OOo 與報表 □ 文/Thinker
OpenOffice.org(OOo)是重量級的開放原始碼(OSS)專案,提供 MS office 的對等功能,具備讀取 MS Office 文件的能力。另一方面,由於 OSS 的開放特性,OpenOffice.org 擁有更多的可能性。其中一項特性,即是和其它語言的聯結能力。透過相當於 MS CO...
OpenOffice.org(OOo)是重量級的開放原始碼(OSS)專案,提供 MS office 的對等功能,具備讀取 MS Office 文件的能力。另一方面,由於 OSS 的開放特性,OpenOffice.org 擁有更多的可能性。其中一項特性,即是和其它語言的聯結能力。透過相當於 MS COM 的 Universal Network Objects(UNO)程式介面,OpenOffice.org 提供與多種 scripting 語言聯結的能力,以擴充其功能,或結合其它系統,以提供服務。
即使在網路普遍的今天,實體報表在商業環境中依然有很大的需求。但許多時候透過 OSS solution 產生報表總是力不從心,原因在於沒有像 Crystal Report 這套商業軟體一樣好的報表工具。然而專業的報表 工具,其價不裴,其用有限。大部分時侯,我們使用 OOo 就可以產生所需的報表。再加以 OOo 和各種程式語言結合的能力,實為 OSS 最有生產力的 report 環境。本文就以 OOo 作為報表工具,提供 OSS solutuion。
OOo 的編輯功能
OOo 包括了許多功能,其中最常用的大概就是 Writer 和 Calc。 Writer 相當於 MS Word,而 Calc 相當於 MS Excel。大部分的報表不外乎公告、單據之類,用 Writer 能處理。另一方面,可能是數據、圖表,可用 Calc 產生。
Writer
經常,我們可能需要列印一些單據、合約之類的內容。內容大致上只是更換幾個欄位,如姓名、住址、電話之類的資料。這類表格,經常是使用 Writer 之類的文書處理器解決。人工的處理方式,是先建立一個範例檔,之後每次打開檔案,修改這些欄位的內容,然後列印抑或另存新檔。透過 OOo 的 script 聯結,我們可以線上自動完成這些流程,立即產生單據、合約。
Calc
而數據,大概是老闆們最想要的東西。我們有各式各樣的統計數據,透過 Calc 整理、試算和分析之後,得到一些結果。甚至,必需將分析的結果以圖表的方式表現。例如: 長條圖、曲線圖等。這些定期要做的事,內容和流程往往是固定的,最適合自動化處理了。
UNO
經常,我們可能需要列印一些單據、合約之類的內容。內容大致上只是更換幾個欄位,如姓名、住址、電話之類的資料。這類表格,經常是使用 Writer 之類的文書處理器解決。人工的處理方式,是先建立一個範例檔,之後每次打開檔案,修改這些欄位的內容,然後列印抑或另存新檔。透過 OOo 的 script 聯結,我們可以線上自動完成這些流程,立即產生單據、合約。
而數據,大概是老闆們最想要的東西。我們有各式各樣的統計數據,透過 Calc 整理、試算和分析之後,得到一些結果。甚至,必需將分析的結果以圖表的方式表現。例如: 長條圖、曲線圖等。這些定期要做的事,內容和流程往往是固定的,最適合自動化處理了。
UNO
OOo 提供類似於 MS COM 的介面,UNO 媒介程式語言和 OOo 建構的元件環境。透過 UNO,程式語言能夠存取 OOo 的物件,修改其內容。例如: 修改 text document,或者填入 spreadsheet 的欄位內容。
UNO 是跨平台、跨程式語言、透過網路進行通訊的物件環境。目前提供 C++、Java、Python...多種語言的 binding,其中 PyUNO 即為 Python 的 language binding。
PyUNO
PyUNO 是 UNO 的 Python binding,作為 Python 和 OOo 的溝通媒介。
啟動 OOo
在使用 PyUNO 之前,必需先啟動 OOo,使之開始接受 connection 。
-
openoffice.org -accept="socket,host=localhost,port=2002;urp;"
OOo 將 listen port 2002,接受來自 localhost 的服務請求。
製作報表
收據之類的大部分表單,只需填入固定的資料欄位就可以產生。OOo 的 input field 就是製作這些欄位用的。input field 的使用方式,就是在 text document 裡,
使用 Insert -> Fields -> Other
選擇 Variables tab
在 Types 列表選擇 User Field
輸入 Name 和 Value
按 Insert button
如此就建立一個新欄位。在欄位上面點一下,即會跳出編輯畫面。
這裡我們建立一個收據範例的 template,存成 receipt.ott。
產生報表
使用 PyUNO,寫簡單幾行程式,很快就能置換表單內的欄位,並輸出 PDF 檔。
-
1 #!python 2 import uno 3 from com.sun.star.beans import PropertyValue 4 5 localContext = uno.getComponentContext() 6 resolver = localContext.ServiceManager.createInstanceWithContext( \ 'com.sun.star.bridge.UnoUrlResolver', localContext ) 7 8 ctx = resolver.resolve( 'uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext' ) 9 smgr = ctx.ServiceManager 10 11 def new_template(url): 12 desktop = smgr.createInstanceWithContext( 'com.sun.star.frame.Desktop', ctx) 13 14 pv = PropertyValue() 15 pv.Name = 'AsTemplate' 16 pv.Value = True 17 pvs = (pv,) 18 temp = desktop.loadComponentFromURL(url, '_blank', 0, pvs) 19 20 return temp 21 22 def change_field(temp, name, value): 23 named_text_fields = temp.getTextFieldMasters() 24 field_master = named_text_fields.getByName('com.sun.star.text.FieldMaster.User.' + name) 25 field_master.setPropertyValue('Content', value) 26 pass 27 28 29 temp_file = 'file:///path/to/OOo_n_report/receipt.ott' 30 pdf_file = 'file:///path/to/OOo_n_report/receipt.pdf' 31 32 # load template 33 temp = new_template(temp_file) 34 35 # change value of fields 36 change_field(temp, 'client_name', 'Thinker') 37 change_field(temp, 'feed_month', '12') 38 change_field(temp, 'year', '2007') 39 change_field(temp, 'month', '12') 40 change_field(temp, 'day', '11') 41 42 # update fields 43 temp.getTextFields().refresh() 44 45 # export to a PDF file 46 pv = PropertyValue() 47 pv.Name = 'FilterName' 48 pv.Value = 'writer_pdf_Export' 49 pvs = (pv,) 50 temp.storeToURL(pdf_file, pvs) 51 52 # close the template 53 temp.dispose()
結論
PyUNO 提供 OOo 和 Python 的介面,使得 OOo 成為絕佳的報表環境。或許效能還有待改進,但隨著應用日漸,效能的改進也可以期待。
shrink this item