Dbgrid 記錄匯出至 openoffice.calc |
|
kadee
高階會員 發表:11 回覆:141 積分:165 註冊:2002-03-20 發送簡訊給我 |
分享一個function,可以將Dbgrid 記錄匯出至 openoffice.calc.
希望可以推廣ooo的應用
function gfSendToOpenOffice(poGrid: tdbgrid; psTitle: string = ''; psFilename: string = ''): boolean; var i, liR0, liRow, liCol: integer; lCol: TColumn; lfield: TField; objServiceManager, objDesktop, oDocument, osheets, osheet: OleVariant; objDocName, objDocParam, objDocNum, objParam: variant; AEVENT: TDataSetNotifyEvent; procedure setsheetvalue(ic, ir: integer; objsheet: OleVariant; psvalue: string); begin objsheet.getCellByPosition(ic, ir).string := psvalue; end; procedure setsheetint(ic, ir: integer; objsheet: OleVariant; psvalue: string); begin objsheet.getCellByPosition(ic, ir).Formula := '=' psvalue; end; begin aEvent := poGrid.DataSource.DataSet.AfterScroll; Result := true; try poGrid.DataSource.DataSet.AfterScroll := nil; poGrid.DataSource.DataSet.DisableControls; try // The service manager is always the starting point // If there is no office running then an office is started up objServiceManager := CreateOLEObject('com.sun.star.ServiceManager'); // Create the Desktop objDesktop := objServiceManager.createInstance ('com.sun.star.frame.Desktop'); // Open a new empty writer document objDocName := 'private:factory/scalc'; objDocParam := '_blank'; objDocNum := 0; objParam := VarArrayCreate([0, 1], VarVariant); objParam[0] := ''; // .Name = '' objParam[1] := 0; // .Value = 0 oDocument := objDesktop.loadComponentFromURL (objDocName, objDocParam, 0, VarArrayOf([])); oSheets := oDocument.Sheets; if oSheets.hasByName('工作表1') then oSheet := oSheets.getByName('工作表1') else oSheet := oDocument.createInstance ('com.sun.star.sheet.Spreadsheet'); liCol := 0; liR0 := 0; //row if psTitle <> '' then begin //表單標題 setsheetvalue(0, 0, osheet, psTitle); inc(lir0); end; for i := 0 to poGrid.Columns.Count - 1 do begin lCol := poGrid.Columns[i]; lfield := lcol.Field; if lfield = nil then continue; //寬度縮太小之欄位不轉出 if (lCol.Width < 15) then continue; //轉入欄位標題 liRow := liR0 1; setsheetvalue(liCol, liRow, osheet, lfield.DisplayLabel); //轉入欄位之資料 poGrid.DataSource.DataSet.first; inc(liRow); while not poGrid.DataSource.DataSet.eof do begin if (not lfield.isnull) then begin case lfield.DataType of ftString: if (lfield.asstring <> '') then setsheetvalue(liCol, liRow, osheet, lfield.AsString); ftBCD, ftInteger, ftFloat, ftCurrency, ftSmallint: setsheetint(liCol, liRow, osheet, lfield.asstring); ftDate, ftTime, ftDateTime: setsheetvalue(liCol, liRow, osheet, lfield.AsString); end; //case end; //isnull poGrid.DataSource.DataSet.Next; inc(liRow); end; //while } inc(liCol); end; //for result := true; except gpmsg('無法啟動 open-office !!', false); if DebugHook > 0 then raise; end; //try finally poGrid.DataSource.DataSet.AfterScroll := aevent; poGrid.DataSource.DataSet.EnableControls; end; end;Kadee_BigRed
------
Kadee/BigRed Ent. www.tw165.com |
bugmans
高階會員 發表:95 回覆:322 積分:188 註冊:2003-04-12 發送簡訊給我 |
我在OpenOffice 1.1.2開始接觸這個軟體,雖然功能不比微軟的Office強
(在1.1.x的版本中,表格的儲存格高度無法用滑鼠調整,只能利用換行來調整, 或是開啟含中文字的檔案會出現方塊字,這些問題在OpenOffice2.0已有大幅度 的改善),但這個軟體所強調開放自由的精神卻是讓我非常認同的,我也嘗試著 用OpenOffice進行簡單的文書處理,後來開始接觸OpenOffice的Macro和API,我 回到Delphi K.Top搜尋是否有相關的討論,很可惜的是有關於OpenOffice程式 設計的只有kadee所發表的"Dbgrid 記錄匯出至openoffice.calc"(也就是各位 看到的這篇),於是我將近日所研究的結果發表出來,以期達到拋磚引玉的效果 因為我比較常用Writer(相對於微軟的Word)寫報告,所以之後的程式碼都是針對 Writer來說明,在BCB6要多加 [code cpp] #include [/code] 出處http://delphi.ktop.com.tw/topic.php?TOPIC_ID=42389 [code cpp] void __fastcall TForm1::FormCreate(TObject *Sender) { //開啟空白的Writer檔案 Variant vService = CreateOleObject("com.sun.star.ServiceManager"); Variant vDesktop = vService.OleFunction("createInstance", "com.sun.star.frame.Desktop"); Variant vEmptyParam(OPENARRAY(int, (0, -1)), varInteger); Variant vDocument = vDesktop.OleFunction("loadComponentFromURL", "private:factory/swriter", "_blank", 0, vEmptyParam); //插入文字 //出處http://mail.python.org/pipermail/python-win32/2002-May/000359.html Variant vText = vDocument.OleFunction("GetText"); Variant vCursor = vText.OleFunction("CreateTextCursor"); vText.OleFunction("insertString",vCursor,"測試",false); //插入表格 //出處:StarSuite 7 程式設計手冊 106 107頁 Variant vTable = vDocument.OleFunction("createInstance","com.sun.star.text.TextTable"); vTable.OleFunction("initialize",5,4); vText.OleFunction("insertTextContent",vCursor,vTable,false); //在儲存格中插入文字 Variant vCell=vTable.OleFunction("getCellByName","B2"); vCell.OlePropertySet("String","儲存格文字"); //改變表格背景顏色 //出處:StarSuite 7 程式設計手冊 108頁 Variant vRows = vTable.OleFunction("getRows"); Variant vRow; for(int i=0;i<2;i ) //出處http://www.oooforum.org/forum/viewtopic.phtml?t=14326 Variant Cursor =vTable.OleFunction("createCursorByCellName","A1"); Cursor.OleFunction("splitrange",3,false); //插入圖片 Variant vImage = vDocument.OleFunction("createInstance","com.sun.star.text.GraphicObject"); vImage.OlePropertySet("GraphicURL","file:///C:/WINNT/Soap Bubbles.bmp"); vText.OleFunction("insertTextContent",vCursor,vImage,false); //儲存檔案 vDocument.OleFunction("storeToURL","file:///c:/test.odt",vEmptyParam); //vDocument.OleFunction("Close",true); } [/code] 以上幾個範例無法滿足實作上的需求,我再介紹幾個參考文件讓各位在學習OpenOffice API 時更加順手 StarSuite 7 Office Suite - Basic 程式設計手冊(繁體中文) http://docs-pdf.sun.com/817-3928/817-3928.pdf 雖然是StarSuite但是OpenOffice也是同樣適用,從第五章開始開始介紹API,裡面的範例非常 淺顯易懂,更何況是繁體中文的內容,非常建議仔細閱讀 OpenOffice.org Macros and API論壇 http://www.oooforum.org/forum/viewforum.phtml?f=9 這裡是討論OpenOffice API最熱鬧的地方,我反倒覺得假如有關API的問題應該到這裡來問, 到Delphi K.Top發問可能會無人回應 http://www.pitonyak.org/AndrewMacro.sxw Andrew Pitonyak針對論壇上常發問的問題作個整理 例如上面的範例中插入圖片的程式碼 [code cpp] Variant vImage = vDocument.OleFunction("createInstance","com.sun.star.text.GraphicObject"); vImage.OlePropertySet("GraphicURL","file:///C:/WINNT/Soap Bubbles.bmp"); vText.OleFunction("insertTextContent",vCursor,vImage,false); [/code] 這個方法有個缺點是圖不會包在文件檔中,在7.15.3 Can I embed or link a graphics object? 有提到解決方法 出處:http://www.oooforum.org/forum/viewtopic.phtml?t=11183 OpenOffice SDK(英文版) http://www.openoffice.org/dev_docs/source/sdk/ StarSuite7 SDK(簡體中文版) http://192.18.97.244/ECom/EComTicketServlet/BEGINBD9B3C6D81227F09EDE32F1E5350852D/ 98986803/768474195/1/359978/467702/768474195/2ts /westCoastFSEND/SOSDK-7-G-F/ SOSDK-7-G-F:8/StarSuite7_SDK_zh-CN.zip 其實StarSuite 7 的SDK和OpenOffice SDK內容是相同的,但建議下載StareSutie SDK,因為 StarSuite SDK有簡體中文的版本,但OpenOffice SDK沒有 |
a903
一般會員 發表:5 回覆:13 積分:3 註冊:2003-08-27 發送簡訊給我 |
|
adson
一般會員 發表:0 回覆:2 積分:0 註冊:2007-12-17 發送簡訊給我 |
|
kadee
高階會員 發表:11 回覆:141 積分:165 註冊:2002-03-20 發送簡訊給我 |
|
adson
一般會員 發表:0 回覆:2 積分:0 註冊:2007-12-17 發送簡訊給我 |
不好意思, 您說的在ooo calc中存成 excel,再用ADO去連, 我沒能理解.
您的意思是說在calc中將做好的資料保存為excel格式嗎? 之前用excel上傳資料的時候,程序是這樣的: 在上傳畫面中,使用opendialog先打開excel檔案的, 點上傳按鈕後,即可將各欄位的內容保存到資料庫表所對應的各個欄位中. 但是現在openoffice時, 我就仿照您帖子上從dbgrid中匯入openoffice工作表這個程式, 還是不可以的, 關鍵我覺得其中的一些method 不知道, 這個和 MS Office是不一樣的. 運行的時候 總是提示method not surpported variant .
------
年少輕狂,幸福時光 |
Reiji
初階會員 發表:30 回覆:57 積分:32 註冊:2008-06-26 發送簡訊給我 |
不好意思,最近公司也在推OO.o 但是遇到了一個問題 那就是TDBGrid中有MEMO欄位時,轉出至OO.o會空白(EXCEL不會) 不曉得有沒有前輩也有遇過? 該如何解決? 結果剛發問完就發現我眼睛太大了,沒找到問題出處 在此PO文自答,當筆記 在程式其中一段加入需要轉出的格式即可 |
Reiji
初階會員 發表:30 回覆:57 積分:32 註冊:2008-06-26 發送簡訊給我 |
過了這麼久,大概也研究出來了吧?
但當作是筆記,我就在此回覆好了 我遇到這個問題是 oDocument := objDesktop.loadComponentFromURL 在程式跑到setsheetvalue中的osheet無法取得目標 解決的方法就是在===================引 用 a903 文 章=================== 使用 gfSendToOpenOffice 在 Call setsheetvalue(0, 0, osheet, psTitle) 出現 com.sun.star.uno.RunTimeException 請問如何解
------
永遠都是新手 |
anchor
一般會員 發表:0 回覆:3 積分:0 註冊:2013-03-27 發送簡訊給我 |
|
Reiji
初階會員 發表:30 回覆:57 積分:32 註冊:2008-06-26 發送簡訊給我 |
www.openoffice.org/api/docs/common/ref/com/sun/star/frame/XComponentLoader.html
objDocName, objDocParam宣告的型態、值的型態 依原PO的例子來說 variant,值為字串: 'private:factory/scalc' '_blank' 也就是 (,
------
永遠都是新手 |
anchor
一般會員 發表:0 回覆:3 積分:0 註冊:2013-03-27 發送簡訊給我 |
我是將整個Function COPY 下來,其中有修改某些行
1. 在uses 增加 ,ComObj ==>因為此函數系統不認的CreateOLEObject('com.sun.star.ServiceManager'); 2. 這一行 ,因為無法執行 "gpmsg('無法啟動 open-office !!', false);" 改為 "showmessage( '無法啟動 open-office !!');" 接下來button 鍵,下的参數為==> gfSendToOpenOffice(tdbgrid1,'',''); 其中tdbgrid1 指我的dbgrid 的物件名, 然後開始執行就出現錯誤訊息 |
Reiji
初階會員 發表:30 回覆:57 積分:32 註冊:2008-06-26 發送簡訊給我 |
|
anchor
一般會員 發表:0 回覆:3 積分:0 註冊:2013-03-27 發送簡訊給我 |
以下是我程式內容, 麻煩你,謝謝
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Grids, DBGrids, DB, DBTables,ComObj; type TForm1 = class(TForm) Button1: TButton; Table1: TTable; DataSource1: TDataSource; tdbgrid1: TDBGrid; Button2: TButton; Table1subjno: TIntegerField; Table1subjnm: TStringField; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; //Form2: TForm2; implementation uses Unit2; {$R *.dfm} function gfSendToOpenOffice(poGrid: tdbgrid; psTitle: string = ''; psFilename: string = ''): boolean; var i, liR0, liRow, liCol: integer; lCol: TColumn; lfield: TField; objServiceManager, objDesktop, oDocument, osheets, osheet: OleVariant; objDocName, objDocParam, objDocNum, objParam: variant; AEVENT: TDataSetNotifyEvent; procedure setsheetvalue(ic, ir: integer; objsheet: OleVariant; psvalue: string); begin objsheet.getCellByPosition(ic, ir).string := psvalue; end; procedure setsheetint(ic, ir: integer; objsheet: OleVariant; psvalue: string); begin objsheet.getCellByPosition(ic, ir).Formula := '=' psvalue; end; begin aEvent := poGrid.DataSource.DataSet.AfterScroll; Result := true; try poGrid.DataSource.DataSet.AfterScroll := nil; poGrid.DataSource.DataSet.DisableControls; try // The service manager is always the starting point // If there is no office running then an office is started up objServiceManager := CreateOLEObject('com.sun.star.ServiceManager'); // Create the Desktop objDesktop := objServiceManager.createInstance ('com.sun.star.frame.Desktop'); // Open a new empty writer document objDocName := 'private:factory/scalc'; objDocParam := '_blank'; objDocNum := 0; objParam := VarArrayCreate([0, 1], VarVariant); objParam[0] := ''; // .Name = '' objParam[1] := 0; // .Value = 0 oDocument := objDesktop.loadComponentFromURL (objDocName, objDocParam, 0, VarArrayOf([])); oSheets := oDocument.Sheets; if oSheets.hasByName('工作表1') then oSheet := oSheets.getByName('工作表1') else oSheet := oDocument.createInstance ('com.sun.star.sheet.Spreadsheet'); liCol := 0; liR0 := 0; //row if psTitle <> '' then begin //表單標題 setsheetvalue(0, 0, osheet, psTitle); inc(lir0); end; for i := 0 to poGrid.Columns.Count - 1 do begin lCol := poGrid.Columns[i]; lfield := lcol.Field; if lfield = nil then continue; //寬度縮太小之欄位不轉出 if (lCol.Width < 15) then continue; //轉入欄位標題 liRow := liR0 1; setsheetvalue(liCol, liRow, osheet, lfield.DisplayLabel); //轉入欄位之資料 poGrid.DataSource.DataSet.first; inc(liRow); while not poGrid.DataSource.DataSet.eof do begin if (not lfield.isnull) then begin case lfield.DataType of ftString: if (lfield.asstring <> '') then setsheetvalue(liCol, liRow, osheet, lfield.AsString); ftBCD, ftInteger, ftFloat, ftCurrency, ftSmallint: setsheetint(liCol, liRow, osheet, lfield.asstring); ftDate, ftTime, ftDateTime: setsheetvalue(liCol, liRow, osheet, lfield.AsString); end; //case end; //isnull poGrid.DataSource.DataSet.Next; inc(liRow); end; //while } inc(liCol); end; //for result := true; except //gpmsg('無法啟動 open-office !!', false); showmessage( '無法啟動 open-office !!'); if DebugHook > 0 then raise; end; //try finally poGrid.DataSource.DataSet.AfterScroll := aevent; poGrid.DataSource.DataSet.EnableControls; end; end; procedure TForm1.Button1Click(Sender: TObject); begin Form2 := TForm2.Create(Application); Form2.Show; end; procedure TForm1.Button2Click(Sender: TObject); begin gfSendToOpenOffice(tdbgrid1,'',''); end; procedure TForm1.FormCreate(Sender: TObject); begin end; end. |
Reiji
初階會員 發表:30 回覆:57 積分:32 註冊:2008-06-26 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |