0

0

Go语言集成Google Sheets:数据读写实战

聖光之護

聖光之護

发布时间:2025-09-13 13:03:07

|

1052人浏览过

|

来源于php中文网

原创

Go语言集成Google Sheets:数据读写实战

本文详细介绍了如何在Go语言环境中高效地集成并使用Google Sheets API,实现对电子表格数据的读写操作。重点阐述了通过Google Apps Script Execution API进行交互的现代方法,涵盖了API配置、认证流程以及核心数据操作的实现细节,旨在为Go开发者提供一套完整的实践指南。

Go语言与Google Sheets交互的现代方案:Google Apps Script Execution API

随着时间的推移,go语言与google sheets的交互方式得到了显著优化。目前,google apps script execution api被认为是实现go语言与google sheets数据读写最灵活和功能最全面的方法。它允许go应用程序远程执行google apps script项目中的函数,从而间接且强大地控制google workspace服务,包括google sheets。这种方法不仅能够实现基本的读写操作,还能利用apps script的强大功能进行更复杂的业务逻辑处理,例如格式化、触发器管理或与其他google服务的集成。

您可以通过官方快速入门指南了解更多详细信息和最新进展:https://www.php.cn/link/8194758636bb0e5bab1a445835138b98

环境配置与认证流程

要开始使用Go语言通过Apps Script Execution API操作Google Sheets,需要完成以下准备工作:

1. Google Cloud Console设置

  • 创建或选择项目:在Google Cloud Console中创建一个新项目或选择一个现有项目。
  • 启用API:搜索并启用“Google Apps Script API”。
  • 配置OAuth同意屏幕:如果您的应用需要代表用户访问数据,请配置OAuth同意屏幕。
  • 创建凭据
    • OAuth 2.0客户端ID:适用于需要用户授权的应用(如桌面应用、Web应用),用户会通过浏览器授权您的应用访问其Google Sheets数据。下载生成的credentials.json文件。
    • 服务账号:适用于服务器到服务器的通信,您的应用将以服务账号的身份访问Sheets。下载服务账号的JSON密钥文件。

2. Go项目准备

在您的Go项目中,需要安装Google API Go客户端库,特别是用于Apps Script的包:

go get google.golang.org/api/script/v1
go get google.golang.org/api/option

3. 认证实现

认证是访问Google API的关键步骤。以下是基于OAuth 2.0的认证流程概述(服务账号认证类似,但更直接):

立即学习go语言免费学习笔记(深入)”;

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "os"

    "golang.org/x/oauth2"
    "golang.org/x/oauth2/google"
    "google.golang.org/api/option"
    "google.golang.org/api/script/v1"
)

// 获取OAuth2配置
func getConfig() (*oauth2.Config, error) {
    b, err := ioutil.ReadFile("credentials.json") // 您的credentials.json文件
    if err != nil {
        return nil, fmt.Errorf("无法读取credentials.json文件: %v", err)
    }

    // 如果是Web应用,这里需要设置RedirectURL
    // config, err := google.ConfigFromJSON(b, script.ScriptExternalExecuteScope)
    // config.RedirectURL = "http://localhost:8080/callback"

    // 桌面应用或CLI应用
    config, err := google.ConfigFromJSON(b, script.ScriptExternalExecuteScope)
    if err != nil {
        return nil, fmt.Errorf("无法解析客户端凭据文件: %v", err)
    }
    return config, nil
}

// 获取或刷新令牌
func getClient(config *oauth2.Config) *http.Client {
    tokFile := "token.json" // 存储用户令牌的文件
    tok, err := tokenFromFile(tokFile)
    if err != nil {
        tok = getTokenFromWeb(config)
        saveToken(tokFile, tok)
    }
    return config.Client(context.Background(), tok)
}

// 从Web获取令牌(首次授权)
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
    authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
    fmt.Printf("请在浏览器中访问此URL进行授权: \n%v\n", authURL)

    var authCode string
    fmt.Print("输入授权码: ")
    if _, err := fmt.Scan(&authCode); err != nil {
        log.Fatalf("无法读取授权码: %v", err)
    }

    tok, err := config.Exchange(context.TODO(), authCode)
    if err != nil {
        log.Fatalf("无法通过授权码获取令牌: %v", err)
    }
    return tok
}

// 从文件加载令牌
func tokenFromFile(file string) (*oauth2.Token, error) {
    f, err := os.Open(file)
    if err != nil {
        return nil, err
    }
    defer f.Close()
    tok := &oauth2.Token{}
    err = json.NewDecoder(f).Decode(tok)
    return tok, err
}

// 将令牌保存到文件
func saveToken(path string, token *oauth2.Token) {
    fmt.Printf("将授权令牌保存到文件: %s\n", path)
    f, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
    if err != nil {
        log.Fatalf("无法保存授权令牌到文件: %v", err)
    }
    defer f.Close()
    json.NewEncoder(f).Encode(token)
}

核心操作:通过Apps Script执行读写Google Sheets数据

由于Apps Script Execution API是用于执行Apps Script脚本的,因此实际的Sheets读写逻辑将编写在Google Apps Script中,Go程序负责调用这些脚本。

1. 编写Apps Script脚本

在Google Apps Script(通常通过访问script.google.com或从Google Sheets中“扩展”->“Apps Script”)中创建一个新项目,并编写用于读写Sheets的函数。

示例:读取数据函数 (readSheetData.gs)

function readSheetData(spreadsheetId, sheetName, range) {
  try {
    var ss = SpreadsheetApp.openById(spreadsheetId);
    var sheet = ss.getSheetByName(sheetName);
    if (!sheet) {
      return { error: "Sheet not found: " + sheetName };
    }
    var values = sheet.getRange(range).getValues();
    return { success: true, data: values };
  } catch (e) {
    return { error: e.message };
  }
}

示例:写入数据函数 (writeSheetData.gs)

function writeSheetData(spreadsheetId, sheetName, range, values) {
  try {
    var ss = SpreadsheetApp.openById(spreadsheetId);
    var sheet = ss.getSheetByName(sheetName);
    if (!sheet) {
      return { error: "Sheet not found: " + sheetName };
    }
    // 确保values是二维数组
    var dataToWrite = Array.isArray(values[0]) ? values : [values];

    var targetRange = sheet.getRange(range);
    if (targetRange.getNumRows() !== dataToWrite.length || targetRange.getNumColumns() !== dataToWrite[0].length) {
        // 如果写入范围与数据维度不匹配,可能需要调整或报错
        // 这里简化处理,直接设置值,如果范围过大/小,Apps Script会自动处理
        // 更严谨的做法是先获取目标范围的行/列数,再判断
        // 或者使用 appendRow/appendRows
    }
    targetRange.setValues(dataToWrite);
    return { success: true, message: "Data written successfully." };
  } catch (e) {
    return { error: e.message };
  }
}

部署Apps Script项目

  1. 在Apps Script编辑器中,点击“部署” -> “新建部署”。
  2. 选择部署类型为“API可执行文件”。
  3. 复制生成的脚本ID,这在Go程序中会用到。

2. Go语言调用Apps Script函数

在Go应用程序中,我们将使用script.Service来调用Apps Script中定义的函数。

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"

    "google.golang.org/api/option"
    "google.golang.org/api/script/v1"
)

// ... (getClient, getConfig等认证函数,如上所示)

func main() {
    ctx := context.Background()

    config, err := getConfig()
    if err != nil {
        log.Fatalf("无法获取OAuth配置: %v", err)
    }
    client := getClient(config)

    srv, err := script.NewService(ctx, option.WithHTTPClient(client))
    if err != nil {
        log.Fatalf("无法初始化Apps Script服务: %v", err)
    }

    // 替换为您的Apps Script项目的部署ID
    scriptID := "YOUR_APPS_SCRIPT_DEPLOYMENT_ID" // 例如:AKfycbyf...

    // --- 示例:调用Apps Script函数读取数据 ---
    spreadsheetID := "YOUR_SPREADSHEET_ID" // 您的Google Sheets文档ID
    sheetName := "Sheet1"
    readRange := "A1:C5"

    readRequest := &script.RunRequest{
        Function: "readSheetData", // Apps Script中定义的函数名
        Parameters: []interface{}{
            spreadsheetID,
            sheetName,
            readRange,
        },
    }

    readResponse, err := srv.Scripts.Run(scriptID, readRequest).Do()
    if err != nil {
        log.Fatalf("执行Apps Script读取函数失败: %v", err)
    }

    if readResponse.Error != nil {
        log.Fatalf("Apps Script执行返回错误: %v", readResponse.Error.Details)
    }
    if readResponse.Response != nil && readResponse.Response.Result != nil {
        // 结果通常是map[string]interface{}类型,需要根据Apps Script返回的结构进行断言
        resultMap, ok := readResponse.Response.Result.(map[string]interface{})
        if !ok {
            log.Printf("Apps Script返回结果非预期类型: %T", readResponse.Response.Result)
        } else {
            if success, found := resultMap["success"].(bool); found && success {
                if data, dataFound := resultMap["data"].([]interface{}); dataFound {
                    fmt.Println("读取到的数据:")
                    for _, row := range data {
                        fmt.Println(row)
                    }
                }
            } else if errMsg, errFound := resultMap["error"].(string); errFound {
                fmt.Printf("Apps Script执行失败: %s\n", errMsg)
            }
        }
    }

    // --- 示例:调用Apps Script函数写入数据 ---
    writeRange := "A6"
    valuesToWrite := [][]interface{}{
        {"New Data 1", "New Data 2", "New Data 3"},
        {"Row 2 Col 1", "Row 2 Col 2", "Row 2 Col 3"},
    }

    writeRequest := &script.RunRequest{
        Function: "writeSheetData", // Apps Script中定义的函数名
        Parameters: []interface{}{
            spreadsheetID,
            sheetName,
            writeRange,
            valuesToWrite,
        },
    }

    writeResponse, err := srv.Scripts.Run(scriptID, writeRequest).Do()
    if err != nil {
        log.Fatalf("执行Apps Script写入函数失败: %v", err)
    }

    if writeResponse.Error != nil {
        log.Fatalf("Apps Script执行返回错误: %v", writeResponse.Error.Details)
    }
    if writeResponse.Response != nil && writeResponse.Response.Result != nil {
        resultMap, ok := writeResponse.Response.Result.(map[string]interface{})
        if !ok {
            log.Printf("Apps Script返回结果非预期类型: %T", writeResponse.Response.Result)
        } else {
            if success, found := resultMap["success"].(bool); found && success {
                fmt.Printf("写入操作成功: %s\n", resultMap["message"])
            } else if errMsg, errFound := resultMap["error"].(string); errFound {
                fmt.Printf("Apps Script写入失败: %s\n", errMsg)
            }
        }
    }
}

注意事项与最佳实践

  • 权限管理:确保您的Apps Script项目拥有访问Google Sheets的必要权限。在Apps Script编辑器中,查看“项目设置”->“Cloud Platform项目”和“概览”->“项目属性”来管理权限。当您首次运行包含Sheets操作的Apps Script时,系统会提示您授权。
  • 错误处理:Go应用程序和Apps Script脚本都应包含健壮的错误处理机制。在Go端,检查script.RunResponse中的Error字段;在Apps Script端,使用try-catch块捕获异常并返回有意义的错误信息。
  • 脚本ID管理:将Apps Script的部署ID作为配置项,而不是硬编码在Go代码中,以便于管理和更新。
  • 性能考量:频繁地调用Apps Script可能会导致性能开销。如果需要进行大量的小型操作,考虑在Apps Script中编写一个函数来批量处理数据,然后Go程序一次性调用该批量处理函数。
  • 安全性:妥善保管您的credentials.json和token.json文件,不要将其提交到版本控制系统。在生产环境中,应使用更安全的凭据管理方式,例如环境变量或Google Secret Manager。
  • Apps Script版本控制:Apps Script项目可以有多个部署版本。在Go代码中,您通常会指定一个特定的部署ID来确保调用的是稳定版本。

总结

通过Google Apps Script Execution API,Go语言开发者可以获得与Google Sheets进行深度交互的能力。这种方法结合了Go语言的强大并发处理能力和Google Apps Script对Google Workspace服务的原生支持,提供了一个灵活、可扩展且功能丰富的解决方案。掌握这种集成方式,将使您能够构建出更加智能和自动化的Go语言应用程序,有效管理和利用Google Sheets中的数据。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

412

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

533

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

309

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

74

2025.09.10

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

187

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

280

2023.10.25

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6095

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

806

2023.09.14

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

68

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 8.3万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号