При выгрузке отчетов из 1С в файлы табличных редакторов Microsoft Excel разработчики часто сталкиваются с неприятным дефектом: встроенная диаграмма сжимается по горизонтали, превращаясь в узкую полосу, либо сильно деформируется. Разберем причины такого поведения платформы и детально рассмотрим способы решения данной проблемы.
Выясним причину возникновения ошибки. При экспорте табличного документа механизм платформы 1С не формирует полноценный интерактивный график Excel. Вместо этого диаграмма конвертируется в растровый графический объект и размещается на листе таблицы. В 1С координаты и габариты объектов коллекции Рисунки измеряются в миллиметрах, в то время как формат Excel рассчитывает размеры в пунктах и точках с учетом разрешения экрана (DPI) и базовых шрифтов книги. При трансляции стандартный конвертер производит пересчет координат со значительными погрешностями, а привязка объекта к границам колонок искажает итоговую ширину графического элемента.
Проанализируем практический подход, предложенный на форуме. Если отчет формируется программно в объект ТабличныйДокумент, мы можем скорректировать габариты объекта в коллекции рисунков непосредственно перед тем, как записать файл на диск.
Посмотрим на пример реализации в процедуре выгрузки отчета:
// Формируем табличный документ отчета программно
ТабДокумент = Новый ТабличныйДокумент;
ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
ОтчетОбъект.СкомпоноватьРезультат(ТабДокумент);
// Находим объект диаграммы в коллекции рисунков
Если ТабДокумент.Рисунки.Количество() > 0 Тогда
Диаграмма = ТабДокумент.Рисунки[0];
// Компенсируем сжатие ширины коэффициентом пересчета
Диаграмма.Ширина = Диаграмма.Ширина * 5;
Диаграмма.РазмерКартинки = ИзменениеРазмераКартинки.Растянуть;
КонецЕсли;
// Сохраняем итоговый результат в файл Excel
ТабДокумент.Записать("C:\Reports\ReportChart.xlsx", ТипФайлаТабличногоДокумента.XLSX);
Разберем по шагам, что происходит в данном коде:
ТабДокумент.Рисунки.Ширина. Точный коэффициент подбирается эмпирически под конкретный макет (в приведенном примере ширина увеличена в пять раз).РазмерКартинки в значение ИзменениеРазмераКартинки.Растянуть, чтобы графическое представление заняло всю выделенную область.ТабДокумент.Записать(). При последующем пересчете координат в процессе конвертации полученная ширина компенсирует системное сжатие, и в результирующем файле график отображается корректно.Рассмотрим подробнее альтернативный метод позиционирования внутри табличного документа. Вместо использования абсолютных координат и ручного подбора коэффициента ширины мы можем жестко зафиксировать расположение рисунка относительно сетки колонок и строк с помощью метода Расположить().
Посмотрим на пример программной привязки:
// Привязываем рисунок к фиксированному прямоугольнику ячеек
ОбластьДляГрафика = ТабДокумент.Область("R5C2:R25C12");
Если ТабДокумент.Рисунки.Количество() > 0 Тогда
График = ТабДокумент.Рисунки[0];
График.РазмерКартинки = ИзменениеРазмераКартинки.Растянуть;
График.Расположить(ОбластьДляГрафика);
КонецЕсли;
ТабДокумент.Записать("C:\Reports\ReportChart.xlsx", ТипФайлаТабличногоДокумента.XLSX);
В данном случае алгоритм экспорта опирается на явно заданный диапазон ячеек таблицы R5C2:R25C12. Если ширина колонок заранее унифицирована в макете, пропорции сохраняются более стабильно.
Проанализируем влияние выбранного формата файла. Стандартный метод Записать() поддерживает несколько типов файлов для работы с таблицами:
ТипФайлаТабличногоДокумента.XLS транслирует графические элементы точнее, чем в формат OpenXML (XLSX), где правила привязки к сетке более жесткие. Если структура документа допускает использование формата XLS, стоит проверить сохранение с параметром ТипФайлаТабличногоДокумента.XLS.ТипФайлаТабличногоДокумента.PDF. Формат PDF сохраняет исходную верстку табличного документа без искажения пропорций.ТипФайлаТабличногоДокумента.MXL. Это полностью исключает этап сторонней конвертации и гарантирует стопроцентное совпадение внешнего вида.Если требуется безупречное отображение именно в среде Excel, а программная корректировка ширины дает разный результат на клиентских машинах с разным разрешением экранов, разберем вариант с постобработкой готового файла через COM-соединение.
Посмотрим на пример выравнивания свойств созданного объекта:
ПутьКФайлу = "C:\Reports\ReportChart.xlsx";
ТабДокумент.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
// Подключаемся к установленному Excel
Попытка
ExcelПриложение = Новый COMОбъект("Excel.Application");
ExcelПриложение.Visible = Ложь;
ExcelПриложение.DisplayAlerts = Ложь;
Книга = ExcelПриложение.Workbooks.Open(ПутьКФайлу);
Лист = Книга.Sheets(1);
// Если на листе присутствует графический объект
Если Лист.Shapes.Count > 0 Тогда
ФормаГрафика = Лист.Shapes.Item(1);
// Отвязываем изменение размеров объекта от ширины колонок (xlFreeFloating = 3)
ФормаГрафика.Placement = 3;
// Задаем требуемую ширину в пунктах
ФормаГрафика.Width = 500;
КонецЕсли;
Книга.Save();
Книга.Close();
ExcelПриложение.Quit();
Исключение
// Обработка ошибок работы с COM
Если ExcelПриложение <> Неопределено Тогда
ExcelПриложение.Quit();
КонецЕсли;
КонецПопытки;
Установка свойства Placement = 3 (константа xlFreeFloating) отвязывает габариты графика от ячеек листа, благодаря чему ширина объекта перестает зависеть от автоподбора колонок и сохраняет заданные параметры.