Формула для преобразования пикселей .NET в ширину Excel в формате OpenXML - PullRequest
12 голосов
/ 10 октября 2011

Я потратил много часов, пытаясь определить формулу для преобразования пикселей .NET в ширину столбца Excel с использованием формата OpenXML.Я использую EPPlus для создания документов xmls.Я пытаюсь определить ширину столбца, который должен иметь размеры Авто.Я получаю количество пикселей, измеряя строку, а затем пытаюсь преобразовать ее в ширину столбца для OpenXML, которая измеряется в символах, я думаю.

Я прочитал документацию Microsoft о том, как преобразовать ее ипопробовал формулу, которую они предлагают, но она даже близко не является точной:

http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.column.aspx

Вот мой код с использованием их формулы:

    public double GetCharacterWidth(string Text, Font f, Graphics g)
    {
        float MaxDigitWidth = g.MeasureString("0", f).Width;
        float Pixels = g.MeasureString(Text, f).Width;

        return ((Pixels - 5) / MaxDigitWidth * 100 + 0.5) / 100;
    }

Любые идеи

Ответы [ 2 ]

19 голосов
/ 26 октября 2011

Сначала нам нужно установить, как Excel выполняет преобразование (так как мы вручную изменяем размер в приложении Excel):

//Use 7d to promote to double, otherwise int will truncate.
ExcelWidth = (Pixels - 12) / 7d +  1;//From pixels to inches.

Предупреждение : формулы не работают для 0(ноль) Ширина или Пиксели.Для этих сценариев используйте оператор «if», чтобы проверить, равен ли ноль, и вернуть ноль.Вместо того, чтобы пытаться определить количество пикселей на ширину, я посмотрел на разницу в пикселях между каждым целым числом ширины и обнаружил, что оно всегда равно 7. Исключение составляет 0 к 1 ширине;где было 12 пикселей для ширины 1,00.Оттуда я смог придумать формулы выше, легко-peasy.

Теперь эти числа остаются в мире Excel, но если вы устанавливаете ширину столбцов непосредственно в документе OpenXml, этонемного другая история.И вот почему: в документации, на которую вы ссылаетесь, говорится о 5 пикселях:

Имеется 4 пикселя отступов полей (по два с каждой стороны), плюс 1 пиксель для линий сетки.

Теперь все это означает, что Excel предполагает, что вы ввели эти 5 пикселей в ширину, которую вы предоставляете.Когда вы откроете документ в Excel и измените размеры столбцов, вы увидите, что ширина на 5 пикселей меньше, чем вы установили.

Чтобы настроить это, вы можете обновить формулы следующим образом:

//Use 7d to promote to double, otherwise int will truncate.
OpenXmlWidth = (Pixels - 12 + 5) / 7d + 1;//From pixels to inches.

Это ответит на заголовок вашего вопроса:" Формула для преобразования пикселей .NET в ширину Excel в формате OpenXML "

Если вы хотите узнать, как изобразить аппроксимацию ширины столбца для автоматического подбора столбца на основе содержимого(и шрифт) одной ячейки, тогда это совершенно другой вопрос.Формулы, предоставленные по указанной вами ссылке Microsoft, работать не будут.Введите 10 периодов в одной ячейке и 10 заглавных букв в другом столбце.Вы увидите, что автоподгонка дает вам 41 пиксель и 129 пикселей соответственно.Формулы, указанные в ms, не учитывают ширину отдельных символов.Другими словами;они отправили вас в погоню за диким гусем.

Единственный способ автоматической подгонки столбца состоит в сканировании каждой строки в столбце и вычислении ширины текста на основе символов и используемого шрифта.Вы бы использовали что-то вроде того, что я нашел здесь .Затем возьмите максимальное значение этого и добавьте 5. Я бы избегал такого подхода при обработке электронных таблиц в веб-среде, потому что вы могли бы экспортировать сотни тысяч строк с десятками столбцов - вы поймете.Наилучший подход состоит в том, чтобы установить оптимальную ширину для ваших столбцов и обучить пользователей тому, как выполнять автоматическую подгонку из Excel.

С уважением," Обычный человек " Редактировать - 26.10.2011:

Поскольку я чувствую себя щедрым, вот пример того, как получить приблизительную ширину для вашего столбца.Я бы предпочел не делать этого для всех строк в столбце, поэтому давайте просто основывать нашу ширину (по умолчанию) на значении в ячейке вашего заголовка.Ниже описано, как вы могли бы сделать это, используя пример, на который я ссылался ранее.Примечание. Это приблизительные значения, но достаточно близкие.

using System.Drawing;
using System.Windows.Forms;//Add Reference.  Test on webserver first.
Font font = new Font("Calibri", 11.0f, FontStyle.Regular);
string header  = "Hello There World!";
int pxBaseline = TextRenderer.MeasureText("__", font).Width;
int pxHeader   = TextRenderer.MeasureText("_" + header + "_"), font).Width;
int pxColumnWidth = pxHeader - pxBaseline + 5;//Pad with 5 for Excel.

Предостережение : если вы используете этот код в том же месте, где вы используете OpenXml, то вам может потребоваться удалить "используя "для System.Drawing и полностью квалифицировать" Font "и" FontStyle "как System.Drawing.Font и System.Drawing.FontStyle.В противном случае ваш компилятор может ошибочно принять эти классы за принадлежность DocumentFormat.OpenXml.Spreadsheet.

1 голос
/ 12 декабря 2018

Формула, которую я придумал для преобразования ширины пикселя в ширину Excel:

    private double PixelWidthToExcel(int pixels)
    {
        var tempWidth = pixels * 0.14099;
        var correction = (tempWidth / 100) * -1.30;

        return tempWidth - correction;
    }

Для меня это всегда дает точное преобразование значения.

И формула для высоты

    private double PixelHeightToExcel(int pixels)
    {
        return pixels * 0.75;
    }
...