问题
最近用 go
编写一个 CLI
工具,用到了 tablewriter 库在终端做最基本的表格化输出,使用官方提供的标准代码如下:
package main
import (
"github.com/olekukonko/tablewriter"
"os"
)
func main() {
var data [][]string
data = append(data, []string{"IP地址", "状态", "延迟", "地理位置"})
data = append(data, []string{"115.222.333.44", "✅ 有效", "210ms", "美国,加利福尼亚州,洛杉矶"})
data = append(data, []string{"133.444.555.66", "❌ 无效", "0ms", ""})
data = append(data, []string{"55.666.777.88", "✅ 有效", "352ms", "新加坡,新加坡,新加坡"})
table := tablewriter.NewWriter(os.Stdout)
table.Header(data[0])
table.Bulk(data[1:])
table.Render()
}
结果输出的表格,表头边框与底部边框栏位宽度均无法正常对齐,如下截图:
原因
原本以为是我引用的 tablewriter
库的版本问题,反复切换尝试了最新稳定版 v1.0.8
和旧版 v0.0.5
还是一样!
当我正准备去 tablewriter
的 github
仓库提 issue
时,刚好看到有人在上个月就已经提交了类似的问题,并且已经被处理掉了;
The borders of the table are misaligned #275
其根本原因如下:
翻译如下:
你好@xuthus5,
感谢分享日志!
从您提供的信息来看,这本身似乎不是一个 bug tablewriter。问题在于您的终端环境如何计算字符宽度,尤其是 Unicode 符号的宽度。实际上,tablewriter我们使用github.com/mattn/go-runewidth来确定字符宽度,而这在不同 Windows 终端上的行为可能有所不同。
例如,框绘制字符的宽度"─"预计为1。但是,在您的情况下(特别是在 GoLand 的终端中),runewidth.StringWidth("─")错误地返回了2,这会导致布局问题。
很遗憾,我无法访问 Windows 环境来直接复现此问题。不过,我们仍然可以尝试诊断并解决此问题。请在您的机器上运行以下 Go 程序,并将调试输出分享给我:
所以这是一个与运行程序的终端环境有关的问题,不过作者效率也是杠杠滴,在确定问题原因的第二天就提交了代码变更,增强了这个功能
Improve EastAsianWidth Handling with Custom Condition #276
解决方法
tablewriter
作者在 276
的提交中引入了一种可以灵活自定义控制表格宽度计算方法的参数,使我们能够动态地影响系统计算字符串宽度的方式,在渲染包含混合宽度字符(东亚全角字符)的表格时也能正确计算表格的宽度。
只需要在代码中,初始化 Table 时加上如下这个参数,即可修复边框无法对齐的问题,代码如下:
table := tablewriter.NewTable(os.Stdout, tablewriter.WithEastAsian(false))
目前针对该增强功能的说明,暂时还没有被被添加到项目的说明文档中,我也是自己翻看 issues 才知道具体原因及对应的解决办法!