1

I'm developing a class, which allows users to create Excel spreadsheets on the fly (using OpenXML api) and I need to calculate columns width, so that they auto-fit the widest cell in the column.

I have the following code to calculate each column's width (using the formula from here and this tutorial):

private double CalculateColumnWidth(int textLength)
        {
            var font = new System.Drawing.Font("Calibri", 11);

            float digitMaximumWidth = 0;
            using(var graphics = Graphics.FromImage(new Bitmap(200, 200)))
            {
                for(var i = 0; i < 10; ++i)
                {
                    var digitWidth = graphics.MeasureString(i.ToString(), font).Width;
                    if (digitWidth > digitMaximumWidth)
                        digitMaximumWidth = digitWidth;
                }
            }

            return Math.Truncate((textLength * digitMaximumWidth + 5.0) / digitMaximumWidth * 256.0) / 256.0;
        }

This works fine, the only question is: Is there any way to get rid of the Bitmap and Graphics objects, that I don't really need to calculate the Excel's column width? Why is the Graphics object necessary to do this? Thx in advance

Edward Wilde
  • 23,831
  • 8
  • 52
  • 64
Skog
  • 503
  • 1
  • 6
  • 16

1 Answers1

3

"Column width measured as the number of characters of the maximum digit width of the numbers 0, 1, 2, …, 9 as rendered in the normal style's font. There are 4 pixels of margin padding (two on each side), plus 1 pixel padding for the gridlines. Reference: http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.column.aspx

You need to calculate the width of each number 0 - 10 and determine which of those has the largest width. An easy way to accomplish this in .Net is to use MeasureString in System.Drawing.Graphics one of it's constructors requires a valid Bitmap. If your main process contains a window, i.e. you are a desktop windows app, you could construct the graphic object without a bitmap using:

Graphics graphics = Graphics.FromHwnd(Process.GetCurrentProcess().MainWindowHandle)

It is also possible to use classes in System.Windows.Media part of WPF see:http://stackoverflow.com/questions/1528525/alternatives-to-system-drawing-for-use-with-asp-net

Edward Wilde
  • 23,831
  • 8
  • 52
  • 64