golang – how to list excel spreadsheet column names?

huangapple go评论87阅读模式
英文:

golang - how to list excel spreadsheet column names?

问题

golang - 如何列出 Excel 的列名?

如图所示,Excel 的列名是按照 A、B、C...AA、AB、AC... 的顺序列出的。目前还没有关于如何在 Go 语言中列出这些列名的示例。在解析 Excel 电子表格并获取电子表格标签的范围以获取单元格值时,这是必需的。

英文:

golang - how to list excel column names ??
golang – how to list excel spreadsheet column names?

As shown in image , the exel columns are listed as A B C ... AA AB AC .... There is no sample available on how to list this in go lang. This is needed when parsing excel spreadsheet to get range of spreadsheet tabs to get cells values

答案1

得分: 3

这是一个高效的解决方案。

func getColumnName(col int) string {
    name := make([]byte, 0, 3) // 最多 16,384 列(2022 年)
    const aLen = 'Z' - 'A' + 1 // 字母表长度
    for ; col > 0; col /= aLen + 1 {
        name = append(name, byte('A'+(col-1)%aLen))
    }
    for i, j := 0, len(name)-1; i < j; i, j = i+1, j-1 {
        name[i], name[j] = name[j], name[i]
    }
    return string(name)
}

https://go.dev/play/p/upjBQeE1x8I


OP(@mahbh2001)在他自己的问题中发布了一个答案:https://stackoverflow.com/a/71350368

以下是对列从 1 到 99 进行 getColumnName 基准测试的结果:

rocka2q:
BenchmarkA2Q-4 758865 1498 ns/op 146 B/op 73 allocs/op

OP(mahbh2001):
BenchmarkOP-4 122714 9515 ns/op 1376 B/op 341 allocs/op

OP 的代码明显较慢。

英文:

Here is an efficient solution.

func getColumnName(col int) string {
    name := make([]byte, 0, 3) // max 16,384 columns (2022)
    const aLen = &#39;Z&#39; - &#39;A&#39; + 1 // alphabet length
    for ; col &gt; 0; col /= aLen + 1 {
	    name = append(name, byte(&#39;A&#39;+(col-1)%aLen))
    }
    for i, j := 0, len(name)-1; i &lt; j; i, j = i+1, j-1 {
	    name[i], name[j] = name[j], name[i]
    }
    return string(name)
}

https://go.dev/play/p/upjBQeE1x8I


The OP (@mahbh2001) posted an answer to his own question: https://stackoverflow.com/a/71350368

Here are the results of getColumnName benchmarks for columns 1 through 99:

rocka2q:
BenchmarkA2Q-4  758865  1498 ns/op   146 B/op   73 allocs/op

OP (mahbh2001):
BenchmarkOP-4   122714  9515 ns/op  1376 B/op  341 allocs/op

The OP's code is significantly slower.

答案2

得分: 2

我尝试搜索一个方便的函数来获取Excel列名,但在Golang中没有找到,所以我自己创建了一个。希望这对其他人节省时间有所帮助。

package main

import "fmt"

func reverse(s string) string {
    runes := []rune(s)
    for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
        runes[i], runes[j] = runes[j], runes[i]
    }
    return string(runes)
}

// 根据给定的列号打印Excel列名的函数
func getColumnName(columnNumber int) string {

    // 存储结果(Excel列名)
    var columnName = ""
    for ok := true; ok; ok = columnNumber > 0 {

        // 求余数
        rem := columnNumber % 26

        // 如果余数为0,则输出中必须有一个'Z'
        if rem == 0 {
            columnName += "Z"
            columnNumber = (columnNumber / 26) - 1
        } else // 如果余数非零
        {
            columnName += string((rem - 1) + int('A'))
            columnNumber = columnNumber / 26
        }
    }

    // 反转字符串
    columnName = reverse(columnName)
    return columnName

}

func main() {
    for cm := 1; cm < 100; cm++ {
        fmt.Println(getColumnName(cm))
    }
}
英文:

I tried to search for handy function to get excel column names but was not able to get in golang , so created one , hope this helps other to save time

package main

import &quot;fmt&quot;

func reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i &lt; j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

// Function to print Excel column
// name for a given column number
//
func getColumnName(columnNumber int) string {

	// To store result (Excel column name)
	var columnName = &quot;&quot;
	for ok := true; ok; ok = columnNumber &gt; 0 {

		// Find remainder
		rem := columnNumber % 26

		// If remainder is 0, then a
		// &#39;Z&#39; must be there in output
		if rem == 0 {
			columnName += &quot;Z&quot;
			columnNumber = (columnNumber / 26) - 1
		} else // If remainder is non-zero
		{
			columnName += string((rem - 1) + int(&#39;A&#39;))
			columnNumber = columnNumber / 26
		}
	}

	// Reverse the string
	columnName = reverse(columnName)
	return columnName

}

func main() {
	for cm := 1; cm &lt; 100; cm++ {
		fmt.Println(getColumnName(cm))
	}
}

答案3

得分: 1

这是一个带有错误处理程序的示例代码,修改自excelize。请注意,这不像@rocka2q的答案那样快速。

package main

import (
	"errors"
	"fmt"
)

func main() {

	for cm := 1; cm < 100; cm++ {
		cmName, _ := ColumnNumberToName(cm)
		fmt.Println(cmName)
	}

}

func ColumnNumberToName(num int) (string, error) {
	if num < 1 {
		return "", fmt.Errorf("不正确的列号 %d", num)
	}
	if num > 16384 {
		return "", errors.New("列号超过最大限制")
	}
	var col string
	for num > 0 {
		col = string(rune((num-1)%26+65)) + col
		num = (num - 1) / 26
	}
	return col, nil
}

或者你可以直接使用excelize函数:

package main

import (
	"fmt"
	"github.com/xuri/excelize/v2"
)

func main() {

	for cm := 1; cm < 100; cm++ {
		cmName, _ := excelize.ColumnNumberToName(cm)
		fmt.Println(cmName)
	}

}
英文:

Here is one with an error handler.
this is modified from excelize
note that this is not as fast as @rocka2q answer.

package main

import (
	&quot;errors&quot;
	&quot;fmt&quot;
)

func main() {

	for cm := 1; cm &lt; 100; cm++ {
		cmName, _ := ColumnNumberToName(cm)
		fmt.Println(cmName)
	}

}

func ColumnNumberToName(num int) (string, error) {
	if num &lt; 1 {
		return &quot;&quot;, fmt.Errorf(&quot;incorrect column number %d&quot;, num)
	}
	if num &gt; 16384 {
		return &quot;&quot;, errors.New(&quot;column number exceeds maximum limit&quot;)
	}
	var col string
	for num &gt; 0 {
		col = string(rune((num-1)%26+65)) + col
		num = (num - 1) / 26
	}
	return col, nil
}

or you can directly use the excelize function:


package main

import (
	&quot;fmt&quot;
	&quot;github.com/xuri/excelize/v2&quot;
)

func main() {

	for cm := 1; cm &lt; 100; cm++ {
		cmName, _ := excelize.ColumnNumberToName(cm)
		fmt.Println(cmName)
	}

}

huangapple
  • 本文由 发表于 2022年3月4日 18:55:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/71350367.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定