Простое объединение PDF-файлов

27.10.26

Задачи пользователя - Разное

Утилита берёт все PDF-файлы из указанного каталога, сортирует их по именам и объединяет в один PDF-файл. Одна операция — один вызов. Никаких других функций нет. Работает шустро, весит мало!

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Пример готовой обработки для объединения PDF-файлов (обычные формы)
.epf 36,54Kb
0 2 500 руб. Купить
Утилита для простого объединение PDF-файлов (EXE)
.exe 39,50Kb
0 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

Разработана на C#. Объем менее 40КБ.

Внешние программы не требуются: нет Adobe Acrobat/Reader, нет Office, нет Ghostscript,
нет сторонних PDF-библиотек (PDFsharp/iText и т. п.). Разбор и сборка PDF реализованы внутри.

Среда. Windows + .NET Framework 4.x. На Windows 10/11 он установлен по умолчанию; 1С:Предприятие 8.3 сама требует CLR 4.x, поэтому на машинах с 1С зависимость уже выполнена.
 

Интерфейс командной строки

MergePdf.exe /InPath <каталог> /OutPath <файл.pdf | каталог> [/Log <журнал>]
MergePdf.exe /Response <файл параметров>
MergePdf.exe <каталог> <результат> [журнал]

Параметр

Алиасы

Смысл

/InPath

/in, /i, /src

каталог с исходными PDF

/OutPath

/out, /o, /dst

файл результата или каталог

/Log

/logpath, /l

файл журнала (по умолчанию %TEMP%\MergePdf.log)

/Response

/params, /paramsfile

файл параметров: строки InPath=, OutPath=, Log=

/Help

/h, /?

краткая справка (код 2)

Пример вызова: 

MergePdf.exe /InPath "D:\Сканы\Договор" /OutPath "D:\Результат\Договор.pdf" /Log "C:\Temp\mp.log"

 

Правила обработки

  • Какие файлы. Все файлы с расширением .pdf в самом каталоге InPath (регистр расширения не важен). Вложенные каталоги не обходятся.

  • Порядок. «Естественная» сортировка по имени: 1.pdf, 2.pdf, 10.pdf (числовые группы сравниваются как числа, буквы — без учёта регистра).

  • Файл результата исключается из списка исходных: можно писать результат в тот же каталог, повторный запуск не «съест» предыдущий результат.

  • OutPath. Оканчивается на .pdf — это имя файла; иначе — каталог (создаётся при необходимости), результат кладётся в merged.pdf.

  • Запись. Сначала *.tmp, затем переименование: недописанный файл не остаётся на месте результата.

  • Ошибки. Любая проблема с конкретным файлом возвращается с его именем (Файл "х.pdf": это не PDF-файл., Файл "у.pdf" защищён паролем ...).

 

Собственный PDF-движок

Сторонних PDF-библиотек нет — реализован минимальный, но «честный» набор:

  • лексер/парсер объектов PDF (словари, массивы, имена с #xx, литеральные и hex-строки с сохранением escape-последовательностей, числа, ссылки n g R, потоки с косвенной /Length);

  • таблица ссылок в двух видах: классическая xref и перекрёстные потоки (xref streams, PDF 1.5+) с /W, /Index и PNG-предиктором;

  • объектные потоки (/ObjStm, сжатые наборы объектов — обычное дело для «офисных» PDF);

  • цепочки инкрементальных обновлений /Prev и гибридные файлы /XRefStm;

  • декодеры: FlateDecode (с автоопределением zlib-заголовка), ASCIIHexDecode, ASCII85Decode, RunLengthDecode; предикторы PNG (10–15) и TIFF (2);

  • восстановление структуры линейным сканированием файла, если startxref/xref повреждены.

 

Как собирается результат

  1. Из каждого файла выбираются страницы обходом дерева /Pages; наследуемые атрибуты (/Resources, /MediaBox, /CropBox, /Rotate) «протаскиваются» в сами страницы.

  2. Объекты всех документов перенумеровываются в один диапазон, все косвенные ссылки пересчитываются (ссылка на отсутствующий объект становится null).

  3. Служебные объекты (/Type /XRef, /Type /ObjStm) не переносятся — они не нужны вне исходного файла.

  4. Строится единый узел /Pages: у каждой страницы переписывается /Parent, при отсутствии /MediaBox подставляется A4 (595×842).

  5. Новый каталог (/Catalog) и /Info из первого файла; содержимое потоков копируется байт в байт с пересчётом /Length.

  6. Файл пишется с заголовком %PDF-1.7, классической таблицей xref и трейлером;

 

Исполнение, память, производительность

  • Один поток, без фоновых задач и таймеров; работа заканчивается вместе с процессом.

  • Каждый исходный файл читается в память целиком (File.ReadAllBytes), затем строится граф объектов. Пиковая память ≈ сумма размеров файлов + накладные расходы объектов, поэтому гигабайтные сканы требуют соответствующего объёма ОЗУ.

  • Замеры на машине разработки (Windows 11, i5-12400F):

Сценарий

Время

«Пустой» запуск (/Help)

≈1,01 с

2 файла, 81 КБ → 3 страницы

≈1,01 с

3 файла, 52,1 МБ → 78 страниц

≈1,01 с

Собственно объединение 52,1 МБ / 78 страниц (в процессе, через MergePdf.exe)

0,11 с

Вывод: время определяется запуском процесса, а не обработкой. Для сравнения, пустая .NET-программа на той же машине стартует за 1,01–1,05 с — столько же, то есть накладные расходы создаёт инициализация CLR и проверка файла антивирусом, а не код утилиты.

 

Ограничения

  • PDF, защищённые паролем (в том числе с пустым паролем пользователя), не объединяются — расшифровка не реализована, возвращается ошибка с именем файла.

  • Не поддерживаются фильтры LZWDecode, JBIG2Decode, JPXDecode при декодировании. Декодирование нужно только для перекрёстных потоков и объектных потоков (там практически всегда FlateDecode); содержимое страниц и изображения копируется байт в байт вместе с исходными фильтрами, поэтому сканы с DCTDecode/JBIG2Decode/JPXDecode объединяются нормально.

  • Закладки (/Outlines) и интерактивные формы (/AcroForm) не переносятся; страницы, содержимое, шрифты, изображения и ссылки-аннотации — переносятся.

  • Метаданные документа (/Info) берутся из первого файла.

  • Вложенные каталоги не обходятся.

  • Нет слияния «по списку файлов» и настройки порядка — только каталог и естественная сортировка по именам.

Поставка

  • Утилита (EXE)

  • Пример обработки на обычных формах (EPF), утилита содержится в макете обработки. Код обработки открыт.

Пример вызова из 1С:

////////////////////////////////////////////////////////////////////////////////
// MergePdf — объединение PDF-файлов каталога в один файл.
//
// Возвращает текст журнала, например:
//     OK: файлов 3, страниц 12, файл: D:\Результат\Договор.pdf
// При ошибке — вызывает исключение с текстом причины.
//
// Как работает:
//   1. во временном каталоге разворачивается утилита MergePdf.exe из макета «Утилита»;
//   2. параметры записываются в файл params.txt, утилита запускается как
//          MergePdf.exe /Response "<params.txt>"
//      поэтому кавычки, пробелы и завершающие «\» в путях не могут сломать разбор
//      командной строки;
//   3. читается журнал работы (при ошибке в нём есть «Данные вызова»);
//   4. временный каталог удаляется — и при успехе, и при ошибке.
//
// Командное окно не появляется: утилита собрана как приложение Windows.
// Коды возврата утилиты: 0 — успех, 1 — ошибка объединения, 2 — неверные параметры.
//
// Используются только методы, доступные в клиентском контексте (проверено на 8.3.27).
////////////////////////////////////////////////////////////////////////////////

Функция ОбъединитьPDF(InPath, OutPath) Экспорт

	// Пустые параметры отсекаем сразу: иначе ошибка будет выглядеть как проблема разбора.
	Если Не ЗначениеЗаполнено(InPath) Тогда
		ВызватьИсключение "MergePdf: не задан InPath (каталог с PDF-файлами).";
	КонецЕсли;

	Если Не ЗначениеЗаполнено(OutPath) Тогда
		ВызватьИсключение "MergePdf: не задан OutPath (путь результата).";
	КонецЕсли;

	КаталогВременных = КаталогВременныхФайлов();
	Если Прав(КаталогВременных, 1) <> "\" Тогда
		КаталогВременных = КаталогВременных + "\";
	КонецЕсли;

	ВременныйКаталог = КаталогВременных + "MergePdf_" + Строка(Новый УникальныйИдентификатор());

	Попытка

		СоздатьКаталог(ВременныйКаталог);

		// 1. Извлекаем утилиту из макета во временный каталог.
		ПутьКУтилите = ВременныйКаталог + "\MergePdf.exe";

		Макет = ПолучитьМакет("Утилита");
		Если ТипЗнч(Макет) = Тип("ДвоичныеДанные") Тогда
			Макет.Записать(ПутьКУтилите);
		Иначе
			ВызватьИсключение "Макет ""Утилита"" должен содержать двоичные данные.";
		КонецЕсли;

		// 2. Параметры — отдельным файлом: в командной строке нет путей пользователя.
		ФайлЖурнала = ВременныйКаталог + "\merge.log";
		ФайлПараметров = ВременныйКаталог + "\params.txt";

		Запись = Новый ЗаписьТекста(ФайлПараметров, КодировкаТекста.UTF8);
		Запись.ЗаписатьСтроку("InPath=" + Строка(InPath));
		Запись.ЗаписатьСтроку("OutPath=" + Строка(OutPath));
		Запись.ЗаписатьСтроку("Log=" + ФайлЖурнала);
		Запись.Закрыть();

		Команда = """" + ПутьКУтилите + """ /Response """ + ФайлПараметров + """";

		КодВозврата = 0;
		ЗапуститьПриложение(Команда, ВременныйКаталог, Истина, КодВозврата);

		// 3. Читаем то, что записала утилита: отчёт об успехе или причину ошибки.
		ТекстЖурнала = "";
		Файл = Новый Файл(ФайлЖурнала);
		Если Файл.Существует() Тогда
			Чтение = Новый ЧтениеТекста(ФайлЖурнала, КодировкаТекста.UTF8);
			ТекстЖурнала = Чтение.Прочитать();
			Чтение.Закрыть();
			ТекстЖурнала = СокрЛП(СтрЗаменить(ТекстЖурнала, Символ(65279), ""));   // убрать BOM
		КонецЕсли;

		Если КодВозврата <> 0 Тогда
			Если Не ЗначениеЗаполнено(ТекстЖурнала) Тогда
				ТекстЖурнала = "Не удалось объединить PDF (код " + КодВозврата + "). Команда: " + Команда;
			КонецЕсли;
			ВызватьИсключение ТекстЖурнала;
		КонецЕсли;

		Результат = ТекстЖурнала;

	Исключение

		Попытка
			УдалитьФайлы(ВременныйКаталог);
		Исключение
			// Временный каталог уберёт система — на результат это не влияет.
		КонецПопытки;

		ВызватьИсключение;

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

	Попытка
		УдалитьФайлы(ВременныйКаталог);
	Исключение
		// Временный каталог уберёт система — на результат это не влияет.
	КонецПопытки;

	Возврат Результат;

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

Проверено на следующих конфигурациях и релизах:

  • Управление производственным предприятием, редакция 1.3, релизы 1.3.286.2

Вступайте в нашу телеграмм-группу Инфостарт

Объединение PDF MergePdf 8.2

См. также

Разное Пользователь 1С 8.3 1С 8.5 1С:Управление торговлей 11 Абонемент ($m)

Представлен алгоритм обработки, позволяющий использовать таблицу значений на форме как таблицу экселя.

2 стартмани

02.11.2026    604    1    aximo    3    

11

Разное 1С 8.5 Домашние учет и финансы Россия Бесплатно (free)

Здравствуйте! Закончил курс "1С Разработчик" на одной популярной площадке. Ищу работу, в процессе поиска понимаю, что как такового опыта практического нет, и нужен какой-то pet-проект. В 1С существует огромное количество решений огромного количества сфер деятельности. Встал вопрос: что можно реализовать и как? Открываю "ИИ" и прошу его подкинуть идею (2026 век все-таки на дворе :D). Предложил "Куратор: «Домашний помощник»". Теперь как делать? Решил установить EDT и полностью положиться на Напарника. Получилось следующее: Описание решения «Домашний помощник» для 1С «Домашний помощник» — это готовая подсистема для платформы 1С:Предприятие 8.5, предназначенная для автоматизации бытовых задач семьи: ведения дел, учёта покупок и товаров, контроля расходов и коммунальных платежей, фиксации показаний счётчиков, а также организации обслуживания домашней техники.

12.08.2026    1036    31    cet241    2    

4

Разное 1С 8.3 Россия Абонемент ($m)

Чего только не было написано на 1С, но вот удивительно, не нашел ни одного проекта по астрологии. Решил исправить такой недостаток :) Конфигурация для расчёта и анализа астрологических карт с собственным астрономическим движком и встроенной интеграцией с языковыми моделями (LLM). Платформа 1С:Предприятие 8.3.27, файловый режим, написана полностью на встроенном языке без внешних компонент.

1 стартмани

22.06.2026    1331    11    AlxPop    12    

9

Разное Бесплатно (free)

Способы, как сэкономить при оплате ИИ-подписок.

18.06.2026    2641    SergMuravev    10    

9

Разное Бесплатно (free)

На связи Сергей Скирдин, технический директор компании «Белый код». Мы занимаемся проектами в сфере управления данными: интеграции, хранилища, BI. Поэтому мне особенно интересно следить за тем, как развивается экосистема 1С в смежных для нас направлениях. В субботу посетил мероприятие для разработчиков и технических специалистов 1С. Хотелось послушать про «1С:Шину», «1С:КХД», «1С:Аналитику» и в целом понять, куда движется мир разработки и технологий 1С. Расскажу, что интересного для себя отметил. Технологии 1С:Предприятие: вопросы и размышления

15.04.2026    2340    sergey.skirdin    0    

5

Разное 1С 8.3 Абонемент ($m)

Внешняя обработка для объединения файлов изображений в единый PDF файл, работает на платформе 1С 8.3.21 и выше.

1 стартмани

24.03.2026    1147    5    evg520750    0    

5

Разное 1С 8.3 Абонемент ($m)

Представляю демку "Infostart". Для тех, кто еще помнит на 8 битных компьютерах такое явление, как демосцена. Олды пустят ностальгическую слезу, молодежь офигеет. Такого на 1С вы точно еще не видели!

23.03.2026    1689    2    DmitryKSL    14    

12
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. dehro 15 29.10.26 09:59 Сейчас в теме
А чем плох штатный "ЗаписьPDF"?
2. madonov 287 29.10.26 10:06 Сейчас в теме
(1) Он доступен, начиная с версии 8.3.16.

Представленное решение работает независимо от режима совместимости конфигурации. Именно поэтому пример обработки на обычных формах.
Для отправки сообщения требуется регистрация/авторизация