目录
  • 问题现象
  • 原因分析
  • 范例运行环境
  • 解决问题
    • 生成测试文本
    • 实现自适应
  • 小结

    问题现象

    通过 COM 操作 Excel 自动适应列宽的方法是 AutoFit 方法,该方法适于自动适应列宽或行高。

    最近在我们的一款应用里发现效果并没有符合预期,我们提供了一个可以设置导出Excel花名册的配置功能,如下图:

    使用C#解决Excel自动适应列宽的问题

    通过查询配置表,可以看到当选择需要输出的列的时候,可以设置 excel 列的宽度,以满足输出样式。列宽的值可以设置0到255的数值,在 C# 中列宽(ColumnWidth)是一个 dynamic 类型,如下示例代码:

    Range  _range=excel.Range[excel.Cells[1,1],excel.Cells[65536,1]];
     
    _range.ColumnWidth=255;

    通过获取 Range 对象,将其 ColumnWidth 设置为我们配置的值。在我们的应用里,如果配置为 -1 ,则表示使用自动适应列宽模式,这就用到了如下代码:

    Range  _range=excel.Range[excel.Cells[1,1],excel.Cells[65536,1]];
     
    if(config_width==-1){
        _range.Columns.AutoFit();
    }

    我们在应用里配置了类似“家庭成员情况”、“主要社会关系人” 、“学习经历”、“工作经历” 等履历型的多行文本输出,使用了自动适应列宽模式,输出效果如下:

    使用C#解决Excel自动适应列宽的问题

    实际上是我们想要得到这样的效果:

    使用C#解决Excel自动适应列宽的问题

    原因分析

    根据输出效果,我们在 Excel 里模拟操作一下自适应列宽,将鼠标移动到指定的列的表头的分隔线处,鼠标形状会显示为左右箭头分隔状,然后双击即可实现自动列宽。

    使用C#解决Excel自动适应列宽的问题

    发现有以下几种情况:

    (1)如果单元格未设置为自动换行,我们将列宽手动调小于文字显示的长度,双击后将成功自动适应为最大文字长度的合适列宽。

    (2)如果单元格设置为自动换行,我们将列宽手动调小于文字显示的长度,双击后将没有达成预期的显示列宽。

    (3)如果单元格设置为自动换行,我们将列宽手动调大于多行文字显示的长度,双击后将成功自动适应为最大文字长度的合适列宽。

    因此我们可以使用 C# 模拟情况(3)的操作来解决情况(2)的问题。

    范例运行环境

    操作系统: Windows Server 2019 DataCenter

    .net版本: .netFramework4.0 或以上

    Office Excel 2016

    开发工具:VS2019  C# 

    解决问题

    生成测试文本

    我们假设生成了如下 HtmlTable 表格内容:

    姓名 与本人关系 政治面目 工作单位 职务
    姓名1 父亲  群众 工作单位工作单位 工人
    姓名2 母亲 群众 工作单位2 员工
    姓名3 子女 群众 无工作单位

    我们通过遍历行列的方法,计算每个单元格相对于列的最大字节数 GetByteCount(不是长度Length),示例代码如下:

                for (int i = 0; i < mtable.Rows[0].Cells.Count; i++)
                {
                    int maxlen = 0;
                    for (int j = 0; j < mtable.Rows.Count; j++)
                    {
                        HtmlTableCell curcell=mtable.Rows[j].Cells[i];
                        int curlen=System.Text.Encoding.Default.GetByteCount(curcell.InnerText);
                        if (curlen > maxlen)
                        {
                            maxlen = curlen;
                        }
                    }
                    mtable.Rows[0].Cells[i].Attributes["maxlen"] = maxlen.ToString();
                }
                string excel = "";
                for (int i = 0; i < mtable.Rows.Count; i++)
                {
                    for (int j = 0; j < mtable.Rows[i].Cells.Count; j++)
                    {
                        int maxlen =int.Parse(mtable.Rows[0].Cells[j].Attributes["maxlen"]);
                        HtmlTableCell curcell = mtable.Rows[i].Cells[j];
                        excel += curcell.InnerText + string.Concat(Enumerable.Repeat(" ", maxlen - System.Text.Encoding.Default.GetByteCount(curcell.InnerText)))+"  " ;
    curcell.InnerText);
                    }
                    excel += "\r\n";
                }

    实现自适应

    通过生成测试文本,保存到数据库并输出到 Excel 指定列,实现自适应非常简单,将列值设置为最大值,再使用自适应AutoFit 方法,即可以让 Excel 自动计算并重新调整列宽,代码如下:

    Range  _range=excel.Range[excel.Cells[1,1],excel.Cells[65536,1]];
     
    if(config_width==-1){
       _range.ColumnWidth = 255;
       _range.Columns.AutoFit();
    }

    自此完美解决。

    小结

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。