Golang使用Google Sheets API处理空单元格问题

Golang使用Google Sheets API处理空单元格问题 在使用 Google Sheets API 读取电子表格时,如果遇到空单元格,我会收到“索引超出范围”的恐慌错误。

我使用的是这个包:google.golang.org/api/sheets/v4,它返回一个 Values 接口(resp.Values)。

如果单元格为空,最简单的方法是什么,可以只留空而不引发恐慌?

if len(resp.Values) == 0 {
		fmt.Println("No data found.")
	} else {
		var csvOutput string = "ShipDate, BOL, SCAC, PRO, PO, SO, Dest"
		var shipDate, BOL, SCAC, PRO, PO, SO, dest string
		for _, row := range resp.Values {
			// Read values and comma separate into a string.
			shipDate = fmt.Sprintf("%v", row[0])[0:10]
			SCAC = fmt.Sprintf("%v", row[2])
			BOL = fmt.Sprintf("%v", row[3])
			PRO = fmt.Sprintf("%v", row[4])
			PO = fmt.Sprintf("%v", row[5])
			SO = fmt.Sprintf("%v", row[6])
			dest = fmt.Sprintf("%v", row[7])
    }

更多关于Golang使用Google Sheets API处理空单元格问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

将条件改为“如果索引小于0”并传递空字符串作为回退值效果很好。之后我只需要在存在时提取前10位数字即可。

感谢您的帮助!

更多关于Golang使用Google Sheets API处理空单元格问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


sivan: 改为“if index < 0”效果很好。

我的建议里有一个错误;这才是正确的修复方法!修正了边界条件后,你应该可以继续使用“0000-00-00”(或其他值)作为默认值,并保留 [:10]

func main() {
    fmt.Println("hello world")
}

感谢Sean!这个方法大部分情况下是有效的,但是shipDate字段总是保持为0000-00-00。检查条件 index <= 0 意味着第一个索引 [0] 总是会返回fallback值。

我尝试将其改为 if index <= -1,但随后我遇到了一个panic错误:“slice bounds out of range [:10] with length 0。”

在尝试索引行之前,请先检查其长度。

我建议添加一个小辅助函数:

tryRowSprintf := func(format string, row []interface{}, index int, fallback string) string {
    if index <= 0 || len(row) <= index {
        return fallback
    }
    return fmt.Sprintf(format, row[index])
}

	if len(resp.Values) == 0 {
		fmt.Println("No data found.")
	} else {
		var csvOutput string = "ShipDate, BOL, SCAC, PRO, PO, SO, Dest"
		var shipDate, BOL, SCAC, PRO, PO, SO, dest string
		for _, row := range resp.Values {
			// Read values and comma separate into a string.
			shipDate = tryRowSprintf("%v", row, 0, "0000-00-00")[0:10]
			SCAC = tryRowSprintf("%v", row, 2, "")
			BOL = tryRowSprintf("%v", row, 3, "")
			PRO = tryRowSprintf("%v", row, 4, "")
			PO = tryRowSprintf("%v", row, 5, "")
			SO = tryRowSprintf("%v", row, 6, "")
			dest = tryRowSprintf("%v", row, 7, "")
    }

我认为这是最简单的方法,因为它对你现有代码的格式改动很少:虽然新增了一个函数,但它位于你代码当前“主流程”之外。

根据你已发布代码的上下文,我和/或其他人可能会有其他建议!

处理Google Sheets API返回的空单元格时,确实需要检查索引边界。以下是修改后的代码示例:

if len(resp.Values) == 0 {
    fmt.Println("No data found.")
} else {
    var csvOutput string = "ShipDate, BOL, SCAC, PRO, PO, SO, Dest"
    var shipDate, BOL, SCAC, PRO, PO, SO, dest string
    
    for _, row := range resp.Values {
        // 安全获取单元格值,处理空单元格
        getValue := func(index int) string {
            if index < len(row) && row[index] != nil {
                return fmt.Sprintf("%v", row[index])
            }
            return ""
        }
        
        // 使用安全函数获取值
        shipDate = getValue(0)
        if len(shipDate) >= 10 {
            shipDate = shipDate[0:10]
        }
        
        SCAC = getValue(2)
        BOL = getValue(3)
        PRO = getValue(4)
        PO = getValue(5)
        SO = getValue(6)
        dest = getValue(7)
        
        // 构建CSV行
        csvOutput += fmt.Sprintf("\n%s, %s, %s, %s, %s, %s, %s",
            shipDate, BOL, SCAC, PRO, PO, SO, dest)
    }
}

或者使用更简洁的辅助函数:

func safeCellValue(row []interface{}, index int) string {
    if index >= len(row) || row[index] == nil {
        return ""
    }
    return fmt.Sprintf("%v", row[index])
}

// 在循环中使用
for _, row := range resp.Values {
    shipDate := safeCellValue(row, 0)
    if len(shipDate) >= 10 {
        shipDate = shipDate[0:10]
    }
    
    SCAC := safeCellValue(row, 2)
    BOL := safeCellValue(row, 3)
    PRO := safeCellValue(row, 4)
    PO := safeCellValue(row, 5)
    SO := safeCellValue(row, 6)
    dest := safeCellValue(row, 7)
    
    // 处理逻辑...
}

关键点:

  1. 检查 len(row) 确保索引有效
  2. 检查 row[index] != nil 确保单元格有值
  3. 使用辅助函数简化重复的边界检查
回到顶部