К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как записать файл на диск в 1С: способы и примеры

Как записать файл на диск в 1С: ЗаписьТекста, ДвоичныеДанные, НачатьЗапись, работа на клиенте и сервере, примеры кода и типичные ошибки.

Запись файла на диск — одна из базовых задач при разработке на платформе 1С:Предприятие: выгрузка отчётов, обмен данными, сохранение печатных форм, выгрузка XML и CSV. В зависимости от типа данных (текст, двоичные данные, табличный документ) и места выполнения кода (клиент или сервер) применяются разные объекты и методы встроенного языка.

Ключевой момент, который часто упускают начинающие разработчики: код на сервере и код на клиенте видят разные файловые системы. Файл, записанный сервером 1С, окажется на диске серверного компьютера, а не на компьютере пользователя. Для передачи файла пользователю нужно либо записать его на клиенте, либо передать через временное хранилище.

Ниже разобраны основные способы записи: текстовые файлы через объект «ЗаписьТекста», двоичные данные, табличные документы, асинхронные методы для тонкого и веб-клиента, а также проверка результата и типичные ошибки.

Какие объекты 1С используются для записи файлов

Платформа предоставляет несколько встроенных объектов, и выбор зависит от типа данных:

  • ЗаписьТекста — текстовые файлы (CSV, XML вручную, логи, произвольные текстовые выгрузки);
  • ЗаписьXML, ЗаписьJSON, ЗаписьFastInfoset — структурированные данные в соответствующих форматах;
  • ДвоичныеДанные.Записать() — сохранение картинок, архивов и любых бинарных данных;
  • ТабличныйДокумент.Записать() — сохранение макетов и отчётов в Excel, PDF, HTML и других форматах;
  • ТекстовыйДокумент.Записать() — простой вариант для текста без потоковой записи.

Для простых случаев удобнее ТекстовыйДокумент: загрузили строки, вызвали «Записать» — готово. Для больших файлов лучше ЗаписьТекста, так как он пишет потоково и не держит весь контент в памяти.

Запись текстового файла через ЗаписьТекста

Объект «ЗаписьТекста» создаётся с указанием пути к файлу и, при необходимости, кодировки. Типовой пример:

Запись = Новый ЗаписьТекста("C:\Выгрузки\данные.txt", КодировкаТекста.UTF8);

Запись.ЗаписатьСтроку("Номенклатура;Цена");

Для Каждого СтрокаТовара Из ТаблицаТоваров Цикл

Запись.ЗаписатьСтроку(СтрокаТовара.Наименование + ";" + Формат(СтрокаТовара.Цена, "ЧГ=0"));

КонецЦикла;

Запись.Закрыть();

Метод Закрыть() обязателен: пока он не вызван, данные могут оставаться в буфере, а файл — заблокированным. Если файл с таким именем уже существует, по умолчанию он будет перезаписан; для добавления строк в конец используйте конструктор с параметром «Добавить».

Альтернатива — ТекстовыйДокумент, когда весь текст уже сформирован:

Документ = Новый ТекстовыйДокумент;

Документ.УстановитьТекст(ГотовыйТекст);

Документ.Записать("C:\Выгрузки\данные.txt", КодировкаТекста.UTF8);

Запись двоичных данных и картинок

Картинки, PDF из хранилища значений, архивы и любые бинарные данные записываются методом Записать() объекта «ДвоичныеДанные»:

ДвоичныеДанные = Справочники.Файлы.НайтиПоКоду(Код).Хранилище.Получить();

ДвоичныеДанные.Записать("C:\Выгрузки\картинка.jpg");

Если данные пришли из временного хранилища (например, после фоновой обработки или с сервера), сначала получите их по адресу через ПолучитьИзВременногоХранилища(Адрес), а затем запишите на диск тем же методом.

Сохранение табличного документа (Excel, PDF, MXL)

Табличные документы — отчёты, печатные формы — сохраняются методом Записать() с указанием типа файла:

ТабДок.Записать("C:\Выгрузки\отчет.xlsx", ТипФайлаТабличногоДокумента.XLSX);

ТабДок.Записать("C:\Выгрузки\отчет.pdf", ТипФайлаТабличногоДокумента.PDF);

Доступные форматы включают MXL (родной формат 1С), XLSX, PDF, HTML, ODS, TXT и другие. Формат определяется вторым параметром, а не расширением в имени файла: если записать в формате MXL файл с расширением .xlsx, Excel его не откроет.

Типичные ошибки
01
Запись файла в серверном коде и ожидание, что он появится у пользователя — файл остаётся на сервере
02
Не вызван Закрыть() у ЗаписьТекста — файл пустой или заблокирован другими процессами
03
Несовпадение расширения файла и ТипФайлаТабличногоДокумента — файл не открывается в целевой программе
04
Использование жёстко прописанного пути C:\ на сервере Linux — ошибка записи, нужен путь в формате ОС сервера

Запись файла на клиенте и на сервере: в чём разница

В клиент-серверном режиме директивы компиляции определяют, где выполняется код. Код в &НаСервере работает с файловой системой сервера, &НаКлиенте — с диском компьютера пользователя. Это принципиально для выгрузок, которые пользователь должен получить локально.

Типовая схема «сформировать на сервере — сохранить у пользователя» выглядит так: серверная процедура формирует данные и помещает их во временное хранилище, клиентская процедура получает данные по адресу и записывает на диск либо предлагает пользователю выбрать путь через диалог сохранения.

&НаСервере

Функция СформироватьНаСервере()

ТабДок = Новый ТабличныйДокумент;

// ... заполнение табличного документа

ИмяФайла = ПолучитьИмяВременногоФайла("xlsx");

ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX);

Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ИмяФайла), УникальныйИдентификатор);

УдалитьФайлы(ИмяФайла);

Возврат Адрес;

КонецФункции

&НаКлиенте

Процедура Сохранить(Команда)

Адрес = СформироватьНаСервере();

ПолучитьФайл(Адрес, "Отчет.xlsx", Истина);

КонецПроцедуры

Сравнение вариантов

Запись на сервере + временное хранилище

Подходит для больших файлов и фоновых операций; требует передачи на клиент и доступности диска сервера

Прямая запись на клиенте

Проще, файл сразу у пользователя; не работает для тяжёлых выборок и недоступна в некоторых контекстах

ПолучитьФайл с диалогом

Пользователь сам выбирает путь сохранения; единственный надёжный вариант для веб-клиента

Асинхронные методы для тонкого и веб-клиента

В тонком и веб-клиенте синхронные вызовы файловой системы ограничены. Для них используются асинхронные методы с «Начать»: НачатьЗапись() у двоичных данных, НачатьПолучениеФайлов, НачатьПолучениеРабочегоКаталогаДанныхПользователя и другие. Результат обрабатывается в описании оповещения.

В веб-клиенте прямой записи в произвольный каталог нет вовсе: файл можно только «отдать» пользователю через механизм получения файла, и браузер сохранит его в папку загрузок или предложит диалог. Это ограничение браузерной модели безопасности, а не платформы.

Проверка результата и обработка ошибок

Запись файла может завершиться ошибкой: нет прав, диск переполнен, путь не существует, файл занят другим процессом. Оборачивайте запись в попытку и проверяйте результат:

Попытка

Запись = Новый ЗаписьТекста(ИмяФайла, КодировкаТекста.UTF8);

Запись.ЗаписатьСтроку(Текст);

Запись.Закрыть();

Исключение

Сообщить("Не удалось записать файл: " + ОписаниеОшибки());

КонецПопытки;

Дополнительно полезно проверить существование каталога перед записью (объект «Файл», метод Существует()) и создать его через СоздатьКаталог(), если его нет. После записи можно убедиться, что файл появился и имеет ненулевой размер.

Порядок действий для выгрузки текстового файла
  1. 1
    Определите, где должен выполняться код: на клиенте или на сервере
  2. 2
    Сформируйте путь к файлу и проверьте существование каталога
  3. 3
    Создайте объект ЗаписьТекста с нужной кодировкой
  4. 4
    Запишите данные построчно в цикле
  5. 5
    Вызовите Закрыть() и убедитесь, что файл появился и открывается
Контрольные точки

Как проверить результат

Файл существует по указанному пути
Норма

Файл на месте, размер больше нуля

Тревожный признак

Файла нет или размер 0 байт — запись не выполнилась или не вызван Закрыть()

Содержимое файла
Норма

Текст читаем, кириллица отображается корректно

Тревожный признак

Кракозябры — неверная кодировка при записи

Расположение файла
Норма

Файл на диске пользователя, а не сервера

Тревожный признак

Файл найден только на сервере — код выполнялся в серверном контексте

Часто задаваемые вопросы

Как записать файл в кодировке UTF-8 без BOM?

Передайте в конструктор ЗаписьТекста или в метод Записать текстового документа значение КодировкаТекста.UTF8. По умолчанию платформа записывает UTF-8 без BOM; если внешняя система требует BOM, используйте КодировкаТекста.UTF8 с параметром записи BOM, где это поддерживается, либо допишите маркер вручную через двоичные данные.

Почему файл записывается пустым?

Чаще всего не вызван метод Закрыть() у объекта ЗаписьТекста — данные остались в буфере. Реже причина в том, что в цикл записи вообще не зашли (пустая таблица) или запись выполняется на сервере, а вы ищете файл на клиентском компьютере.

Как сохранить файл, чтобы пользователь сам выбрал папку?

Используйте ПолучитьФайл(Адрес, ИмяФайла, Истина) на клиенте — третий параметр открывает диалог сохранения. Либо примените ДиалогВыбораФайла в режиме Сохранение и запишите файл по выбранному пути.

Можно ли дописывать данные в существующий файл?

Да. У ЗаписьТекста есть конструктор с параметром «Добавить»: Новый ЗаписьТекста(ИмяФайла, Кодировка, , Истина) — новые строки будут добавлены в конец файла вместо его перезаписи. У ТекстовыйДокумент такого режима нет, файл перезаписывается целиком.

Как записать файл на сервере Linux?

Указывайте пути в формате Linux (например, /opt/1c/export/file.csv) и убедитесь, что у пользователя, под которым работает агент сервера 1С, есть права на запись в этот каталог. Жёстко зашитые пути вида C:\ работать не будут — выносите каталог в настройки.

Чем ПолучитьИмяВременногоФайла отличается от обычного пути?

Метод возвращает уникальное имя во временном каталоге системы, что исключает конфликты имён при параллельных выгрузках. После использования временный файл следует удалять через УдалитьФайлы, чтобы не засорять диск сервера.

Итог

Что важно запомнить

Текст пишется через ЗаписьТекста или ТекстовыйДокумент, двоичные данные — методом Записать, табличные документы — с указанием ТипФайлаТабличногоДокумента. Всегда закрывайте запись, учитывайте разницу между клиентом и сервером, а для передачи файла пользователю используйте временное хранилище и ПолучитьФайл.