问题

最近用 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()
}

结果输出的表格,表头边框与底部边框栏位宽度均无法正常对齐,如下截图:
go-tablewriter-borders-are-not-misaligned.png

原因

原本以为是我引用的 tablewriter 库的版本问题,反复切换尝试了最新稳定版 v1.0.8 和旧版 v0.0.5 还是一样!

当我正准备去 tablewritergithub 仓库提 issue 时,刚好看到有人在上个月就已经提交了类似的问题,并且已经被处理掉了;

The borders of the table are misaligned #275

其根本原因如下:
go-tablewriter-not-misaligned-plobrom.png
翻译如下:

你好@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 才知道具体原因及对应的解决办法!

Last modification:July 28, 2025
如果觉得我的文章对你有用,请随意赞赏