1
Vote

Exception in ExcelFontXml.GetHeightByName

description

Exception occurred for missing key in OfficeOpenXml.Style.XmlAccess.ExcelFontXml.GetHeightByName(string name, float size).

This occurred when processing an Excel file generated using SSRS that contained a chart. Going up the stack, the method was called using default name = "Calibri", size = 0, from the method ExcelDrawingBase.GetRowHeightFromCellFonts(int row, ExcelWorksheet ws), where f.Name = "", f.Size = 0.

The issue is clear because the dictionary contains keys of font sizes from 6 to 256, but when size = 0, the "min" variable is never changed from its initial value of -1, causing the exception to be thrown on FontSize.FontHeights[name][min].

A possible fix for the method is below, and I intentionally did not include Linq extensions so the code is pretty basic following the pattern that is already there:
        private static float GetHeightByName(string name, float size)
        {
            if (FontSize.FontHeights[name].ContainsKey(size))
            {
                return FontSize.FontHeights[name][size].Height;
            }
            else
            {
                float min = -1, max = 500;
                float minKey = 500, maxKey = -1;
                foreach (var h in FontSize.FontHeights[name])
                {
                    if (h.Key < minKey)
                    {
                        minKey = h.Key;
                    }
                    if (h.Key > maxKey)
                    {
                        maxKey = h.Key;
                    }
                    if (min < h.Key && h.Key < size)
                    {
                        min = h.Key;
                    }
                    if (max > h.Key && h.Key > size)
                    {
                        max = h.Key;
                    }
                }
                if (!FontSize.FontHeights[name].ContainsKey(min))
                {
                    min = minKey;
                }
                if (!FontSize.FontHeights[name].ContainsKey(max))
                {
                    max = maxKey;
                }
                if (min == max)
                {
                    return Convert.ToSingle(FontSize.FontHeights[name][min].Height);
                }
                else
                {
                    return Convert.ToSingle(FontSize.FontHeights[name][min].Height  + (FontSize.FontHeights[name][max].Height - FontSize.FontHeights[name][min].Height) * ((size - min) / (max - min)));
                }
            }
        }

comments