Home » excel » Is it possible to calculate the width of an Excel column using .Net or OpenXml framework without using System.Drawing objects Graphics and Bitmap?

Is it possible to calculate the width of an Excel column using .Net or OpenXml framework without using System.Drawing objects Graphics and Bitmap?

Posted by: admin May 14, 2020 Leave a comment

Questions:

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

How to&Answers:

“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