6

Closed

Adjusting to Content does not work on Windows Azure Websites

description

Adjusting column widths based on content fails on Windows Azure Websites because it seems that the functionality provided by System.Windows.Forms.TextRenderer, which is used for measuring string widths, is missing. TextRenderer returns arbitrary output (width > 1,000,000 for the string "hello") instead of real values.

The issue can be resolved by using GDI+ instead of GDI, hence using System.Drawing.Graphics.MeasureString.

The following code snippet demonstrates a rough idea how text measuring using GDI+ could be implemented. Note however that always bold fonts are assumed and that rich text is not handled appropriately.
public static void AdjustToContentsGDIPlus(this IXLColumn column)
{
    using (var bitmap = new Bitmap(1, 1))
    using (var graphics = Graphics.FromImage(bitmap))
    {
        graphics.TextRenderingHint = TextRenderingHint.AntiAlias;

        var fontCache = new Dictionary<IXLFontBase, Font>();
        var width = column.CellsUsed()
            .Select(c => new {Font = GetFont(c.Style.Font, fontCache), Value = c.GetFormattedString()})
            .Max(c => MeasureText(graphics, c.Value, c.Font));

        column.Width = width;
    }
}

private static Font GetFont(IXLFontBase fontBase, IDictionary<IXLFontBase, Font> fonts)
{
    Font font;

    if (!fonts.TryGetValue(fontBase, out font))
    {
        font = new Font(fontBase.FontName, (float) fontBase.FontSize, FontStyle.Bold);
        fonts.Add(fontBase, font);
    }

    return font;
}

private static double MeasureText(Graphics graphics, string text, Font font)
{
    var size = graphics.MeasureString(text, font, Int32.MaxValue, StringFormat.GenericTypographic);

    // calculation taken from FontBaseExtensions.GetWidth method
    var width = (((size.Width / (double)7) * 256) - (128 / 7)) / 256;
    width = (double) Decimal.Round((decimal)width + 0.2M, 2);

    return width;
}
Closed May 13 at 7:53 PM by MDeLeon
Pick up the latest source code.

comments

mhidinger wrote Aug 13, 2013 at 6:34 PM

I've also noticed issues with my project when deployed to Azure. Will try and to create a simple repro, but for now it's rendered ClosedXml usage completely useless, since the Excel report makes no sense with those arbitrary width.s

MDeLeon wrote Aug 13, 2013 at 7:00 PM

How about using the GDI as fallback? Please see if you can make a repro project...

paaland wrote Mar 16 at 9:36 PM

This is a huge issue for me. This single issue is preventing me from going live on Azure.

jlopezr wrote May 12 at 11:09 PM

Please, please, please.

JYL wrote May 29 at 5:15 PM

Wow ! Works great now.
Thank you very much for the fix !