Как создать pdf файл c

Обновлено: 07.07.2024

На высшем уровне процесс создания документов PDF с расширенным доступом состоит из нескольких основных этапов.

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

Эти этапы представлены в порядке, подходящем для большинства задач. Однако можно выполнять задачи и в другом порядке или повторять некоторые этапы. В любом случае сначала необходимо просмотреть документ, определить его предполагаемое назначение и использовать этот анализ для определения ряда операций, которые нужно выполнить.

Дополнительные ресурсы

Дополнительные сведения о создании файлов PDF с расширенным доступом представлены в следующих ресурсах:

Обеспечение поддержки функций расширенного доступа перед преобразованием документа в формат PDF

По возможности следует обеспечить поддержку функций расширенного доступа для документов PDF во время создания исходных файлов в каком-либо приложении, например в текстовом приложении или в приложении для создания макетов страниц.

Типичные этапы обеспечения такой поддержки в исходном приложении включают добавление дополнительного текста к графике, оптимизацию таблиц и применение стилей абзацев или других элементов структуры документа, которые можно преобразовать в теги. Дополнительные сведения представлены в разделе Создание документа PDF с тегами из исходного приложения.

Добавление заполняемых полей форм и описаний, установка порядка следования

Если в файле PDF содержатся поля форм, выберите «Инструменты» > «Расширенный доступ» > Выполнить распознавание полей форм , чтобы обнаружить поля форм и сделать их интерактивными (заполняемыми).

Воспользуйтесь инструментами «Формы» для создания полей форм, например кнопок, флажков, всплывающих меню и текстовых окон. При создании поля введите его описание в текстовом окне «Всплывающая подсказка» диалогового окна «Свойства». Программа чтения с экрана прочитает этот текст вслух. Дополнительная информация представлена в разделе Создание полей форм.

Можно также использовать инструмент «Порядок чтения» в Acrobat Pro для добавления описаний в поля форм.

Сведения о задании порядка табуляции в структуре документа представлены в разделе «Установка навигации по полям формы».

Добавление других функций расширенного доступа в документ PDF

В Acrobat Pro этот этап включает настройку языка документа, проверку того, что настройки защиты не мешают работе программ чтения с экрана, создание ссылок с расширенным доступом и добавление закладок. Дополнительные сведения см. в разделах Настройка языка документа, Изменение параметров защиты, препятствующих работе программ чтения с экрана, Добавление ссылок с расширенным доступом и Сведения о закладках.

В Acrobat Standard этот этап включает настройку языка документа, проверку того, что параметры защиты не мешают работе программ чтения с экрана и добавление закладок. Дополнительные сведения см. в разделах Настройка языка документа, Изменение параметров защиты, препятствующих работе программ чтения с экрана и Сведения о закладках.

Создание тегов в документе PDF

Можно обеспечить расширенный доступ документов PDF, добавляя в Acrobat теги. Если документ PDF не содержит теги, то Acrobat может выполнить попытку их автоматической расстановки при прочтении или перекомпоновке документа, при этом результаты могут быть неудовлетворительными. Дерево логической структуры в документах PDF с тегами представляет содержимое программе чтения с экрана или другому вспомогательному программному или аппаратному обеспечению в соответствующем порядке.

Для получения наилучших результатов следует добавлять теги в документ во время преобразования исходного документа в документ PDF из исходного приложения. Это могут быть в том числе такие приложения, как Adobe FrameMaker®, Adobe InDesign®, Microsoft Word или OpenOffice Writer . При отсутствии доступа к приложению, создающему файл PDF с тегами, можно в любое время добавить теги в PDF с помощью Acrobat.

Расстановка тегов в документе во время преобразования в формат PDF требует, чтобы исходное приложение поддерживало расстановку тегов в PDF. Расстановка тегов в документе во время преобразования позволяет приложению получить сведения о стилях абзацев или другую информацию о структуре исходного документа для создания дерева логической структуры. Дерево логической структуры отражает точный порядок чтения и соответствующие уровни тегов. При таком способе расстановки тегов легче выявить структуру сложных макетов, таких как встроенные врезки, близко расположенные столбцы, неоднородное выравнивание текста и таблицы. При расстановке тегов во время преобразования в формат PDF можно также пометить ссылки, перекрестные ссылки, закладки и дополнительный текст (при его наличии), которые находятся в файле.

Чтобы расставить теги в документе PDF при помощи программы Acrobat, выберите «Инструменты» > «Расширенный доступ» > Добавить теги в документ . Эта команда выполняется в любых документах PDF без тегов, например, в таких, которые создаются при помощи программы Adobe PDF Printer . Acrobat анализирует содержимое файла PDF для интерпретации отдельных элементов страницы, их иерархической структуры и порядка чтения каждой страницы. Затем на основе этой информации она создает дерево тегов. Она также создает теги для любых ссылок, перекрестных ссылок и закладок, добавленных в документ в программе Acrobat.

Команда Добавить теги в документ правильно расставляет теги в большинстве стандартных макетов. Однако она не может всегда правильно интерпретировать структуру и порядок чтения сложных элементов страниц. Это могут быть такие элементы, как близко расположенные колонки, необычное выравнивание текста, незаполняемые поля форм и таблицы без границ. Расстановка тегов на таких страницах с помощью команды Добавить теги в документ может привести к неправильной компоновке элементов или беспорядочному расположению тегов. Эти ошибки могут привести к проблемам при чтении файла PDF вслух.

О водяных знаках и программах чтения с экрана

Добавить водяной знак к документу PDF с тегами можно без добавления его в дерево тегов. Отсутствие водяного знака в дереве тегов полезно для людей, использующих программы чтения с экрана, потому что водяной знак не будет прочитан как содержимое документа.

Наилучшим способом добавления водяного знака, не мешающего программам чтения с экрана, является вставка водяного знака без тегов в документ PDF с тегами.

Оценка документа PDF и исправление проблем с тегами (Acrobat Pro)

Независимо от метода расстановки тегов в документе PDF, используйте программу Acrobat , чтобы скорректировать порядок расстановки тегов и порядок чтения для сложных макетов страниц или нестандартных элементов. Например, команда Добавить теги в документ не всегда отличает рисунки от декоративных элементов на странице, таких как границы, линии или фоновые элементы. Она может неправильно пометить тегами все эти элементы как рисунки. Также эта команда может неправильно пометить тегами графические символы внутри текста (например, буквицы) как рисунки вместо того, чтобы включить их в теги, представляющие блоки текста. Такие ошибки могут нарушить дерево тегов и усложнить порядок чтения, на котором основывается вспомогательная программа.

Если расстановка тегов в документе происходит в Acrobat, приложение создает отчет об ошибках после завершения процесса расстановки тегов. Используйте этот отчет как руководство по устранению проблем с расстановкой тегов. Можно определить другие проблемы с тегами, порядком чтения и расширенным доступом для любого документа PDF с помощью инструмента Полная проверка/Проверка на доступность или инструмента Порядок чтения . Дополнительные сведения представлены в разделе Проверка расширенного доступа при помощи команды «Полная проверка/Проверка на доступность» и Проверка и исправление порядка чтения.

Созданный из веб-страницы документ PDF обладает расширенным доступом настолько, насколько им обладает HTML-источник. Например, если макет веб-страницы основан на таблицах, HTML-код может идти не в том логическом порядке чтения, который требуется документу PDF с тегами, даже несмотря на полную структурированность HTML-кода для правильного отображения всех элементов в браузере.

В зависимости от сложности веб-страницы может потребоваться выполнение в программе Acrobat Pro значительных исправлений при помощи инструмента Порядок чтения или редактирования дерева тегов в Acrobat.

Чтобы сделать из созданных веб-страниц документы PDF с большим количеством возможностей расширенного доступа, сначала необходимо установить логический порядок чтения в их HTML-коде. Для наилучших результатов следует воспользоваться руководствами по обеспечению расширенного доступа к содержимому веб-страниц , которые опубликованы консорциумом World Wide Web (W3C). Дополнительные сведения см. в рекомендациях на веб-сайте W3C.

В программе Acrobat выберите «Файл» > «Создать» > PDF из веб-страницы , введите адрес веб-страницы и нажмите «Параметры».

На панели инструментов Adobe PDF в Microsoft Internet Explorer нажмите на стрелку Вниз на кнопке «Преобразовать» и выберите «Установки».

Ко мне в список попало 7 библиотек, о которых я скажу несколько слов, а для самой популярной (судя по ответам на stackoverflow), я напишу, как с помощью неё сделать простейший документ. Сразу скажу, что это iTextSharp и работа с ней будет описана в конце статьи.

Обзор библиотек

1. iTextSharp
Библиотека iText позволяет создавать и манипулировать PDF документами. Она позволяет разработчикам совершенствовать веб и прикладные приложения с помощью динамической генерации и/или манипуляции над PDF документами.

Возможности библиотеки:
Рисования: точки, линии, коробки, круги, кривые Безье, многоугольники, звезды, комплекс путей и форм.
Текст: поддержка юникода, кернинг текста при использовании Helvetica и Times-Roman семейств основных шрифтов, вставка гиперссылок, просто использовать табличный класс с гибкостью отчетных возможностей.
Поддерживает вставку следующих типов изображений: PNG, JPEG, BMP

Быстрый старт с помощью iTextSharp

Как я уже писал ранее, данная библиотека была выбрана не из-за того, что я протестировал все описанные и выбрал её, а по причине того, что на неё чаще всего ссылаются и советуют. Итак, переходим на сайт проекта, видим, что можно купить книжку, а также скачать файлы:
Желания что-то собирать самому, у меня нет, поэтому качаю не исходные коды, а сразу библиотеку itextsharp-5.0.5-dll.zip. С одной библиотекой быстрого старта не выйдет, поэтому качаем примеры iTextSharp.tutorial.01.zip. Открыв архив примеров, я понял, что старт будет гораздо быстрее, чем я думал, т.к. там есть целых 13 глав примеров. Сразу подумал, что на этом можно закончить, но всё же решил сделать небольшое приложение.

Распишу по шагам, что нужно для использования библиотеки:
— Я создаю WinForms приложение.
— Добавляю ссылку на itextsharp.dll.
— Устанавливаю кнопку на форму и добавляю следующий код в обработчик нажатия:

var doc = new Document();
PdfWriter.GetInstance(doc, new FileStream (Application.StartupPath + @"\Document.pdf" , FileMode .Create));
doc.Open();
iTextSharp.text.Image jpg = iTextSharp.text.Image.GetInstance(Application.StartupPath + @"/images.jpg" );
jpg.Alignment = Element.ALIGN_CENTER;
doc.Add(jpg);
PdfPTable table = new PdfPTable(3);
PdfPCell cell = new PdfPCell( new Phrase( "Simple table" ,
new iTextSharp.text. Font (iTextSharp.text. Font .FontFamily.TIMES_ROMAN, 16,
iTextSharp.text. Font .NORMAL, new BaseColor(Color.Orange))));
cell.BackgroundColor = new BaseColor(Color.Wheat);
cell.Padding = 5;
cell.Colspan = 3;
cell.HorizontalAlignment = Element.ALIGN_CENTER;
table.AddCell(cell);
table.AddCell( "Col 1 Row 1" );
table.AddCell( "Col 2 Row 1" );
table.AddCell( "Col 3 Row 1" );
table.AddCell( "Col 1 Row 2" );
table.AddCell( "Col 2 Row 2" );
table.AddCell( "Col 3 Row 2" );
jpg = iTextSharp.text.Image.GetInstance(Application.StartupPath + @"/left.jpg" );
cell = new PdfPCell(jpg);
cell.Padding = 5;
cell.HorizontalAlignment = PdfPCell.ALIGN_LEFT;
table.AddCell(cell);
cell = new PdfPCell( new Phrase( "Col 2 Row 3" ));
cell.VerticalAlignment = PdfPCell.ALIGN_MIDDLE;
cell.HorizontalAlignment = PdfPCell.ALIGN_CENTER;
table.AddCell(cell);
jpg = iTextSharp.text.Image.GetInstance(Application.StartupPath + @"/right.jpg" );
cell = new PdfPCell(jpg);
cell.Padding = 5;
cell.HorizontalAlignment = PdfPCell.ALIGN_RIGHT;
table.AddCell(cell);
doc.Add(table);
doc.Close();

* This source code was highlighted with Source Code Highlighter .

example

Результат работы данного кода:

Выводы

По каждой из приведенных библиотек в интернете можно найти уйму информации (начинать рекомендую с сайтов разработчиков), готовя данную подборку библиотек, я встречал разные мнения, хоть все библиотеки, казалось бы, предназначены для работы с pdf, но возможности у них разные, всё зависит от Ваших потребностей. Честно скажу, что все из них я не использовал, я лишь попробовал несколько из них и остановился на iTextSharp.

Пожелание: Если Вы указываете, что остановились на той или иной библиотеке, то не поленитесь указать, что явилось для Вас решающим при выборе.

Заголовок. Заголовком называется первая строка файла. Она содержит информацию о версии PDF. В нашем тестовом документе заголовок выглядит так:

PDF начал свою историю с версии 1.0. Последняя на текущий момент версия — 1.7. Символ % обозначает комментарий в языке PostScript, который лег в основу формата.

Тело. Все содержимое документа находится в теле файла. Типы данных, которые встречаются в теле, рассмотрим в следующем разделе.

Таблица xref. Эта таблица содержит ссылки на все объекты документа. Благодаря ей, не нужно читать весь документ, чтобы найти нужный объект. Таблица xref состоит из секций. Каждая секция соответствует новой версии документа.

Таблица ссылок начинается со слова xref. Каждая секция начинается с двух чисел: идентификатора первого объекта и количества объектов в секции. Объекты представляются двумя последовательностями байтов. Первая соответствует позиции первого байта объекта в файле, а вторая — номеру поколения. О поколениях и метках f и n будет немного позже.

Хвост. Этот раздел дает информацию о расположении ключевых объектов в файле. Например, в нем прописано смещение таблицы xref от начала файла. Поэтому любое программное чтение PDF-документа начинается с хвоста. В нашем примере:

Хвост начинается с ключевого слова trailer. Он включает в себя словарь с мета-информацией о документе и позицию начала таблицы ссылок. Конец файла отмечается строкой %%EOF. В словарь хвоста входят данные о количестве объектов (/Size), ссылки на каталог документа (/Root — об этом немного позже) и информационный словарь (/Info), а также идентификатор файла (/ID).

В теле документа содержится вся информация, которая отображается пользователю. Она может быть представлена восемью типами данных:

Любой PDF-объект может быть помечен уникальным идентификатором и использоваться как ссылка. Такие объекты называются косвенными. Они начинаются с идентификатора, номера поколения и ключевого слова obj. Заканчивается косвенный объект словом endobj. На эти объекты можно ссылаться в таблице xref и любом другом объекте (для этого используется символ R). Так как они содержатся в таблице ссылок, доступ к ним осуществляется очень быстро.

Формат PDF спроектирован с идеей инкрементальных обновлений документа. То есть, при изменении содержимого, файл не перезаписывается заново. В его конец добавляются новый заголовок, xref таблица и хвост. В новых таблицах ссылок будут записаны только те объекты, которые были добавлены, изменены или удалены. Удаленные объекты помечаются символом f, а новые символом n. Каждый хвост содержит запись /Prev, которая указывает на предыдущую таблицу xref.

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

Каталог документа ссылается на корень дерева страниц. Листья дерева являются страницами. Каждый узел дерева содержит информацию о родителе, детях и количестве листьев среди потомков. Каждую страницу документа можно найти по записи /Page, корень дерева страниц — по записи /Pages, а каталог документа — по /Catalog.

Теперь, когда мы получили общее представление о формате данных PDF, мы можем перейти к связанным с ним задачам. Структура PDF-документов сложна, поэтому даже задача извлечения текста не является тривиальной. Текст содержится в объектах, где есть потоки. Обычно он сжат, возможно, несколькими способами. Об этом скажут те самые фильтры из мета-информации потока. Кроме того, каждый символ в потоке зашифрован в соответствии с таблицей символов, которая также хранится в PDF-документе.

Для работы с существующим PDF-документом создадим экземпляр класса PdfReader.

PdfReader содержит информацию о всех тех объектах, которые были рассмотрены. Например, мы можем просмотреть мета-информацию каталога документа:

Для извлечения текста из документа используется статический класс PdfTextExtractor. Помимо PdfReader’а он принимает на вход номер страницы.

Задачи, связанные со структурой текста, такие как выделение параграфов, заголовков и тому подобные вообще не имеют общего решения. Это связано с тем, что в PDF-файле не хранится этой информации, только лишь потоки текста. Но PdfTextExtractor может принимать третий параметр – реализацию интерфейса ITextExtractionStrategy. Вы можете написать свою стратегию обработки текста, которая будет учитывать специфичные для вашего случая параметры (позицию на странице, шрифт и т.д.). В результате вы получите не только текст, но и структурные элементы.

Выберите свои файлы изображений, которые будут добавлены в PDF или перетащите их в активную область и приступите к созданию. Через несколько секунд после этого вы сможете скачать свою PDF книгу изображений.

Поддерживает разные форматы файлов изображений

Вы можете выбрать изображения других форматов для создания PDF книги изображений, таких как JPG, PNG, GIF and TIFF.

Просто в использовании

Мы максимально упростили для вас процесс создания PDF книги изображений. Не требуется установка или настройка, просто выберите файлы и приступите к созданию.

Поддерживает вашу систему

Для создания PDF книги изображений вам не требуется какая-либо специальная система. Инструмент работает на всех распространенных операционных системах и браузерах.

Установка не требуется

Вам не нужно скачивать и устанавливать какие-либо программы. Создание PDF книги изображений происходит в облаке на наших серверах. Этот инструмент не потребляет ресурсы вашей системы.

Безопасность важна для нас

Ваши файлы изображений не хранятся на нашем сервере дольше чем это требуется. Изображения и результаты будут удалены с нашего сервера через короткий промежуток времени.

Разработано Stefan Ziegler

Что говорят другие

С этим инструментом я могу объединить разные изображения в один PDF. Любой сможет просмотреть PDF. Благодаря этому мне не нужно отправлять много разных картинок по отдельности.
Идея представить изображения в виде PDF просто отличная. Я могу встроить картинки в один PDF файл. Если размер PDF файла будет большим, я смогу уменьшить его при помощи инструмента сжатия.

Вопросы и ответы

Как я могу создать PDF-файл из нескольких изображений?

  1. Кликните на поле выбора файла вверху страницы, чтобы выбрать изображения, которые вы хотите преобразовать в PDF.
  2. При необходимости исправьте порядок изображений с помощью перетаскивания.
  3. Начните создание вашего PDF с помощью соответствующей кнопки.
  4. Сохраните созданный PDF-файл на свой компьютер с помощью кнопки скачивания.

Безопасно ли использовать инструменты PDF24?

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

  1. Все передачи файлов зашифрованы.
  2. Все файлы удаляются автоматически из обрабатывающего сервера в течение часа после обработки.
  3. Мы не храним файлы и не оцениваем их. Файлы используются только по назначению.
  4. PDF24 принадлежит немецкой компании Geek Software GmbH. Все обрабатывающие серверы находятся в центрах обработки данных на территории ЕС.

Могу ли я использовать PDF24 на Mac, Linux или смартфоне?

Да, вы можете использовать PDF24 Tools в любой системе, в которой у вас есть доступ в Интернет. Откройте PDF24 Tools в веб-браузере, таком как Chrome, и используйте инструменты прямо в веб-браузере. Никакого другого программного обеспечения устанавливать не нужно.

Вы также можете установить PDF24 в качестве приложения на свой смартфон. Для этого откройте инструменты PDF24 в Chrome на своем смартфоне. Затем щелкните значок «Установить» в правом верхнем углу адресной строки или добавьте PDF24 на начальный экран через меню Chrome.

Могу ли я использовать PDF24 в офлайн без подключения к Интернету?

Да, пользователи Windows также могут использовать PDF24 в офлайн, то есть без подключения к Интернету. Просто скачайте бесплатный PDF24 Creator и установите программное обеспечение. PDF24 Creator переносит все инструменты PDF24 на ваш компьютер в виде настольного приложения. Пользователи других операционных систем должны продолжать использовать PDF24 Tools.

Возникла задача (и, как показал поиск, не у меня одного) формирования печатных форм в формате pdf для отправки клиентам. Причем процесс этот должен был происходить практически полностью автоматически - в один-два клика. То, что я нашел на эту тему в сети меня не устроило по тем или иным причинам, поэтому пришлось писать свое. Первое с чем я столкнулся - это достаточно скудное количество информации на эту тему, очень мало примеров. Несколько дней разбирался сам, теперь решил поделиться опытом с вами. Америку, я конечно не открыл, но пару интересных решений в процессе написания родилось - возможно кому-то пригодится и сэкономит время.

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

Итак, сначала немного предыстории. Изучив вопрос, я остановил свой выбор на бесплатных виртуальных принтерах BullZip PDF Printer и PDFCreator, которые позволяют на выходе получать файлы pdf, а также файлы различных графических форматов. Обе утилиты имеют возможность автосохранения файлов без лишних вопросов пользователю. В принципе, для полуавтоматического создания печатных форм в электронном виде, этого достаточно. Мы можем написать в коде

ТабДок . ИмяПринтера = "PDFCreator" ; //"BullZip PDF Printer";
ТабДок . Напечатать ();

и в каталогах, указанных в настройках автосохранения, появятся нужные файлы. Но, во-первых, пользователь может что-нибудь в настройках изменить, во-вторых, принтер вообще может оказаться переименован или удален чьими-нибудь шаловливыми ручонками (то есть нам нужно как-то контролировать имя и вообще наличие виртуального принтера в системе), в-третьих, придется настроить автосохранение для каждого пользователя (если принтер не сетевой), в-четвертых, проблематично добиться вменяемого имени файла с помощью настроек. Да и вообще, мы же все хотим делать автоматически, а так пользователю придется самому создать письмо, указать адрес клиента, прикрепить нужные вложения - вероятность ошибки возрастает, ну и лениво конечно. Приходим к выводу, что нужно юзать COM-объект, самому устанавливать необходимые настройки и выполнять нужные действия, чтобы не взрывать потом мозг ни себе, ни пользователю.

Изначально имелось пожелание сохранять файлы в графическом формате, скажем jpeg или png. PDFCreator, по-моему мнению, обладает более гибкими возможностями, но, к сожалению, он не умеет разбивать изображения на страницы, поэтому при сохранении печатных форм в виде картинок, можно наблюдать только первую страницу документа. BullZip же такую функцию имеет, поэтому я начал работать с ним. Но вот его COM-интерфейс оказался довольно скудным, да и плюс ко всему, настройки свои утилита хранит в ini-файле. Соответственно тратится время на их чтение и запись, если мы хотим (а мы хотим!) в них что-то менять. Вобщем, чтобы не извращаться и не придумывать всякую ерунду, было принято решение сохранять печатные формы в pdf и использовать для этих целей PDFCreator. Полностью конечно "ерунды" избежать не удалось, но в целом задача была решена.

Собственно дальше код моей функции для формирования файлов с подробными комментариями в проблемных местах. Функция выдрана из модуля обработки с минимальными изменениями, поэтому имеет "узкие" места в виде привязки к конфигурации и конкретному виду документов. Но общий смысл понятен и при необходимости код легко может быть преобразован для конкретной задачи.

upd 14.04.2011

Сегодня понадобилось переписать обработку, сделав ее более универсальной. Теперь в главную функцию передается массив готовых табличных документов для конвертации в pdf. Для передачи имен файлов используется свойство табличного документа "ИспользуемоеИмяФайла", которое необходимо заполнить программно до вызова функции конвертации.

upd 03.05.2011

Выявил неявный баг. У табличного документа есть свойство "ИмяПараметровПечати". Оно отвечает за сохранение параметров печати, установленных пользователем, и их восстановление при следующем показе табличного документа. Так вот, если это свойство используется в конфигурации (а в типовых оно, как правило, используется), то при печати в pdf в указанных параметрах будет сохранен наш виртуальный pdf-принтер, и, если в следующий раз табличный документ будет печататься обычным способом, то 1С восстановит именно этот принтер для печати по-умолчанию (не путать с принтером по-умолчанию в Windows). Чтобы этого избежать, после формирования наших файлов, вернем табличному документу его старое имя принтера.

// Функция формирует файлы для отправки по электронной почте с помощью виртуального принтера PDFCreator,
// Возвращаемое значение: тип "Массив" - массив сформированных файлов pdf
// Параметры: ТабличныеДокументы - тип "Массив", массив табличных документов для конвертации
// Путь - тип "Строка", путь к каталогу, в котором будут создаваться конечные файлы pdf
//
Функция PDFCreator_СформироватьФайлыДляОтправки ( ТабличныеДокументы , Путь ) Экспорт

Состояние ( "Настройка виртуального принтера . " );

// Получим виртуальные принтеры, установленные в системе, если нет ни одного - создадим новый, если есть - будем использовать первый попавшийся
ПринтерыPDF = УтилитаПечати . cGetPDFCreatorPrinters ();
Если ПринтерыPDF . Count () = 0 Тогда
УтилитаПечати . cAddPDFCreatorPrinter ( "PDFCreator" );
ПринтерыPDF = УтилитаПечати . cGetPDFCreatorPrinters ();
КонецЕсли;
ИмяПринтераPDF = ПринтерыPDF . Item ( 1 );

// Запустим утилиту, в области уведомлений появится соответствующий значок очереди печати
УтилитаПечати . cStart ();

// PDFCreator позволяет создавать несколько профилей с настройками - это очень удобно: мы не будем менять настройки по умолчанию, а создадим отдельный профиль для печати из 1С и будем его использовать. То есть для "ручной" печати пользователь может настроить принтер как ему вздумается.
// Проверим, существует ли профиль для печати документов из 1С, если нет - создадим
Если Не УтилитаПечати . cProfileExists ( "Печать 1С" ) Тогда
УтилитаПечати . cAddProfile ( "Печать 1С" , УтилитаПечати . cStandardOptions );
КонецЕсли;

// Поскольку теоретически пользователь может изменить настройки и нашего профиля, а некоторые из них для нас критичны, будем записывать их принудительно каждый раз. Это настройки автосохранения, остальные - пусть меняет, если надо.
// Запишем настройки профиля, которые не должны меняться
НастройкиПоУмолчанию = УтилитаПечати . cReadOptions ( "Печать 1С" );
НастройкиПоУмолчанию . UseAutosave = 1 ;
НастройкиПоУмолчанию . UseAutosaveDirectory = 1 ;
НастройкиПоУмолчанию . UseCreationDateNow = 1 ;
НастройкиПоУмолчанию . AutosaveDirectory = Путь ;

// Подробно на каждой опции останавливаться не буду, думаю и так понятно. Поясню только принципиальный момент, на котором строится дальнейшая логика работы функции.
// Я долго пытался добиться более менее вменяемого и при этом уникального имени файла стандартными настройками - это оказалось довольно проблематично. В итоге я пришел к такой схеме: в качестве имени файла автосохранения используем предопределенную настройку Title - заголовок нашего документа. Поскольку табличный документ мы создаем программно, средствами 1С изменить его не удастся (есть лишь возможность задать его при выводе на экран, указав в качестве первого параметра метода Показать()). Соответственно, используя такую настройку, мы всегда будем получать файл вида "Табличный документ.pdf". Что ж, значит, придется переименовать его после. Если бы мы печатали один файл, можно было задать его имя сразу в настройках, но мы-то хотим печатать много и сразу, а в этом случае опции просто не будут успевать сохраняться. Короче говоря, экспериментальным путем я пришел именно к такому варианту.
НастройкиПоУмолчанию . AutosaveFileName = "Title" ; // Здесь Title должно быть в угловых скобках, но редактор HTML воспринимает это как тег и сбивает разметку

НастройкиПоУмолчанию . AutosaveFormat = 0 ; // 0 = PDF, 1 = PNG, 2 = JPEG, 3 = BMP, 4 = PCX, 5 = TIFF, 6 = PS, 7 = EPS, 8 = TXT, 9 = PDF/A-1b, 10 = PDF/X, 11 = PSD, 12 = PCL, 13 = RAW
НастройкиПоУмолчанию . AutosaveStartStandardProgram = 0 ;
УтилитаПечати . cSaveOptions ( НастройкиПоУмолчанию , "Печать 1С" );

Состояние ( "Создание файлов . " );

// Делаем наши настройки текущими. Возможно как-то можно сделать активным конкретный профиль программно, но мне это не удалось, а так - заработало и ладно. По сути здесь мы подменяем настройки по умолчанию своими.
УтилитаПечати . cOptionsProfile = "Печать 1С" ; // эта строка, по-моему, не работает, но так "красивше" =)
УтилитаПечати . cOptions = НастройкиПоУмолчанию ;

// Собственно, начинаем штамповать наши файлы
МассивФайлов = Новый Массив ;
Для Индекс = 0 По ТабличныеДокументы . Количество () - 1 Цикл
// Получаем табличный документ по индексу из массива. Цикл Для . По . используем для того, чтобы иметь возможность сразу получать индекс элемента из счетчика без применения метода Найти().
ТабДок = ТабличныеДокументы [ Индекс ];

// Запоминаем старое имя принтера, т.к. при использовании параметров печати, они будут сохраняться с нашим pdf-принтером
СтароеИмяПринтера = ТабДок . ИмяПринтера ;

// Далее уже знакомый нам кусок кода. Все настройки сделаны - можем смело печатать.
ТабДок . ИмяПринтера = ИмяПринтераPDF ;
ТабДок . Напечатать ();

// Здесь одна особенность, которую я победил не очень хорошим способом. Помните, что у нас все файлы называются "Табличный документ.pdf"? Это нас не устраивает - надо переименовать, но поскольку принтер работает не мгновенно, необходимо сначала дождаться, пока файл сформируется и запишется на диск. Так что запускаем цикл и ждем пока файл появится. Да, грузится проц, но что поделать - это ненадолго.
// На случай, если что-то пойдет не так, ставим ограничение в 30 секунд, по истечении которых цикл прерываем принудительно
ФайлСформирован = Истина;
ФайлPDF = Новый Файл ( Путь + "Табличный документ.pdf" );
Порог = ТекущаяДата () + 30 ;
Пока Не ФайлPDF . Существует () И ФайлСформирован Цикл
ОбработкаПрерыванияПользователя ();

Если ТекущаяДата () >= Порог Тогда
ФайлСформирован = Ложь;
КонецЕсли;
КонецЦикла;
// Наш файл уже существует, но еще не записан - ждем еще, но не более 30 секунд
Порог = ТекущаяДата () + 30 ;
Пока ФайлPDF . Размер () = 0 И ФайлСформирован Цикл
ОбработкаПрерыванияПользователя ();

Если ТекущаяДата () >= Порог Тогда
ФайлСформирован = Ложь;
КонецЕсли;
КонецЦикла;

Возврат Неопределено;
КонецЕсли;

// Вот теперь переименуем его. Используем свойство табличного документа "ИспользуемоеИмяФайла" (должно быть заполнено программно до вызова процедуры, предполагается, что имя файла указано без расширения), либо , если оно не заполнено , просто порядковый номер элемента.
НовоеПолноеИмя = Путь + ?( ЗначениеЗаполнено ( ТабДок . ИспользуемоеИмяФайла ), ТабДок . ИспользуемоеИмяФайла , "Табличный документ " + Строка ( Индекс + 1 ) ) + ".pdf" ;
ПереместитьФайл ( ФайлPDF . ПолноеИмя , НовоеПолноеИмя ) ;

// Добавим в массив вложений, который вернет в итоге наша функция
ФайлPDF = Новый Файл ( НовоеПолноеИмя );
МассивФайлов . Добавить ( ФайлPDF );

// Возвращаем старое имя принтера, чтобы не менялись параметры печати по-умолчанию
ТабДок . ИмяПринтера = СтароеИмяПринтера ;
КонецЦикла;

// Закрываем утилиту - иконка в трее пропала. Что примечательно, закрывать раньше времени очередь печати нельзя, а то пропадут все задания, но так как мы с нетерпением ждем появления каждого файла и в этот момент уже дождались, то тут все ок.
УтилитаПечати . cClose ();
УтилитаПечати = Неопределено;
НастройкиПоУмолчанию = Неопределено;

Ну а дальше уже дело техники, что с этими файлами делать. Я, например, использую встроенный в УТ почтовый клиент, создаю новое письмо, заполняю адрес из контактной информации контрагента, добавляю туда вложения и открываю письмо пользователю для просмотра и принятия решения об отправке, а pdf-ки с диска удаляю.

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

upd 08.10.2010

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

// Функция формирует файлы для отправки по электронной почте с помощью внешней компоненты Yoksel.dll
//
Функция Йоксель_СформироватьФайлыДляОтправки ( ТабличныеДокументы , Путь )

Попытка
ЗагрузитьВнешнююКомпоненту ( КаталогПрограммы () + "Yoksel.dll" );

Йоксель = ПолучитьCOMОбъект ( "" , "Йоксель" );
КонвертерPDF = Йоксель . СоздатьГрафическийКонвертерPDF ();
Исключение
Предупреждение ( "Не удалось загрузить внешнюю компоненту Yoksel! Сообщите администратору системы!" , 20 );
Возврат Неопределено;
КонецПопытки;

МассивФайлов = Новый Массив ;

Состояние ( "Создание файлов . " );

Для Индекс = 0 По ТабличныеДокументы . Количество () - 1 Цикл
// Получаем табличный документ
ТабДок = ТабличныеДокументы [ Индекс ];

// Формируем временный файл xls
ИмяФайлаБезРасширения = ?( ЗначениеЗаполнено ( ТабДок . ИспользуемоеИмяФайла ), ТабДок . ИспользуемоеИмяФайла , "Табличный документ " + Строка ( Индекс + 1 ) ) ;
ТабДок . Записать ( Путь + ИмяФайлаБезРасширения + ".xls" , ТипФайлаТабличногоДокумента . XLS97 );

// Удаляем временный файл xls
УдалитьФайлы ( Путь + ИмяФайлаБезРасширения + ".xls" );

// Добавляем в массив вложений
ФайлPDF = Новый Файл ( Путь + ИмяФайлаБезРасширения + ".pdf" );
МассивФайлов . Добавить ( ФайлPDF );
КонецЦикла;

Читайте также: