使用中日泰等非字母数字字符时的C#文本对齐问题求助
解决C#文本报表中全角/半角字符对齐问题
这个问题我之前帮不少开发者排查过,核心原因很明确:全角字符(比如中文)和半角字符(英文、数字)的显示宽度不一致。在常规的文本显示环境里,一个全角字符会占用2个半角字符的宽度,但C#默认的PadRight/PadLeft或字符串格式化是按字符数量计算长度的,不是实际显示宽度,这就导致了中文和英文内容的对齐错位。
下面给你几个可行的解决办法,按可控性排序:
1. 自定义按显示宽度对齐的方法(最推荐)
写一个工具方法,先计算字符串的实际显示宽度(全角字符算2,半角算1),再根据目标宽度补充空格。这样不管用什么字体打开文本文件,对齐效果都能保证。
示例代码:
using System.Globalization; public static class StringExtensions { // 计算字符串的实际显示宽度 public static int GetDisplayWidth(this string input) { return input.Sum(c => char.GetUnicodeCategory(c) switch { UnicodeCategory.OtherLetter => 2, // 全角中文字符等 _ => 1 // 半角字符(英文、数字、符号等) }); } // 按显示宽度向右补空格 public static string PadRightByDisplayWidth(this string input, int targetWidth) { int currentWidth = input.GetDisplayWidth(); int spacesToAdd = Math.Max(0, targetWidth - currentWidth); return input + new string(' ', spacesToAdd); } }
使用方式:
// 目标显示宽度设为10 Console.WriteLine($"{ "Johnny".PadRightByDisplayWidth(10) } $1000"); Console.WriteLine($"{ "Adam".PadRightByDisplayWidth(10) } $1000"); Console.WriteLine($"{ "测测".PadRightByDisplayWidth(10) } $1000");
这样输出后,三行的名称部分实际显示宽度都是10,金额就能完美对齐了。
2. 使用支持中文等宽的字体(适合本地查看)
如果只是自己查看生成的文本文件,可以换用支持中文等宽的字体,比如思源黑体等宽、JetBrains Mono(新版支持中文等宽)、Consolas配合中文等宽补丁。这类字体中,全角和半角字符的显示宽度一致,用普通的PadRight就能实现对齐。
不过这个方法依赖查看环境,如果你需要把文件发给其他人,对方可能没有同款字体,所以不如第一种方法可靠。
3. 转成全角字符(不推荐,仅特殊场景)
把所有半角字符(英文、数字、符号)转成全角格式,这样所有字符都是全角,按字符数量对齐就没问题。但这种方式会改变文本的原始格式(比如$变成$,1变成1),通常只适合特定的展示场景。
示例转换代码:
public static string ToFullWidth(string input) { char[] chars = input.ToCharArray(); for (int i = 0; i < chars.Length; i++) { if (chars[i] >= 0x20 && chars[i] <= 0x7E) { chars[i] = (char)(chars[i] + 0xFEE0); } } return new string(chars); }
内容的提问来源于stack exchange,提问作者tickwave




