You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# 动态设置string.Format格式化长度实现DataGrid通用ASCII导出

问题描述

现有一段从DataGrid读取数据并导出为ASCII文件的代码,运行正常,代码如下:

FileInfo info = new FileInfo(@"C:\SqlExports\");
info.Directory.Create();

string fileName = condition + " " + date + ".txt";

FileStream stream = new FileStream(@"C:\SqlExports\" + fileName, FileMode.OpenOrCreate);
StreamWriter sw = new StreamWriter(stream, Encoding.Default);

for (int i = 0; i < Grid.Rows.Count; i++)
{
    List<string> rowprint = new List<string>();
    for (int f = 0; f < Grid.Columns.Count; f++)
    {
        if (Grid.Rows[i].Cells[f].Value != DBNull.Value)
        { rowprint.Add(Grid.Rows[i].Cells[f].Value.ToString()); }
        else
        {
            rowprint.Add(" ");
        }
    }
    sw.Write(string.Format("{0,-19}", rowprint[0]) + String.Format("{0,10}", rowprint[1]) + sw.NewLine, Encoding.Default);

}
sw.Close();

需要将该代码改造为可复用逻辑,适配DataGrid绑定不同数据源的导出需求,支持2列、3列及更多列的动态列数场景。
曾尝试如下写法实现字段长度加2个空格的格式化效果,但无法正常运行:

sw.Write(string.Format("0, -(rowprint[0].length + 2)", rowprint[0]) + string.Format("{"0,rowprint[1].Length + 2"} + sw.Newlinn, Encoding.Default);

需要找到正确的实现方式,在格式化时基于字段值对应长度增加2个空格完成对齐输出,适配动态列数场景。

错误原因

之前的写法无法运行有三个核心问题:

  • 把变量计算逻辑直接写在字符串字面量内部,C#不会解析引号包裹的普通字符串中的变量取值,"0, -(rowprint[0].length + 2)" 是非法的string.Format格式串
  • 格式串的大括号没有正确拼接,存在语法错误
  • 逐单元格用当前内容长度+2作为占位宽度,会因为同一列不同行内容长度不一致,导致最终输出列错位
可复用实现方案

实现逻辑分三步:

  • 预计算每一列的最大显示宽度:遍历所有行的单元格内容,取每列最长内容的长度加2个空格作为该列统一的对齐宽度,同时兼容列头长度,避免列头长于内容时错位
  • 动态生成格式化模板:根据实际列数拼接占位符,不需要硬编码列索引和固定宽度,可适配任意列数
  • 统一写入文件:用using语句自动释放文件资源,自动跳过DataGrid自带的新增空行,支持自定义导出路径、文件名、编码

完整可复用代码如下:

/// <summary>
/// 将DataGrid内容导出为对齐的ASCII文本文件
/// </summary>
/// <param name="grid">要导出的DataGrid控件</param>
/// <param name="saveDir">导出文件保存目录</param>
/// <param name="fileName">导出文件名</param>
/// <param name="encoding">文件编码,默认使用系统默认编码</param>
public void ExportDataGridToAscii(DataGridView grid, string saveDir, string fileName, Encoding encoding = null)
{
    encoding ??= Encoding.Default;
    // 自动创建不存在的目录
    Directory.CreateDirectory(saveDir);
    string fullSavePath = Path.Combine(saveDir, fileName);

    int colCount = grid.Columns.Count;
    int[] colWidths = new int[colCount];

    // 初始化列宽为列头长度+2个空格
    for (int i = 0; i < colCount; i++)
    {
        colWidths[i] = (grid.Columns[i].HeaderText?.Length ?? 0) + 2;
    }

    // 遍历所有行,计算每列的最大内容宽度+2个空格
    foreach (DataGridViewRow row in grid.Rows)
    {
        // 跳过DataGrid的新增占位空行
        if (row.IsNewRow) continue;
        for (int i = 0; i < colCount; i++)
        {
            string cellVal = row.Cells[i].Value == DBNull.Value ? " " : row.Cells[i].Value.ToString();
            int currentWidth = cellVal.Length + 2;
            if (currentWidth > colWidths[i])
            {
                colWidths[i] = currentWidth;
            }
        }
    }

    // 动态拼接行格式化模板:保持原逻辑第一列左对齐,其余列右对齐
    List<string> formatSegments = new List<string>();
    for (int i = 0; i < colCount; i++)
    {
        // 负宽度代表左对齐,正宽度代表右对齐,需要全列左对齐就统一加负号
        string alignFlag = i == 0 ? "-" : "";
        formatSegments.Add($"{{{i},{alignFlag}{colWidths[i]}}}");
    }
    string lineFormat = string.Concat(formatSegments) + Environment.NewLine;

    // 写入文件
    using (FileStream fs = new FileStream(fullSavePath, FileMode.OpenOrCreate, FileAccess.Write))
    using (StreamWriter sw = new StreamWriter(fs, encoding))
    {
        // 写入列头(不需要可以注释掉这部分)
        List<string> headerVals = new List<string>();
        for (int i = 0; i < colCount; i++)
        {
            headerVals.Add(grid.Columns[i].HeaderText ?? string.Empty);
        }
        sw.Write(lineFormat, headerVals.ToArray());

        // 逐行写入数据
        foreach (DataGridViewRow row in grid.Rows)
        {
            if (row.IsNewRow) continue;
            List<string> rowVals = new List<string>();
            for (int i = 0; i < colCount; i++)
            {
                string val = row.Cells[i].Value == DBNull.Value ? " " : row.Cells[i].Value.ToString();
                rowVals.Add(val);
            }
            sw.Write(lineFormat, rowVals.ToArray());
        }
    }
}

调用示例:

// 调用时只需要传入对应参数即可,不管DataGrid绑定的数据源是2列还是更多列都能自动适配
ExportDataGridToAscii(Grid, @"C:\SqlExports\", $"{condition} {date}.txt");

如果需要所有列都左对齐,只需要把生成alignFlag的判断去掉,统一赋值为"-"即可。


内容的提问来源于stack exchange,提问作者John Karagiannis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 02:57:32