При выгрузке отчетов и печатных форм из 1С в формат Excel разработчики часто сталкиваются с неприятным поведением: числовые коды, артикулы, номера счетов, ИНН или телефоны с ведущими нулями (например, "00123") автоматически преобразуются платформой в числа. В результате лидирующие нули безвозвратно теряются, а в свойствах ячейки Excel отображается формат «Общий» вместо ожидаемого формата «Текстовый».
Выясним причину такого поведения и подробно разберем практические способы решения этой проблемы средствами 1С и сопутствующих механизмов.
Проанализируем работу встроенного конвертера платформы 1С. Когда мы вызываем метод ТабличныйДокумент.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX), платформа выполняет внутреннюю трансляцию структуры ячеек. При этом настройки макета Область.Формат или Область.СодержитЗначение = Истина с типом Строка определяют отображение данных только внутри самой 1С.
Штатный механизм экспорта платформы 1С не назначает ячейкам Excel числовой формат «Текстовый» (обозначаемый в Excel символом @). Любая строка, содержащая исключительно цифры и разделители, расценивается конвертером как числовое значение и записывается с форматом «Общий» (General). Чтобы обойти это системное ограничение, рассмотрим проверенные варианты реализации.
Файлы современного формата XLSX представляют собой обычные zip-архивы, содержащие набор XML-файлов и медиаресурсов. Мы можем использовать штатные средства платформы для работы с архивами и XML, чтобы напрямую скорректировать стили и типы ячеек после сохранения документа.
Разберем по шагам логику этого подхода:
Записать().ЧтениеZipФайла и распаковываем сформированный XLSX во временный каталог.xl/worksheets/, например, sheet1.xml) и файл стилей оформления xl/styles.xml.<c> для текстового представления должна иметь атрибут типа t="s" (ссылка на таблицу общих строк sharedStrings.xml) либо t="inlineStr" с прямым текстовым тегом <is><t>Значение</t></is>, либо ссылаться на стиль с числовым форматом @.ЗаписьZipФайла, сохраняя расширение .xlsx.Посмотрим на пример базовой распаковки и упаковки документа средствами платформы:
// 1. Сохраняем исходный табличный документ
ИмяФайлаXLSX = ПолучитьИмяВременногоФайла("xlsx");
ТабДок.Записать(ИмяФайлаXLSX, ТипФайлаТабличногоДокумента.XLSX);
// 2. Распаковываем архив во временный каталог
КаталогРаспаковки = КаталогВременныхФайлов() + "xlsx_unpack_" + СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
АрхивЧтение = Новый ЧтениеZipФайла(ИмяФайлаXLSX);
АрхивЧтение.ИзвлечьВсе(КаталогРаспаковки, РежимВосстановленияФайловZIP.ПереписыватьБолееНовые);
АрхивЧтение.Закрыть();
// 3. Выполняем обработку XML (чтение и замену тегов через ЧтениеXML / ЗаписьXML)
// Обрабатываем файлы в КаталогРаспаковки + "/xl/worksheets/"
// 4. Собираем архив обратно
ИмяИтоговогоФайла = "C:\Export\Result.xlsx";
АрхивЗапись = Новый ЗаписьZipФайла(ИмяИтоговогоФайла);
АрхивЗапись.Добавить(КаталогРаспаковки + "\*", РежимСохраненияПутейZIP.СохранятьОтносительныеПути);
АрхивЗапись.Записать();
// Удаляем временные файлы
УдалитьФайлы(КаталогРаспаковки);
УдалитьФайлы(ИмяФайлаXLSX);
Этот способ является полностью кроссплатформенным, не требует сторонних программ на сервере и позволяет добиться стопроцентного соответствия форматов стандарту OpenXML.
Если решение работает в операционной системе Windows и на рабочей машине установлен Microsoft Excel, мы можем применить автоматизацию через COM-объект. Это наиболее прямолинейный способ принудительно задать формат «Текстовый» ячейкам или колонкам.
Рассмотрим подробнее программную реализацию:
ИмяФайла = "C:\Export\Report.xlsx";
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);
Попытка
ExcelПриложение = Новый COMОбъект("Excel.Application");
ExcelПриложение.Visible = Ложь;
ExcelПриложение.DisplayAlerts = Ложь;
Книга = ExcelПриложение.Workbooks.Open(ИмяФайла);
Лист = Книга.Sheets(1);
// Устанавливаем текстовый формат для всей первой колонки
Лист.Columns("A:A").NumberFormat = "@";
// Или для конкретной ячейки
Лист.Cells(2, 1).NumberFormat = "@";
Книга.Save();
Книга.Close();
ExcelПриложение.Quit();
Исключение
Если ExcelПриложение <> Неопределено Тогда
ExcelПриложение.Quit();
КонецЕсли;
ВызватьИсключение "Ошибка взаимодействия с Excel: " + ОписаниеОшибки();
КонецПопытки;
Важно помнить: данный способ не подходит для серверных процессов под управлением Linux, а также может вызывать зависание фоновых заданий при возникновении диалоговых окон операционной системы.
Если основная бизнес-задача заключается не в строгом присутствии надписи «Текстовый» в меню Excel, а в защите кодов и артикулов от потери лидирующих нулей при открытии пользователем, можно применить быстрое платформенное решение.
В момент формирования табличного документа к началу или концу строки добавляется неразрывный пробел с помощью функции Символ(160) или предопределенного значения Символы.НПП:
ОбластьМакета.Параметры.КодНоменклатуры = Строка(ТекущиеДанные.Артикул) + Символы.НПП;
Платформа 1С при анализе ячейки видит нечисловой символ и сохраняет значение исключительно как строку. При открытии такого файла в Excel лидирующие нули не пропадают, хотя формат ячейки формально останется «Общий».
Microsoft Excel полноценно интерпретирует HTML-документы. При этом поддерживаются специализированные стили форматирования Microsoft Office, в частности стилевое свойство mso-number-format.
Если сформировать файл с расширением .xls или .html, в котором для ячеек прописан класс с правилом mso-number-format:"\@", Excel при открытии жестко присвоит этим элементам формат «Текстовый»:
// Фрагмент формирования HTML-кода ячейки
СтрокаHTML = "<td style=""mso-number-format:'\@';"">00012345</td>";
Такой подход избавляет от необходимости использовать COM-объекты и надежно фиксирует текстовое отображение цифровых данных.