Всем привет. Уже неделю мучаюсь с этим вопросом. Работу я делаю для Ревита, но в Автокаде тоже самое.
Итак, стоит задача - получить ячейку в файле экселя и отрисовать её в автокаде (т.е. и рамочку и текст).
Создаю файл экселя, заполняю первую ячейку:
Размеры ячейки в самом файле экселя: ширина - 19,43 ед. (141 пиксель); высота - 15,00 поинтов (20 пиксель). Единицы измерения ширины ячеек в экселе - это отдельная песня:
Ширина столбца на листе может иметь значение от 0 до 255. Оно соответствует числу знаков, которые могут отображаться в ячейке, отформатированной с использованием стандартного шрифта. Ширина столбца по умолчанию составляет 8,43 знака
Благо, Office.Interop.Excel выдает ширину еще и в поинтах, поэтому одной головной болью меньше.
Сделал небольшой тестовый проект (приложу к теме), который читает первую ячейку в эксель файле. В нем же я пытаюсь перевести единицы экселя в нужные мне. В частности, в миллиметры. Проект прикладываю к теме.
Для начала перевожу размеры ячейки:
Excel.Workbook wb = eXapp.Workbooks.Open(fileName);
Excel.Worksheet ws = wb.Worksheets[1];
Excel.Range cell = ws.Cells[1, 1];
float dpiX = GetDpiX();
float dpiY = GetDpiY();
var str = cell.Text;
Msg($"First cell text: {str}");
var cellWidthInPoints = cell.Width;
var cellHeightInPoints = cell.Height;
Msg($"Cell width in points: {cellWidthInPoints}");
Msg($"Cell height in points: {cellHeightInPoints}");
var cellWidthInPixels = ConvertPointToPixels(cellWidthInPoints, dpiX);
var cellHeightInPixels = ConvertPointToPixels(cellHeightInPoints, dpiY);
Msg($"Cell width in pixels: {cellWidthInPixels}");
Msg($"Cell height in pixels: {cellHeightInPixels}");
Msg($"Cell height in mm: {ConvertPixelsToMm(cellHeightInPixels, dpiY)}");
Msg($"Cell width in mm: {ConvertPixelsToMm(cellWidthInPixels, dpiX)}");
В итоге получаю размер ячейки в мм: 5,291667х37,30625. Отрисовываю её в автокаде.
Вот дальше начинается просто непонятная мне хрень - нужно получить размеры текста. И как бы не было это странно, но ширину всей строки получить получается, а высоту - НЕТ!
Для измерения ширины строки нужно использовать класс Font и класс Graphics из библиотеки System.Drawing. Тут тоже пришлось помучаться, но нашел наиболее точный вариант измерения:
var fW2 = _MeasureDisplayStringWidth(Graphics.FromHwnd(IntPtr.Zero), str, font);
Msg($"text width 2: {fW2}");
var textWidthInMm = ConvertPixelsToMm(fW2, dpiX);
....
protected int _MeasureDisplayStringWidth(Graphics graphics, string text, Font font)
{
if (text == "")
return 0;
StringFormat format = new StringFormat(StringFormat.GenericDefault);
RectangleF rect = new RectangleF(0, 0, 1000, 1000);
CharacterRange[] ranges = { new CharacterRange(0, text.Length) };
Region[] regions = new Region[1];
format.SetMeasurableCharacterRanges(ranges);
format.FormatFlags = StringFormatFlags.MeasureTrailingSpaces;
regions = graphics.MeasureCharacterRanges(text, font, rect, format);
rect = regions[0].GetBounds(graphics);
return (int)(rect.Right);
}
При измерении ширины строки получаю 34,925 мм
Возвращаюсь в автокад и создаю текст. Подгонял на глаз, чтобы примерно было похоже на эксель. Высоту текста подгонял только в десятках (в сотнях было бы точнее):
Т.е. высоту текста в мм я должен получить примерно 2,6 мм. Вот тут и проблема - сколько я не пробую, сколько ни ищу информацию - но у меня никак этого не получается. Все возможные попытки выдают мне высоту текста много больше!
Может я просто уже устал и не вижу чего-то очевидного ( Надеюсь на свежий взгляд других пытливых умов.
З.Ы. Я многие методы не привел в тексте. Все есть в приложенном проекте