Эта страница может содержать автоматически переведенный текст.

Преобразование HTML в PDF с помощью C# и VB.NET

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

Эта статья представляет собой подробное руководство по преобразованию HTML в PDF в .NET с использованием Docotic.Pdf вместе с его бесплатным дополнением HtmlToPdf.

Информацию о том, почему Docotic.Pdf является правильным выбором, как установить дополнение и как работает преобразование внутри, смотри на странице Обзор API для преобразования HTML в PDF.

Преобразование HTML в PDF

Простое преобразование HTML в PDF с помощью C#

Сначала установите дополнение.

Install-Package BitMiracle.Docotic.Pdf.HtmlToPdf

Используя API для преобразования HTML в PDF, код преобразования на C# может выглядеть следующим образом:

static async Task ConvertUrlToPdfAsync(string urlString, string pdfFileName)
{
    using var converter = await HtmlConverter.CreateAsync();
    using var pdf = await converter.CreatePdfAsync(new Uri(urlString));
    pdf.Save(pdfFileName);
}

Всё довольно просто. Для создания PDF-документа требуется всего два вызова.

Код создаёт экземпляр конвертера и использует его для генерации PDF-файла из HTML. Вы можете редактировать этот PDF-документ или подписать его цифровой подписью. Для простоты в примере кода документ сохраняется как есть.

Как видите, API является асинхронным и не предоставляет синхронных методов.

Использование асинхронного API в синхронном коде

В некоторых случаях вам может потребоваться вызвать API из синхронного кода. Например, если ваше консольное приложение использует более старую версию C# и у вас нет асинхронного метода Main. Не беспокойтесь, вы все равно можете использовать дополнение в своем приложении.

Следующий код показывает, как преобразовать URL в PDF в обычном синхронном методе:

Task.Run(async () =>
{
    using var converter = await HtmlConverter.CreateAsync();
    var uri = new Uri("https://bitmiracle.com/pdf-library/html-pdf/");
    using var pdf = await converter.CreatePdfAsync(uri);
    pdf.Save("output.pdf");
}).GetAwaiter().GetResult();

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

Task.Run(
    Async Function()
        Using converter = Await HtmlConverter.CreateAsync()
            Dim uri = New Uri("https://bitmiracle.com/pdf-library/html-pdf/")
            Using pdf = Await converter.CreatePdfAsync(uri)
                pdf.Save("output.pdf")
            End Using
        End Using
    End Function
).GetAwaiter().GetResult()

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

Пример кода

Мы предоставляем примеры кода для консольных приложений, приложений Windows Forms и WPF. Скачайте полные тестовые проекты из нашего репозитория GitHub:

Также имеется группа примеров преобразования HTML в PDF. Каждый пример доступен в версиях на C# и VB.NET.

Создание PDF-файла из строки или файла с HTML в C# и VB.NET

С помощью API легко преобразовать HTML-строку в PDF. Строка может содержать полный HTML-документ или только его фрагмент. Конвертер создаст для вас PDF-файл из HTML-кода.

using var converter = await HtmlConverter.CreateAsync();

var html = "<body><br><br><br><h1>Hello, World</h1></body>";
using var pdf = await converter.CreatePdfFromStringAsync(html);
pdf.Save("output.pdf");

HTML-код может содержать относительные ссылки на изображения, скрипты и CSS-файлы. Для корректного преобразования такого кода необходимо указать базовый URL-адрес для всех относительных ссылок в HTML. Вот как указать базовый URL-адрес с помощью параметров преобразования:

using var converter = await HtmlConverter.CreateAsync();

var incompleteHtml = "<img src=\"/images/team.svg\"></img>";

var options = new HtmlConversionOptions();
options.Load.BaseUri = new Uri("https://bitmiracle.com/");

using var pdf = await converter.CreatePdfFromStringAsync(incompleteHtml, options);
pdf.Save("output.pdf");

В нашем репозитории GitHub находится полный тестовый проект.

Преобразование HTML-файла практически идентично преобразованию URL-адреса. Просто используйте перегрузку CreatePdfAsync, которая принимает путь вместо URL-адреса. Базовый URL-адрес и другие параметры также поддерживаются при преобразовании HTML-файла в PDF в коде C# или VB.NET.

var sampleHtmlPath = @"C:\path\to\sample.html";
using var pdf = await converter.CreatePdfAsync(sampleHtmlPath);
pdf.Save("output.pdf");

Вы также можете преобразовать изображения SVG в PDF, используя API.

Использовать пользовательские размеры страниц, полей и масштаб

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

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

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

Смотри как настроить коэффициент масштабирования и поля при создании PDF из HTML.

using var converter = await HtmlConverter.CreateAsync();

var html = "<html><head><style>body { background-color: coral; margin-top: 100px;}</style></head>" +
"<body><h1>Did you notice the margins and the scale?</h1></body></html>";

var options = new HtmlConversionOptions();
options.Page.MarginLeft = 10;
options.Page.MarginTop = 20;
options.Page.MarginRight = 30;
options.Page.MarginBottom = 40;
options.Page.Scale = 1.5;

using var pdf = await converter.CreatePdfFromStringAsync(html, options);
pdf.Save("output.pdf");

В репозитории примеров Docotic.Pdf содержится полный проект.

API преобразования HTML в PDF позволяет добавлять повторяющиеся блоки нижнего и верхнего колонтитулов на генерируемые страницы. Конвертер создает блоки на основе HTML-шаблонов, указанных в параметрах страницы. Мы рекомендуем использовать встроенные стили и Data URI для изображений внутри шаблонов.

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

Смотри как преобразовать HTML в PDF и добавить верхний и нижний колонтитулы.

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
options.Page.HeaderTemplate = File.ReadAllText("header-template.html");
options.Page.MarginTop = 50;

options.Page.FooterTemplate = File.ReadAllText("footer-template.html");
options.Page.MarginBottom = 50;

var url = new Uri("https://www.iana.org/numbers");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

В шаблонах используется обычный HTML-код с поддержкой нескольких переменных. Эти переменные — date, title, url, pageNumber и totalPages. Как шаблоны заголовка, так и шаблоны нижнего колонтитула поддерживают один и тот же набор переменных.

Полный код тестового проекта и шаблонов находится в репозитории примеров Docotic.Pdf. В примере кода показано, как использовать переменные и URI данных в шаблонах.

Преобразование HTML в PDF с защитой паролем на C#

Для доступа к некоторым веб-страницам требуется аутентификация. При переходе по защищенному URL-адресу, требующему HTTP-аутентификации, браузер запрашивает имя пользователя и пароль.

Используя параметры преобразования, вы можете указать API предоставлять учетные данные для веб-страниц, требующих авторизации.

Этот код на C# демонстрирует, как преобразовать защищенный паролем HTML-код в PDF.

using var converter = await HtmlConverter.CreateAsync();
var url = new Uri("http://httpbin.org/basic-auth/foo/bar");

var options = new HtmlConversionOptions();
options.Authentication.SetCredentials("foo", "bar");

using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

Полный рабочий пример можно найти в репозитории примеров.

Если для корректной работы страницы необходимы определенные файлы cookie, то это легко сделать. Просто добавьте эти файлы cookie в параметры. Вот как это сделать:

var options = new HtmlConversionOptions();
options.Cookies.Add(new Cookie("sessionID", "my-session-ID"));

using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

Отложить запуск конвертации

По умолчанию преобразование начинается сразу после загрузки. Задержка преобразования HTML в PDF может быть полезна, если страница продолжает обновляться некоторое время после загрузки. Это часто происходит при работе с динамическим контентом, генерируемым JavaScript или AJAX-запросами.

Тест Acid 3 — прекрасный пример страницы, которой пойдет на пользу задержка перед преобразованием. Тест выполняет определенное количество проверок для оценки способности браузера корректно отображать сложные веб-страницы. Эти проверки занимают время. Попробуйте изменить время ожидания в следующем коде, чтобы увидеть, как это повлияет на результаты преобразования.

var options = new HtmlConversionOptions();
options.Start.SetStartAfterDelay(10 * 1000);

using var converter = await HtmlConverter.CreateAsync();
var url = new Uri("http://acid3.acidtests.org/");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

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

Полный тестовый проект можно найти в репозитории примеров Docotic.Pdf.

Выполнить JavaScript перед преобразованием

API дополнения предоставляет возможность запуска кода JavaScript перед преобразованием. Этот код может динамически генерировать или изменять HTML-контент. Например, он может переключать элементы или обеспечивать динамическую загрузку контента.

Следующий код показывает, как отложить преобразование HTML в PDF до завершения работы JavaScript.

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
var js = @"document.body.style.backgroundColor = 'green';";
options.Start.SetStartAfterScriptRun(js);

var url = new Uri("https://google.com");
using var pdf = await converter.CreatePdfAsync(url, options);
pdf.Save("output.pdf");

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

Преобразовать HTML в PDF в .NET без учета ошибок SSL

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

По умолчанию дополнение выдаст исключение, если конвертер HTML в PDF по какой-либо причине не доверяет сертификату. Обычно это происходит из-за самоподписанного, отозванного или просроченного сертификата.

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

var engineOptions = new HtmlEngineOptions
{
    IgnoreSslErrors = true
};
using var converter = await HtmlConverter.CreateAsync(engineOptions);

var url = new Uri("https://self-signed.badssl.com/");
using var pdf = await converter.CreatePdfAsync(url);
pdf.Save("output.pdf");

Полный код можно найти в репозитории примеров Docotic.Pdf.

Наложить HTML на существующий PDF

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

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

using var converter = await HtmlConverter.CreateAsync();

var options = new HtmlConversionOptions();
options.Page.SetSizeInches(4.13, 5.83);

string htmlCode =
    "<div style=\"position: absolute; top: 270px; right: 100px;\">" +
    "I would like to put this here</div>";
using var htmlPdf = await converter.CreatePdfFromStringAsync(htmlCode, options);

using var pdf = new PdfDocument("pdf-to-merge-with.pdf");
var xObj = pdf.CreateXObject(htmlPdf.Pages[0]);

pdf.Pages[0].Canvas.DrawXObject(xObj, 0, 0);
pdf.Save("output.pdf");

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

Приведённый выше код:

  • создаёт PDF-документ с прозрачной страницей из HTML-кода
  • открывает существующий PDF-файл
  • создаёт объект XObject из первой страницы преобразованного документа в существующем документе
  • рисует объект XObject поверх первой страницы PDF-файла в существующем документе

Полный тестовый проект с примером исходного PDF-файла находится в репозитории примеров Docotic.Pdf.