EPPlus中合并单元格的自适应行高

13

我正在使用EPPlus和C#,尝试自动调整行的高度以容纳合并单元格中所有内容的文本换行所需的高度。但是无论我尝试什么都会出现文本截断。因为我需要在不同工作表上重复此过程,使用各种文本大小,所以我不想硬编码行高(除了强制对行施加最小高度)。如果可能的话,我想在EPPlus/C#内部完成。

将单元格A2:E2合并,并设置WrapText = true:

文本被截断的单元格

enter image description here

应该如下图所示,具有所需的单元格高度

enter image description here

这是我相关且简短的C#代码:

Int32 intToCol;
intToCol = 5;
eppWorksheet.Cells[2, 1, 2, intToCol].Merge = true;
eppWorksheet.Cells[2, 1].Style.WrapText = true; 
//Check if at the minimum height. If not, resize the row
if (eppWorksheet.Row(2).Height < 35.25)
{
    eppWorksheet.Row(2).Height = 35.25;
}

我看过EPPlus中的自动调整行高,但似乎没有直接回答我的问题,除非我理解有误。


1
这是Excel的一个已记录的限制:https://support.microsoft.com/en-us/kb/212010。恐怕没有简单的解决方案,除了估算高度,这里有一篇关于自动调整宽度的文章,但原理相同:https://dev59.com/9mMk5IYBdhLWcg3w3xnq#23528323 - Ernie S
我意识到了 Excel 的限制,但在网上没有找到合适的解决方案,想知道其他人是否有解决方案。 - cmbarnett87
3个回答

30

以下是可重复使用的解决方案。传入文本值、单元格使用的字体、合并列的总宽度,获得行高度并将其设置为结果。

方法的使用

eppWorksheet.Row(2).Height = MeasureTextHeight(cell.Value, cell.Style.Font, [enter the SUM of column widths A-E]);

可重复使用的方法

    public double MeasureTextHeight(string text, ExcelFont font, double width)
    {
        if (text.IsNullOrEmpty()) return 0.0;
        var bitmap = _bitmap ?? (_bitmap = new Bitmap(1, 1));
        var graphics = _graphics ?? (_graphics = Graphics.FromImage(bitmap));

        var pixelWidth = Convert.ToInt32(width * 7);  //7 pixels per excel column width
        var fontSize = font.Size * 1.01f;
        var drawingFont = new Font(font.Name, fontSize);
        var size = graphics.MeasureString(text, drawingFont, pixelWidth, new StringFormat { FormatFlags = StringFormatFlags.MeasureTrailingSpaces });

        //72 DPI and 96 points per inch.  Excel height in points with max of 409 per Excel requirements.
        return Math.Min(Convert.ToDouble(size.Height) * 72 / 96, 409);
    }

4
非常好的解决方案。只需注意您需要处理BitmapGraphics对象。 - Dylan
1
伟大的解决方案。做到了它所说的一切。谢谢,伙计。 - Ocean Airdrop
1
将点转换为像素时,应使用“/ 0.75”而不是“*”。变量pixelWidth = Convert.ToInt32(width / 7.5)。 - Kalpesh Popat
2
很好的一般想法。以下是一些可能有助于他人的评论:
  • 每个Excel列宽度有7.0017094(7)个像素。我认为您可能一直在考虑行间距和格式。
  • 切换到每列7像素/列宽后,我通过: a)将font.Size * 1.01乘以, b)传递一个StringFormat参数给MeasureString,其中FormatFlags = StringFormatFlags.MeasureTrailingSpaces, 找到了不错的结果。
- Jedidja
2
@Jedidja 感谢您发布建议。我已经编辑了我的帖子以反映它们。这些编辑已在我们的应用程序中进行了测试,并解决了我们遇到的问题! - Ben Gripka
非常奇怪的是,Excel 默认不支持此行为。您必须下载额外的帮助库才能自动调整合并单元格的行高...太蠢了。感谢 @BenGripka 提供的解决方案 <3 - Dorin Baba

2
我已经采用了一种解决方法,并且我有一个打印区域A:Q。
  1. 我将合并单元格的值复制到列z中。
  2. 将列z的宽度设置为合并单元格的宽度。
  3. 然后在格式中将自动行高设置为true。
  4. 隐藏z列。
  5. 设置打印区域为A:Q。

缺点: 有重复数据。但是我们可以接受,因为报告正在打印,而不是打印z列。

优点: 行高像计算方法一样正确。


"Original Answer"翻译成"最初的回答"

0

不得不稍微调整一下代码,删除返回行的乘法因子。可能是因为我正在使用这段代码来获取列的宽度。

ws1.Column(colIndx).Width * 7

乘数因子是合并的列数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接