Эта страница может содержать автоматически переведенный текст.
Как создавать PDF-документы на C# и VB.NET
В этой статье описаны различные способы создания PDF-документов в .NET с помощью библиотеки Docotic.Pdf. Это высокопроизводительная библиотека .NET на чистом C# без внешних зависимостей, для создания, редактирования, преобразования и обработки PDF-документов.

В следующих разделах я представлю основные подходы к созданию PDF-файлов с помощью Docotic.Pdf:
- Использование Core API, который обеспечивает низкоуровневое управление текстом, графикой и внутренним устройством PDF. Этот вариант лучше всего подходит для нестандартных макетов, документов с большим количеством графики и при использовании расширенных функций.
- Использование высокоуровневого Layout API, который поддерживает абзацы, таблицы, верхние и нижние колонтитулы и автоматическую разбивку на страницы. Этот API идеально подходит, когда вам нужны структурированные документы без ручного расчета позиций.
- Преобразование HTML в PDF с поддержкой SVG и других веб-форматов. Этот подход особенно полезен, когда ваше решение уже создает HTML-документы, и вам нужны PDF-версии этих HTML и CSS файлов.
- Создание PDF-файлов из изображений. Этот метод полезен для отсканированных документов, отчетов на основе изображений, квитанций и в процессах, которые начинаются с растровых изображений.
- Объединение или разделение PDF-файлов. Это хороший вариант для составления отчетов, обработки пользовательских загрузок, объединения связанных документов и реструктуризации больших PDF-файлов.
- Создание PDF-файлов из шаблонов. Этот подход хорош, когда требуется единообразное форматирование для массово создаваемых документов, таких как квитанции, налоговые декларации, трудовые договоры и другие повторяющиеся типы документов.
Дополнительные темы, рассматриваемые в руководстве, включают:
- Интерактивные функции, такие как ссылки и действия JavaScript
- Подходы к тестированию создаваемых PDF для обеспечения ожидаемых результатов
Создание PDF-файлов с помощью Core API
Core API является основой для создания PDF-файлов в Docotic.Pdf. Он предоставляет полный низкоуровневый контроль над размещением текста, изображений и векторной графики на холсте PDF-файла через свой Canvas API. Этот API для рисования является подмножеством Core API и предоставляет методы и свойства, используемые для добавления контента на страницы и другие объекты с холстами. Помимо рендеринга, Core API также поддерживает аннотации, поля форм, слои, закладки и другие функции PDF.
Ниже приведён код на C#, который создаёт простой PDF-файл, используя три основные операции: рисование текста, размещение изображения и рендеринг векторной графики на холсте страницы.
using var pdf = new PdfDocument();
var canvas = pdf.Pages[0].Canvas;
canvas.Font = pdf.CreateFont(PdfBuiltInFont.HelveticaBold);
canvas.FontSize = 14;
canvas.DrawString(40, 100, "Core API demo: text, images, and vector graphics");
var image = pdf.CreateImage("image.png");
canvas.DrawImage(image, 40, 180, 120, 120, 0);
canvas.Pen.Color = new PdfRgbColor(30, 60, 160);
canvas.Pen.Width = 2;
canvas.Brush.Color = new PdfRgbColor(200, 230, 255);
canvas.DrawRectangle(new PdfRectangle(200, 200, 150, 80), PdfDrawMode.FillAndStroke);
pdf.Save("core-api-demo.pdf");
Этот обзор представляет лишь небольшую часть возможностей Core API. Для получения дополнительной информации смотри подробную статью о создании PDF-файлов с помощью Core API. В статье рассматриваются измерение текста, работа с цветовыми пространствами, применение обрезки, заполнение областей узорами, обработка прозрачности и другие возможности.
Создание PDF-файлов с помощью Layout API
Layout API — это высокоуровневый механизм построения документов, предоставляющий самый простой и эффективный способ создания сложных, насыщенных контентом PDF-файлов.
При использовании 'этого API вы создаёте PDF-файлы из структурных элементов, таких как страницы, контейнеры, текстовые блоки, изображения, таблицы, ссылки, верхние и нижние колонтитулы и многое другое. Вместо вычисления координат или ручного управления разметкой страниц вы описываете структуру документа, а механизм компоновки позаботится обо всём остальном.
Этот пример демонстрирует, как создать PDF-файл с помощью Layout API, используя декларативную компоновку вместо ручного позиционирования.
PdfDocumentBuilder.Create()
.Info(info => info.Title = "Docotic.Pdf Layout API demo")
.Generate("layout-api-demo.pdf", doc => doc.Pages(pages =>
{
pages.Content().Padding(100).Text(text =>
{
text.Span("The Layout API lets you compose PDFs from structural elements ");
text.Line("without manually calculating coordinates or handling pagination.")
.Style(s => s.Strong);
});
}));
Ознакомьтесь с подробным руководством, чтобы узнать, как использовать Layout API для генерации PDF-файлов в приложениях .NET.
Преобразование веб-контента с помощью API для HTML в PDF
Docotic.Pdf в паре со своим бесплатным дополнением HtmlToPdf предоставляет современный высококачественный механизм преобразования HTML в PDF на основе Chrome. Вы можете преобразовывать современный HTML и другой веб-контент, например изображения SVG или WebP, в высококачественные PDF-документы, используя API, предоставляемый дополнением.
API преобразования HTML в PDF позволяет создавать PDF-файлы из полных HTML-страниц или фрагментов HTML. Вы можете преобразовывать контент из URL-адресов, строк с HTML-кодом и локальных HTML-файлов. Последние два варианта упрощают создание PDF-файлов из HTML-шаблонов.
Пример создания PDF-файла из HTML-шаблона:
public static async Task HelloHtmlTemplate()
{
static string GetUserName()
{
// Replace with real logic: form input, API call, config, etc.
return "World";
}
string html = $@"
<h1>Hello, {GetUserName()}!</h1>
<p>This PDF was generated from an HTML template.</p>";
using var converter = await HtmlConverter.CreateAsync();
using var pdf = await converter.CreatePdfFromStringAsync(html);
pdf.Save("hello-html-template.pdf");
}
Для получения более подробной информации и примеров ознакомьтесь с нашим подробным обзором преобразования HTML в PDF.
Создание PDF-файлов из изображений
Docotic.Pdf предоставляет гибкий и удобный для разработчиков способ преобразования изображений в PDF. Библиотека поддерживает форматы изображений JPEG, BMP, GIF, PNG, TIFF и JPEG 2000 при использовании Core API.

Если допустимо по стандарту PDF, библиотека Docotic.Pdf встраивает байты изображений как есть, избегая декодирования и перекодирования пикселей для сохранения исходного сжатия. Библиотека также сохраняет цветовое пространство, когда это возможно.
Кроме того, форматы SVG и WebP поддерживаются через API преобразования HTML в PDF. Когда вам нужно разместить изображения рядом с метками или описаниями, Layout API поможет вам расположить и выровнять элементы с минимальными усилиями.
Как объединить несколько изображений в один PDF-файл
С помощью Docotic.Pdf вы можете легко преобразовать набор изображений в один PDF-файл, разместив по одному изображению на каждой странице.
Пример ниже загружает изображения из файлов и отображает каждое из них на отдельной странице. Каждое изображение масштабируется по размеру страницы и центрируется для обеспечения аккуратного и единообразного макета.
public static void ImagesOnToPdf(string[] imagePaths, string outputPath)
{
using var pdf = new PdfDocument();
foreach (string path in imagePaths)
{
var image = pdf.CreateImage(path);
var page = pdf.AddPage();
var pageWidth = page.Width;
var pageHeight = page.Height;
var scale = Math.Min(pageWidth / image.Width, pageHeight / image.Height);
var drawWidth = image.Width * scale;
var drawHeight = image.Height * scale;
var x = (pageWidth - drawWidth) / 2;
var y = (pageHeight - drawHeight) / 2;
page.Canvas.DrawImage(image, x, y, drawWidth, drawHeight, 0);
}
pdf.RemovePage(0);
pdf.Save(outputPath);
}
Обработка многостраничных изображений в форматах TIFF и GIF
Docotic.Pdf полностью поддерживает многостраничные файлы TIFF и GIF. При добавлении изображений в
PDF используйте метод OpenImage вместо CreateImage, если какое-либо из изображений может
содержать несколько страниц.
Следующий код демонстрирует, как преобразовать TIFF в PDF, и он работает как для одностраничных, так и для многостраничных изображений:
public static void OddFramesToPdf(string[] imagePaths, string outputPath)
{
using var pdf = new PdfDocument();
foreach (string path in imagePaths)
{
var imageFrames = pdf.OpenImage(path);
for (int i = 0; i < imageFrames.Count; i++)
{
if (i % 2 != 0)
continue;
var image = pdf.CreateImage(imageFrames[i]);
var page = pdf.AddPage();
page.Width = image.Width;
page.Height = image.Height;
page.Canvas.DrawImage(image, 0, 0, image.Width, image.Height, 0);
}
}
pdf.RemovePage(0);
pdf.Save(outputPath);
}
Аналогичный подход можно использовать для преобразования GIF в PDF. Он также применим к другим форматам изображений, хотя для форматов, содержащих только один кадр, он может быть более сложным, чем необходимо.
Объединение и разделение PDF-файлов
Библиотека Docotic.Pdf, являясь полнофункциональной библиотекой .NET, позволяет создавать новые PDF-файлы путем объединения, извлечения и реорганизации страниц из существующих документов.
При объединении PDF-файлов библиотека не только добавляет страницы из другого документа, но и добавляет слои, закладки, метки страниц, общий JavaScript, целевые ссылки и встроенные файлы. Более подробную информацию и рекомендации по уменьшению размера объединенных PDF-файлов см. в статье об объединении PDF-файлов.
PDF-файлы с цифровой подписью нельзя объединить без аннулирования существующих подписей. Чтобы сохранить подписи, создайте портфолио PDF-файлов вместо объединения документов. Другой вариант — сначала объединить PDF-файлы, а затем применить новую цифровую подпись к объединенному документу.
Docotic.Pdf также позволяет копировать и извлекать страницы в новые документы. Все содержимое, связанное со скопированными страницами, сохраняется, включая аннотации, элементы управления форм, структурированное содержимое, слои и другие связанные данные. Практические примеры смотри в статье о разделении PDF-файлов в .NET. В ней также объясняется, как извлекать или удалять страницы.
Работа с PDF-шаблонами
Шаблоны PDF — это предварительно разработанные PDF-файлы, которые служат базовой структурой для создания новых документов. Они полезны, когда необходимо создавать PDF-файлы с единообразным макетом, но различным содержимым. Если вы хотите отделить визуальный дизайн от данных, шаблоны PDF также являются хорошим выбором.
Шаблоны могут быть либо PDF-файлами на основе форм, либо статическими PDF-файлами без форм. Оба типа служат одной и той же цели. Кроме того, шаблоны на основе форм включают интерактивные элементы, которые, если не сведены в один слой, могут собирать информацию от пользователей.
Создание PDF-файлов из шаблонов на основе форм
Шаблоны на основе форм обычно содержат AcroForms — стандартный и широко поддерживаемый тип интерактивных PDF-форм. Для создания PDF-файла из такого шаблона обычно необходимо:
- заполнить каждое поле-заполнитель
- сгладить поля, чтобы предотвратить дальнейшее редактирование
- сохранить результат как новый PDF-файл
Вот код на C#, который находит текстовое поле-заполнитель по имени, присваивает ему значение, сглаживает поле и сохраняет результат, создавая PDF-файл из шаблона:
var nameOnCertificate = "Eva Marin";
using var pdf = new PdfDocument("certificate-template.pdf");
if (pdf.TryGetControl("name", out var field))
{
if (field is PdfTextBox nameField)
{
nameField.Text = nameOnCertificate;
nameField.Flatten();
}
}
pdf.Save($"certificate-{nameOnCertificate}.pdf");
Если ваш шаблон содержит много заполнителей, вы можете импортировать данные в формате FDF вместо
заполнения каждого поля по отдельности. Вы также можете использовать PdfDocument.FlattenControls
для одновременного сглаживания всех полей.
Создание PDF-файлов из статических шаблонов без форм
Если ваш шаблон не содержит полей формы, имена и другие данные нужно будет рисовать непосредственно на холсте страницы. Статические шаблоны PDF обычно содержат фиксированные визуальные заполнители, такие как текст, изображения или пустые области. Для создания PDF-файла из шаблона вам потребуется заполнить эти пустые области и заменить текст и изображения-заполнители программным способом.
Пустые области
Используйте Canvas API для размещения текста и изображений в пустых областях. В простых случаях, когда вам нужны лишь незначительные изменения, такие как добавление имени и фотографии, этот подход работает хорошо. Вам необходимо знать координаты и размер областей, а для правильного позиционирования текста может потребоваться сначала измерить его, а затем выровнять соответствующим образом.
Работа с текстом переменной длины или многострочным текстом более сложна, но все же выполнима.
Комбинируя DrawText, DrawString и методы измерения текста, вы можете переносить и
позиционировать строки по мере необходимости. Если ваш шаблон содержит более нескольких таких
областей, рассмотрите альтернативный подход, например, генерацию PDF-файлов с помощью Layout API.
Текст-заполнитель
Docotic.Pdf также предоставляет методы для поиска и замены текста. Однако использование поиска текста в качестве механизма шаблонирования обычно не проще, чем работа с пустыми полями-заполнителями. Перед вставкой нового контента необходимо найти точный фрагмент текста и удалить его без ошибок.
Изображения-заглушки
Статические шаблоны могут содержать изображения-заполнители для аватаров пользователей или
фотографий товаров. Чтобы найти изображение-заполнитель, перечислите набор изображений,
отображаемых на каждой странице. Для каждого отображаемого изображения можно получить его видимый
размер и положение. Чтобы заменить изображение-заполнитель, используйте PdfImage.ReplaceWith.
using var pdf = new PdfDocument("invoice-template.pdf");
var paintedImages = pdf.Pages[0].GetPaintedImages();
var placeholder = paintedImages.First();
placeholder.Image.ReplaceWith("company-logo.jpg");
pdf.Save($"invoice.pdf");
Другой вариант — нарисовать новое изображение поверх области, занятой изображением-заполнителем, но это обычно увеличивает размер результирующего PDF-файла без видимых на то оснований.
Проектирование заполнителей для легкой замены.
Для статических шаблонов полезно проектировать макет с предсказуемыми, четко определенными областями как для текста, так и для изображений. Оставьте достаточно отступов вокруг областей, которые будут содержать контент переменной длины, и используйте нейтральные изображения-заполнители, соответствующие пропорциям изображений, которые вы планируете вставить позже.
Если ваш шаблон использует текст-заполнитель, который вы планируете заменить, вы можете упростить
рабочий процесс, используя текстовые поля вместо обычного текста. Добавьте в шаблон текстовое поле
без границ, доступное только для чтения, и поместите в него текст-заполнитель. При создании
окончательного PDF-файла откройте шаблон, найдите текстовое поле по имени и присвойте ему новое
значение напрямую с помощью box.Text = "новый текст";. Затем сгладьте текстовое поле, чтобы
предотвратить дальнейшее редактирование.
Добавление интерактивных элементов
Интерактивные функции превращают статичный PDF-файл в динамичный, удобный для навигации документ, обогащенный аннотациями и разметкой. Действия и JavaScript позволяют автоматизировать процессы непосредственно в PDF-файле.
Аннотации
Аннотации — это объекты, прикрепленные к странице, которые представляют собой комментарии, выделения, вложения файлов и другие интерактивные элементы. Они видны в содержимом страницы и поддерживают процессы рецензирования и совместной работы.
Следующий пример на C# демонстрирует, как добавить текстовые аннотации, также известные как стикеры, на страницу PDF-файла с помощью Docotic.Pdf.
using var pdf = new PdfDocument("example.pdf");
var page = pdf.Pages[0];
var textAnnot = page.AddTextAnnotation(new PdfPoint(50, 100), "Reviewer comment");
textAnnot.Contents = "Please check the figures on this page.";
pdf.Save("text-annotation.pdf");
Следующий пример демонстрирует, как выделить текст и другой контент, чтобы привлечь внимание к ключевым частям документа.
using var pdf = new PdfDocument("example.pdf");
var page = pdf.Pages[0];
var color = new PdfRgbColor(255, 255, 120);
var annotationText = "Please confirm this part.";
var bounds = new PdfRectangle(50, 250, 120, 40);
page.AddHighlightAnnotation(annotationText, bounds, color);
pdf.Save("highlight-annotation.pdf");
Ссылки
Стандарты PDF определяют несколько типов ссылок в PDF-документах. Наиболее важными и широко используемыми являются внутренние ссылки и гиперссылки.
Внутренние ссылки, также называемые действиями GoTo, позволяют переходить на страницу или в
именованный пункт назначения внутри того же PDF-документа. Они полезны для перекрестных ссылок и
внутренней навигации.
Вот код на C#, который создает ссылку с первой страницы на страницу с индексом, равным 5:
using var pdf = new PdfDocument();
var page = pdf.Pages[0];
int targetPageIndex = 5;
for (int i = 0; i < targetPageIndex; i++)
pdf.AddPage();
var rect = new PdfRectangle(50, 50, 100, 40);
page.Canvas.DrawRectangle(rect);
page.AddLinkToPage(rect, targetPageIndex);
pdf.Pages[targetPageIndex].Canvas.DrawString(50, 50, "Glad to have you here.");
pdf.Save("link-to-page.pdf");
Layout API предоставляет еще один способ создания внутренних ссылок, не требующих абсолютного позиционирования.
Внешние ссылки, также называемые действиями URI, открывают веб-адрес. Вы можете добавить
гиперссылку на страницу PDF, используя метод PdfPage.AddHyperlink. В остальном подход тот же, что
и с внутренними ссылками.
Закладки
Закладки, также называемые огласлением документа, — это специальные ярлыки или ссылки, которые помогают читателям быстро переходить к определенным разделам или страницам. Когда читатель щелкает закладку, приложение просмотра переходит к указанной части документа.
Огласление отображается на панели закладок приложения просмотра и представляют собой иерархическое дерево навигации, похожее на оглавление книги, но интерактивное. Оглавление в PDF-документах может включать основные закладки и вложенные закладки, что упрощает структурирование больших документов.
Следующий пример показывает, как создавать закладки в PDF-файлах с использованием C# и Docotic.Pdf. Код создает три закладки верхнего уровня. Вторая закладка содержит одну вложенную закладку.
using var pdf = new PdfDocument();
for (int i = 0; i < 5; i++)
{
var page = i == 0 ? pdf.Pages[0] : pdf.AddPage();
var canvas = page.Canvas;
canvas.FontSize = 14;
canvas.DrawString(50, 50, $"Page {i + 1}");
}
var root = pdf.OutlineRoot;
root.AddChild("Getting Started", 1);
var child = root.AddChild("Things You Can Do", 2);
child.AddChild("Making Quick Improvements", 3);
root.AddChild("Keeping Everything Running Smoothly", 4);
pdf.PageMode = PdfPageMode.UseOutlines;
pdf.Save("bookmarks.pdf");
Закладки отличаются от оглавления, которое вы можете найти на страницах бумажной книги или PDF-файла. Оглавление на страницах можно создать программным способом, измерив заголовки и указав номера страниц в каждом разделе.
Чтобы увидеть альтернативный подход к созданию оглавления с помощью Layout API, ознакомьтесь с соответствующим кодом в нашем репозитории примеров.
Скриптинг PDF
Действия JavaScript являются одними из самых мощных интерактивных функций. JavaScript для PDF — это подмножество JavaScript, предоставляющее API для работы с документами и средствами просмотра. Он используется для проверки форм, вычислений, диалогов пользовательского интерфейса и небольших задач автоматизации.
Вы можете прикреплять скрипты к аннотациям, закладкам, элементам управления формами или действиям при открытии. С помощью Docotic.Pdf вы можете встраивать код JavaScript в PDF-файл. Код может проверять введенные в форму данные, вычислять значения, показывать или скрывать поля, а также выполнять действия в средствах просмотра.
Коллекция общих скриптов JavaScript содержит скрипты, хранящиеся на уровне документа. Эти скрипты могут быть повторно использованы в нескольких действиях. Другими словами, общие скрипты полезны для вспомогательных функций и общей логики. Они помогают уменьшить дублирование и упростить обслуживание.
Приведенный ниже код определяет общий скрипт, который отображает предупреждающее сообщение в средстве просмотра PDF. Код показывает, как запустить этот скрипт, связав его с кликом на кнопке.
using var pdf = new PdfDocument();
pdf.SharedScripts.Add(
pdf.CreateJavaScriptAction("function messageBox(message) { app.alert(message,3); }")
);
var button = pdf.Pages[0].AddButton(50, 50, 100, 40);
button.Text = "Click me";
button.OnMouseUp = pdf.CreateJavaScriptAction("messageBox('Hello, dear!');");
pdf.Save("shared-javascript.pdf");
В примере приведен простой скрипт, но вы можете создавать действия JavaScript любой сложности. Справочник по JavaScript API от Adobe содержит множество методов. Имейте в виду, что программы просмотра, не от Adobe, обычно поддерживают лишь часть API.
Действия при открытии
Действие открытия — это действие, которое выполняет средство просмотра PDF-файлов при открытии документа. Типичные примеры использования включают открытие на определенной странице, запуск процедуры инициализации на JavaScript или настройку параметров средства просмотра. Вы можете использовать действия любого типа в качестве действия открытия.
В следующем примере показано, как создать действие открытия типа GoTo. Код добавляет текст на
вторую страницу и устанавливает действие открытия, которое заставляет средство просмотра
автоматически переходить на эту страницу при открытии PDF-файла.
using var pdf = new PdfDocument();
var canvas = pdf.AddPage().Canvas;
canvas.FontSize = 14;
var message =
"If you see this immediately after opening the file, " +
"your PDF viewer supports open actions.";
var options = new PdfTextDrawingOptions(new PdfRectangle(100, 100, 100, 150));
canvas.DrawText(message, options);
pdf.OnOpenDocument = pdf.CreateGoToPageAction(1, 0);
pdf.Save("open-action.pdf");
Обратите внимание, что не все программы просмотра выполняют действия открытия типа JavaScript. Некоторые игнорируют их или сначала запрашивают подтверждение у пользователя. Некоторые программы просмотра полностью блокируют действия открытия.
Чтобы проверить, содержит ли PDF-файл действие открытия, загрузите его в объект PdfDocument и
проверьте свойство OnOpenDocument. Если свойство имеет значение null, значит, в документе не
определено действие открытия.
Применение шифрования и цифровых подписей
Шифрование и цифровые подписи решают две взаимодополняющие задачи по обеспечению безопасности создаваемых вами PDF-файлов. Шифрование контролирует, кто может открыть документ и что он может с ним делать, а подписи подтверждают, кто создал или одобрил файл, и гарантируют, что он не был изменен.
Защита паролем позволяет устанавливать правила доступа во время создания. Вы можете назначить пароль для открытия, чтобы ограничить просмотр, и пароль владельца, чтобы определить разрешения на действия такие как печать, копирование, редактирование или заполнение форм. Шифрование с помощью сертификатов обеспечивает более надежную защиту, специфичную для получателя, и хорошо подходит для распространения конфиденциальных PDF-файлов нескольким людям без использования общего пароля. Для получения более подробной информации смотри статью о шифровании PDF-файлов с помощью паролей и сертификатов.
Цифровые подписи добавляют аутентичность и целостность во время создания. Docotic.Pdf может подписывать PDF-файлы с помощью сертификатов из файлов, хранилища Windows, аппаратных токенов, HSM или облачных служб ключей. Вы можете добавлять метки времени и данные для долгосрочной проверки, чтобы подписи оставались проверяемыми еще долго после создания документа. Поддерживается также подписание при помощи внешних средств таких как PKCS#11 и облачные KMS.
Настройка метаданных PDF
Метаданные PDF — это описательная информация, встроенная в документ, такая как заголовок, автор, тема, ключевые слова, даты создания и аналогичные поля. Они помогают программному обеспечению, поисковым системам и системам управления документами понять, о чём файл, не открывая его.
PDF-документ может содержать метаданные в двух сосуществующих системах:
- Метаданные XMP
- Словарь информации о документе (словарь
Info)

XMP — это более богатый, структурированный и стандартизированный формат для встраивания
описательных метаданных. Словарь Info прост и широко поддерживается, но имеет ограничения и он
помечен устаревшим в пользу метаданных XMP в стандарте PDF 2.0 (ISO 32000-2). Docotic.Pdf может
читать и записывать данные в обе системы и предоставляет вспомогательный метод для их
синхронизации.
Docotic.Pdf автоматически обновляет некоторые метаданные перед сохранением PDF-файла. Например, библиотека по умолчанию устанавливает значения Producer и Creator. Используйте параметры сохранения, чтобы изменить это поведение и сохранить явно заданные значения метаданных.
Метаданные XMP
Свойство PdfDocument.Metadata позволяет получать доступ к метаданным XMP в PDF-файле и изменять
их. С помощью этого свойства вы можете работать с известными схемами, такими как XMP Core, Dublin
Core и PDF schema, а также управлять собственными пользовательскими метаданными.
using var pdf = new PdfDocument();
var xmp = pdf.Metadata;
xmp.Pdf.Creator = new XmpString("Second-line authoring terminal");
xmp.Pdf.Title = new XmpString("Quarterly Report");
var creators = new XmpArray(XmpArrayType.Ordered);
creators.Values.Add(new XmpString("Second-line authoring terminal"));
creators.Values.Add(new XmpString("Assistive authoring terminal"));
xmp.DublinCore.Creators = creators;
var descriptions = new XmpArray(XmpArrayType.Alternative);
descriptions.Values.Add(new XmpLanguageAlternative("x-default", "Quarterly Report"));
descriptions.Values.Add(new XmpLanguageAlternative("fr", "Rapport trimestriel"));
descriptions.Values.Add(new XmpLanguageAlternative("de", "Quartalsbericht"));
xmp.DublinCore.Descriptions = descriptions;
var author1 = new XmpString("First Author");
author1.Qualifiers.Add("role", "main author");
var author2 = new XmpString("Second Author");
author2.Qualifiers.Add("role", "co-author");
var authors = new XmpArray(XmpArrayType.Unordered);
authors.Values.Add(author1);
authors.Values.Add(author2);
xmp.Custom.Properties.Add("authors", authors);
pdf.Save("with-xmp-metadata.pdf");
XMP поддерживает массивы, структуры и типизированные значения, что делает его подходящим для работы с расширенными метаданными. Приведенный выше код также демонстрирует, как хранить свойства, специфичные для приложения, в пользовательской схеме XMP.
Словарь информации о документе
Словарь Info в основном хранит строковые текстовые значения. Он компактен и широко
поддерживается, но имеет ограничения. Используйте словарь Info для совместимости со старыми
инструментами, а в остальных случаях отдавайте предпочтение XMP.
Синхронизация метаданных
Рекомендуется синхронизировать обе системы метаданных, чтобы избежать несоответствий, которые могут ввести в заблуждение читателей и автоматизированные инструменты.
Используйте PdfDocument.SyncMetadata для выравнивания значений XMP и Info таким образом, чтобы
соответствующие поля совпадали. Метод заполняет недостающие свойства Info из XMP и аналогично
заполняет недостающие поля XMP из Info. Установите preferXmp: true, если XMP является вашим
авторитетным источником, или false, если приоритет должен иметь словарь Info.
pdf.SyncMetadata(preferXmp: true);
Подробную информацию о том, какие свойства синхронизирует этот
метод, смотри в разделе «Примечания»
документации по SyncMetadata.
Настройка меток страниц и параметров просмотра
Вновь созданный PDF-файл может выиграть от явной нумерации страниц, точной настройки параметров просмотра и выбора макета страниц для более эффективного представления содержимого документа. Эти настройки влияют на то, как читатели впервые видят файл и перемещаются по нему.
Метки страниц
Метки страниц — это метаданные, которые указывают программам просмотра PDF-файлов, какую метку отображать для каждой страницы. Используйте их, когда видимая нумерация должна отличаться от фактических номеров страниц. Например, когда вам нужны «i, ii, iii» для вводной части и «1, 2, 3» для основного текста в вашем PDF-файле.
Этот код на C# показывает, как пометить страницы PDF-файла строчными римскими цифрами для первых трех страниц и арабской нумерацией, начиная с 1, для остальных.
using var pdf = new PdfDocument();
for (int i = 0; i < 8; i++)
pdf.AddPage();
pdf.PageLabels.AddRange(0, 2, PdfPageNumberingStyle.LowercaseRoman);
pdf.PageLabels.AddRange(3, PdfPageNumberingStyle.DecimalArabic);
pdf.Save("with-page-labels.pdf");
Настройки программы просмотра PDF-файлов
Настройки просмотра PDF-файлов — это рекомендации, встроенные в документ, которые указывают, как средство просмотра должно его отображать. Например, вы можете указать, что средство просмотра должно скрывать панели инструментов, центрировать окно или подгонять окно под размер страницы. Настройки просмотра дополняют параметры макета страницы и действия открытия.
Вот как изменить настройки просмотра PDF-файлов с помощью Docotic.Pdf:
using var pdf = new PdfDocument();
pdf.ViewerPreferences.DisplayTitle = false;
pdf.ViewerPreferences.FitWindow = true;
pdf.ViewerPreferences.HideToolBar = true;
pdf.ViewerPreferences.HideMenuBar = true;
pdf.ViewerPreferences.HideWindowUI = true;
pdf.ViewerPreferences.CenterWindow = true;
pdf.Save("with-viewer-prefs.pdf");
Обратите внимание, что в зависимости от настроек Adobe Acrobat и другие программы просмотра могут игнорировать эти параметры.
Макет страницы и режим страницы
Макет страницы определяет, как страницы будут располагаться при открытии документа: по одной странице за раз, в один столбец или в виде двухстраничных разворотов. Режим страницы определяет, какие панели пользовательского интерфейса будут видны при открытии: закладки/структура, вложения, эскизы или никакие.
Вот как указать, что созданный PDF-файл должен отображаться в виде двухстраничного разворота, начиная с левой страницы, с видимой панелью эскизов при открытии:
using var pdf = new PdfDocument();
for (int i = 0; i < 7; i++)
{
var page = i > 0 ? pdf.AddPage() : pdf.Pages[0];
page.Canvas.FontSize = 36;
page.Canvas.DrawString(100, 100, $"Page {i + 1}");
}
pdf.PageLayout = PdfPageLayout.TwoPageLeft;
pdf.PageMode = PdfPageMode.UseThumbs;
pdf.Save("with-layout-and-mode.pdf");
Сохранение PDF-файлов
Библиотека Docotic.Pdf может создавать различные PDF-файлы или потоки из одного и того же созданного или отредактированного вами документа. Эти выходные данные могут соответствовать различным версиям формата PDF, различаться по длине в байтах и требовать разного объема памяти для генерации.
Способ создания байтов PDF-файла зависит от параметров сохранения. Если вы явно не указываете
параметры сохранения, методы Save, SignAndSave и TimestampAndSave объекта PdfDocument
используют настройки по умолчанию. Эти значения по умолчанию тщательно подобраны и хорошо работают
в большинстве сценариев, но вам все равно может потребоваться их скорректировать.
Подробную информацию о доступных параметрах и их значениях по умолчанию см. в документации к классу PdfSaveOptions. В разделах ниже выделены некоторые из наиболее важных параметров и даны практические рекомендации.
Версия PDF
Docotic.Pdf по умолчанию использует потоки объектов для достижения лучшего сжатия создаваемых файлов. Как результат, по умолчанию библиотека использует формат PDF 1.5 для создаваемых файлов и потоков.
Для просмотра документов формата PDF 1.5 требуется Adobe Reader 6 (выпущенный в 2003 году) или более поздняя версия. Обычно это не проблема, если только вам не нужно поддерживать устаревшие инструменты, старые программы просмотра или встроенные устройства, которые принимают только старые версии PDF.
Вот как сохранить файл PDF с более старой версией формата:
using var pdf = new PdfDocument();
var options = new PdfSaveOptions
{
Version = PdfVersion.Pdf14,
UseObjectStreams = false,
};
pdf.Save("version-1.4.pdf", options);
Для сохранения в формате PDF 1.4 необходимо также отключить потоки объектов. Библиотека не будет использовать более старую версию, если документ содержит функции, появившиеся в более поздних версиях формата.
Уменьшение размера файла
Некоторые параметры сохранения, если установить их значение в true, приводят к тому, что
Docotic.Pdf создает файлы меньшего размера (в байтах): RemoveUnusedObjects,
OptimizeIndirectObjects, WriteWithoutFormatting и UseObjectStreams.
Вот как создать PDF-файлы без неиспользуемых объектов и лишних пробелов, с данными, плотно упакованными в потоки объектов:
using var pdf = new PdfDocument();
var options = new PdfSaveOptions
{
UseObjectStreams = true,
RemoveUnusedObjects = true,
OptimizeIndirectObjects = true,
WriteWithoutFormatting = true,
};
pdf.Save("optimized.pdf", options);
Эти параметры наиболее эффективны при полной перезаписи PDF-файла. При инкрементальном сохранении они применяются только к вновь добавленной версии и не могут очищать или оптимизировать более ранние части файла.
Инкрементальные обновления
Библиотека Docotic.Pdf может обновлять PDF-файлы инкрементально. Если параметр WriteIncrementally
имеет значение true, библиотека добавляет изменения к существующему файлу, а не перезаписывает
его. Предыдущие перекрестные ссылки и данные об объектах остаются неизменными. Добавленные данные
называются инкрементальным обновлением, и текущее обновление вместе со всеми предыдущими
обновлениями составляет новую версию файла.
Инкрементальные обновления невозможны для вновь созданных документов, поскольку нет предыдущей версии, к которой можно было бы добавить изменения. Библиотека игнорирует этот параметр для новых документов и записывает их в неинкрементальном режиме.
Когда инкрементальные обновления обязательны
При добавлении новой цифровой подписи в документ, уже содержащий подписи, обязательно нужно сохранять файл инкрементально. То же самое относится к обновлению ранее подписанного файла новыми аннотациями или данными формы. Перезапись всего файла в этих случаях приведет к аннулированию существующих подписей.
В то же время, перед применением первой цифровой подписи лучше всего выполнить неинкрементальное (полное) сохранение, чтобы подписанный базовый файл был чистым и полностью перезаписанным. Подписание документа, содержащего структурные проблемы в предыдущих версиях, может привести к неожиданным проблемам с проверкой подписи.
Инкрементальное добавление также необходимо в рабочих процессах, которые требуют сохранять историю изменений для последующего аудита, или обеспечивать хранение документов в режиме "только добавление".
Преимущества использования инкрементальных обновлений
Поэтапные обновления позволяют добавлять несколько подписей к одному и тому же файлу и допускают ограниченный набор изменений после подписи, таких как заполнение полей формы, без аннулирования существующих подписей.
Кроме того, такой подход обеспечивает более быстрое сохранение небольших изменений, поскольку записываются только измененные данные. Он также сохраняет историю изменений документа, что крайне важно для аудита и других рабочих процессов, ориентированных на соответствие требованиям.
Проблемы и подводные камни, которых следует избегать
Инкрементальные обновления не могут применять глобальное сжатие или удалять устаревшие объекты по всему файлу, поскольку они добавляют только измененные объекты. В результате они, как правило, создают файлы большего размера и менее оптимизированные, чем при полной перезаписи.
Размер файла увеличивается с каждой редакцией, даже если нет неиспользуемых объектов, поскольку все предыдущие редакции остаются встроенными в файл и продолжают занимать место.
Конфиденциальная или некорректная информация из предыдущих версий может быть восстановлена, а существующие проблемы с форматом PDF или структурные дефекты в предыдущих версиях не исправляются путем добавления новых данных.
Наконец, некоторые программы просмотра и обработки испытывают трудности с PDF-файлами, содержащими несколько редакций. Прежде чем полагаться на пошаговые обновления, убедитесь, что все пользователи ваших документов могут обрабатывать файлы с несколькими редакциями.
Тестирование создаваемых PDF
Автоматизированное тестирование PDF-файлов защищает релизы от регрессий в содержимом и макете, сравнивая сгенерированные PDF-файлы с базовыми PDF-файлами, хранящимися в вашем репозитории или хранилище артефактов. Базовые версии помогают обнаруживать случайные изменения текста, шрифтов, изображений или макета и снижают необходимость ручного контроля качества в каждой сборке.
Сочетайте структурные проверки, извлечение текста и визуальное сравнение для получения наиболее надежных результатов.
Краткое сравнение подходов
| Метод | Скорость | Чувствительность | Лучше всего подходит для |
|---|---|---|---|
| Структурное сравнение | Высокая | Высокая: обнаруживает изменения на уровне объекта | Регрессионных тестов, которые должны подтвердить структурную идентичность двух версий одного и того же документа |
| Извлечение текста | Высокая | Средняя: обычно игнорирует изменения макета | Проверки семантического содержимого и таблиц |
| Визуальное сравнение | Медленнее | Высокая: обнаруживает как изменения содержимого, так и изменения отображения/макета | Выявление визуальных регрессий |
Сравнение структуры документа
Используйте PdfDocument.DocumentsAreEqual для сравнения графов объектов PDF, версии PDF и хранилища безопасности документа (DSS), игнорируя при этом зависящие от времени свойства документа. Метод также игнорирует метаданные документа, идентификаторы концевых элементов и другие автоматически генерируемые свойства.
Этот метод идеально подходит для тестирования PDF-документов, которое должно гарантировать
отсутствие добавления или удаления неожиданных объектов. DocumentsAreEqual поддерживает
перегрузки файлов и потоков и может сравнивать зашифрованные PDF-файлы.
Полный пример, демонстрирующий эту технику, доступен в примерах Docotic.Pdf. Помимо демонстрации использования метода в обычных приложениях .NET, пример также демонстрирует использование DocumentsAreEqual в приложениях Native AOT.
Проверка PDF-файлов через извлечение текста
Извлеките текст из всего документа сразу или постранично и сравните полученные строки. Вы можете использовать параметры извлечения текста для точной настройки процесса, например, исключить прямоугольник с нижним колонтитулом. Для упрощения сравнения вы можете разбить извлеченный текст на строки или слова.
Для структурированных проверок сначала извлеките текст с указанием положения, шрифта и другой подробной информации о каждом фрагменте, слове или символе. Затем сравните каждый извлеченный элемент с соответствующим базовым элементом.
Выявление визуальных различий
Начните с преобразования страниц PDF в изображения и сравните каждое изображение с базовым. Используйте специализированные библиотеки, такие как ImageSharp.Compare или Magick.NET, для обнаружения различий в изображениях.
Предпочтительнее проводить строгое попиксельное сравнение, чтобы каждый соответствующий пиксель в обоих изображениях совпадал. Если ваши требования допускают небольшие вариации в рендеринге, вы можете скорректировать логику сравнения, чтобы допускать незначительные различия, но точное равенство пикселей обеспечивает наиболее надежные результаты.
Рассмотрите возможность использования хеширования в качестве быстрой предварительной проверки, чтобы определить, являются ли два изображения, вероятно, идентичными, без выполнения полного попиксельного сравнения. Вычислите хеш SHA-256 для каждого рендерированного изображения, и если хеши совпадают, изображения почти наверняка одинаковы. Если хеши различаются, выполните полное попиксельное сравнение.
Заключение
Docotic.Pdf предоставляет комплексный многоуровневый инструментарий для создания и обработки PDF-файлов в .NET. Разработчики могут выбирать между низкоуровневым управлением с помощью Core API, высокоуровневой генерацией документов с помощью Layout API или преобразованием HTML в PDF для рабочих процессов, уже построенных на основе веб-технологий.
Библиотека также поддерживает PDF-файлы на основе изображений, генерацию на основе шаблонов и богатый набор интерактивных функций, таких как аннотации, ссылки, закладки, действия JavaScript и действия открытия.
Для обеспечения надежности Docotic.Pdf включает методы для тестирования выходных PDF-файлов, чтобы изменения в вашем приложении не приводили к регрессиям или неожиданным изменениям.