一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Go 語(yǔ)言腳本化調(diào)用 Excelize 操作 Excel,簡(jiǎn)潔零依賴,生成獨(dú)立 EXE

 江海博覽 2024-10-06
aardio
aardio
2024-06-01 11:30優(yōu)質(zhì)科技領(lǐng)域創(chuàng)作者

Go 有一個(gè)開(kāi)源的 Excelize 很強(qiáng)大,可用于操作 Excel 表格。

看著 Excelize 范例里絲滑的 Go 代碼,我就想著怎么能弄到 aardio 里用。先嘗試把 Go 對(duì)象封包到 IDispatch 接口,然后又用 Go 反射整了幾個(gè)小時(shí),最后都放棄了。

后面繼續(xù)調(diào)整思路,改為調(diào)用在運(yùn)行時(shí)用 Go 語(yǔ)法寫腳本的 Yaegi (不需要安裝 Go 編譯環(huán)境,體積小速度快,內(nèi)存加載沒(méi)有外部依賴 ),一頓封裝實(shí)現(xiàn)了在 aardio 里運(yùn)行時(shí)執(zhí)行 Go 代碼、讀寫 Go 變量、調(diào)用 Go 函數(shù)。

一、 aardio 運(yùn)行 Yaegi(Go 腳本)

aardio 代碼示例:

//創(chuàng)建 Yaegi(Go 腳本)解釋器 import golang.yaegi; var go = golang.yaegi(); //直接用 Go 語(yǔ)法寫腳本。 go.eval(` package main //導(dǎo)入內(nèi)建模塊 import 'fmt' //編寫函數(shù) func Hello(name string) string { return name; } //全局變量 var GlobaVal = '這是全局變量'; `) //在 aardio 中直接調(diào)用 Go 函數(shù) var ret = go.Hello( 'Hello' ); //在 aardio 中修改 Go 全局常量的值 go.GlobaVal = '新的 Go 全局常量值'; import console.int; //獲取 Go 全局常量的值 console.log( go.GlobaVal );

二、調(diào)用 Excelize 操作 Excel 表格

然后調(diào)用 Excelize 就變簡(jiǎn)單了。

基于上面的原理,我又寫了一個(gè) golang.excelize 擴(kuò)展庫(kù)。然后只要直接復(fù)制粘貼 Excelize 官方的 Go 代碼范例就可以在 aardio 里用了。

直接看 aardio 代碼:

import console.int; 
import golang.excelize;
var go = golang.excelize();

//直接用 Go 語(yǔ)法寫腳本。 
go.eval(`
package main

import (
    'fmt'  
    
    //golang.excelize 已經(jīng)提前導(dǎo)入,不用再下載安裝外部模塊
    'github.com/xuri/excelize/v2'
)

func CreateExcel(path string)  string {
    
    //下面是 Excelize 官網(wǎng)范例
    f := excelize.NewFile();
    
    defer func() {
        if err := f.Close(); err != nil {
            fmt.Println(err)
        }
    }()
    
    // 創(chuàng)建新表格.
    index, err := f.NewSheet('Sheet2')
    if err != nil {
        fmt.Println(err)
        return ''
    }
    
    // 設(shè)置單元格的值.
    f.SetCellValue('Sheet2', 'A2', 'Hello world.')
    f.SetCellValue('Sheet1', 'B2', 100)
    
    // 設(shè)置工作簿的當(dāng)前激活表格
    f.SetActiveSheet(index)
    
    // 保存表格到指定的路徑
    if err := f.SaveAs(path); err != nil {
        fmt.Println(err)
    } 

    //讀單元格的值
    cell, err := f.GetCellValue('Sheet1', 'B2')
    if err != nil {
        fmt.Println(err)
        return ''
    }
    
    return cell;
}`) 
 
//在 aardio 中直接調(diào)用 Go 函數(shù) 
var ret = go.CreateExcel( io.fullpath('/hello.xlsx') );

//查看 Go 函數(shù)的返回值
console.log( ret );

三、Yaegi 導(dǎo)入第三方模塊

這里說(shuō)一下 Yaegi 導(dǎo)入第三方模塊的步驟。

以 aardio 中的 golang.excelize 擴(kuò)展庫(kù)為例。打開(kāi)生成 DLL 的源文件:

'~\lib\golang\excelize\.dll\編譯.aardio'

然后在 Go 源碼里可以看到這個(gè)全局常量:

var Symbols = map[string]map[string]reflect.Value{}

這個(gè) Symbols 就是符號(hào)表,第三方模塊都放到這里面。

例如我們要添加 aardio 模塊?,在創(chuàng)建解釋器以后就這么寫:

//創(chuàng)建 Yaegi 解釋器 yaegiInterpreter = interp.New(interp.Options{}) yaegiInterpreter.Use(stdlib.Symbols) //添加第三方模塊 Symbols['aardio/aardio'] = map[string]reflect.Value{ 'Call': reflect.ValueOf(aardio.Call), 'CallPtr': reflect.ValueOf(aardio.CallPtr), 'CallJson': reflect.ValueOf(aardio.CallJson), 'JsonParam': reflect.ValueOf(aardio.JsonParam), } //注冊(cè)到解釋器 yaegiInterpreter.Use(Symbols);

Symbols 可以理解為 aardio 里的表對(duì)象,每個(gè)鍵值對(duì)注冊(cè)一個(gè)?第三方模塊。比較坑的地方是這個(gè)鍵名 'aardio/aardio' 要寫兩次。

如果是非常大的模塊,手動(dòng)寫?就不現(xiàn)實(shí)了。這時(shí)候可以用 Yaegi 提供的工具?自動(dòng)生成符號(hào)表。為了避免被坑,可以直接運(yùn)行我提供的 aardio 代碼生成,以 Excelize 為例:

//提取符號(hào)表
import console.int; 
import golang;
 
var go = golang('/','1.22.3') 
go.mod('init excelize') 
go.get('github.com/xuri/excelize/v2') 
go.yaegiExtract('github.com/xuri/excelize/v2')

沒(méi)有任何顯示是正常的,耐心等到完成?。打開(kāi)自動(dòng)生成的

github_com-xuri-excelize-v2.go

?有了前面的知識(shí),看生成的代碼你就知道怎么做了。

四、Yaegi(Go 腳本)回調(diào) aardio 函數(shù)

?直接看代碼:

//aardio 回調(diào)函數(shù)
import golang.yaegi;
var go = golang.yaegi();

go.eval(`
package main
 
import 'aardio'   

func TestCallBack(fnCallback float64) int{
    
    var s = '字符串'
     
    var r,_ = aardio.CallJson( fnCallback ,s,123,map[string]int{'id': 1, 'id2': 2} )
     
    return r
}

`) 

import raw.jsonCall
  
//創(chuàng)建回調(diào)函數(shù)指針, 在 Go 中必須用 aardio.CallJson 調(diào)用。
var callback = raw.jsonCall(
    function(a,b,c){ 
        console.log('回調(diào)參數(shù):',a,b) 
        console.dumpJson(c);
        return 123;
    } );

import console.int 

var ret  = go.TestCallBack( callback )

console.log(ret);

回調(diào)可以支持任意個(gè)數(shù) JSON 兼容的參數(shù),傳參與返回值會(huì)自動(dòng)通過(guò) JSON 轉(zhuǎn)換。

要注意在 aardio 中調(diào)用 Yaegi 函數(shù)時(shí),數(shù)值默認(rèn)是 float64 類型( JSON 只能描述一種數(shù)值類型 ),可以在 Go 函數(shù)?里強(qiáng)制轉(zhuǎn)換一下就可以了。

五、Yaegi(Go 腳本)調(diào)用 aardio 窗口函數(shù)

直接看代碼:

import golang.yaegi; var go = golang.yaegi(); go.eval(` package main import 'aardio' func TestCallBack(hwnd float64){ aardio.Call(hwnd,'onCallback','參數(shù)1','參數(shù)2'); } `) import win.ui; var winform = win.form(text='Yaegi') winform.add( edit={cls='edit';left=43;top=27;right=717;bottom=400;multiline=1;z=1} ) winform.onCallback = function(param1,param2){ winform.edit.print('Go 調(diào)用了 aardio 函數(shù),參數(shù):',param1,param2) } go.TestCallBack( winform.hwnd ); winform.show(); win.loopMessage();?

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    欧美美女视频在线免费看| 国产欧美高清精品一区| 偷自拍亚洲欧美一区二页| 在线播放欧美精品一区| 久久精品国产亚洲av久按摩| 欧美成人国产精品高清| 亚洲精品国产第一区二区多人| 91老熟妇嗷嗷叫太91| 国产视频一区二区三区四区| 不卡一区二区在线视频| 丰满人妻熟妇乱又乱精品古代| 在线免费国产一区二区三区| 麻豆视传媒短视频在线看| 日本午夜乱色视频在线观看| 国产成人精品99在线观看| 亚洲精品成人综合色在线| 国产一区麻豆水好多高潮| 国产又黄又猛又粗又爽的片| 国产精品免费视频视频| 少妇视频一区二区三区| 欧美一区二区不卡专区| 日韩欧美中文字幕av| 久热在线视频这里只有精品| 激情国产白嫩美女在线观看| 日韩精品成区中文字幕| 亚洲综合一区二区三区在线| 国产精品不卡一区二区三区四区| 尤物天堂av一区二区| 欧美国产在线观看精品| 免费观看潮喷到高潮大叫| 国产精品一区二区视频成人| 欧美国产日本高清在线| 国产成人精品99在线观看| 欧美人妻少妇精品久久性色| 欧洲自拍偷拍一区二区| 韩日黄片在线免费观看| 日韩精品一区二区三区含羞含羞草| 亚洲欧洲精品一区二区三区| 九九热这里只有免费精品| 91欧美日韩一区人妻少妇| 成年人视频日本大香蕉久久|