Я использую itext7 версии 7.1.2 и itext7.pdfhtml версии 2.0.2 для создания PDF-файла из некоторых HTML-элементов, которые не должны разбиваться на страницы (например, графики и сопровождающий их текст).
Iпытались использовать явные разрывы страниц (как было успешно использовано в нашем устаревшем решении iTextSharp (с использованием page-break-before: always
для любых элементов, содержащих элементы, которые не следует разделять)), но они не работают вообще, поэтому попытались использовать более предпочтительный page-break-inside: avoid
как стиль элемента, содержащего элементы, которые я не хотел разбивать на несколько страниц.Вот упрощенная версия кода, который выводит встроенный HTML-файл в виде PDF-файла по пути «Мои документы» ...
using iText.Html2pdf;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout;
using iText.Layout.Element;
using System;
using System.Linq;
namespace IText7Html2PdfPageBreakTester
{
internal class Program
{
private static void Main(string[] args)
{
var html = @"<html>
<head>
</head>
<body>
<div style=""font-size: 60pt"">
Some Initial Text.
</div>
<div style=""page-break-inside: avoid; font-size: 120pt"">
This text should all be on the same page.
</div>
</body>
</html>";
var pdfFilePath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Example PDF.pdf");
Console.WriteLine($"Converting example HTML to PDF and writing the PDF to: \"{pdfFilePath}\".");
using (var pdfWriter = new PdfWriter(pdfFilePath))
{
using (var pdfDocument = new PdfDocument(pdfWriter))
{
var converterProperties = new ConverterProperties();
pdfDocument.SetDefaultPageSize(PageSize.A4);
using (var document = new Document(pdfDocument))
{
//NOTE: If this line is commented then the "page-break-inside: avoid" style behaves as expected.
document.SetMargins(40, 40, 40, 40);
foreach (var element in HtmlConverter.ConvertToElements(html, converterProperties).OfType<IBlockElement>())
document.Add(element);
}
}
}
Console.WriteLine($"PDF written to: \"{pdfFilePath}\".");
}
}
}
Обратите внимание, что я смог добиться желаемого поведения, если не были заданы поляна документе;однако, это бизнес-требование, чтобы в документе были заданы поля, так как я могу одновременно установить эти поля и сохранить поведение page-break-inside: avoid
?
Я также попытался создать пользовательский ITagWorker
для интерпретациипользовательский элемент <pageBreak/>
, который я попытался использовать вместо этого в качестве обходного пути, но не смог получить там метод ProcessorContext.GetPdfDocument().AddNewPage()
для фактического добавления страницы.
Дополнение : если вы подставите html
Переменная со следующим, вы можете видеть, что ни page-break-before: always
, ни page-break-after: always
не работают должным образом, независимо от того, были ли установлены поля в документе.
var html = @"<html>
<head>
</head>
<body>
<div style=""page-break-after: always"">
Some Initial Text.
</div>
<div>
This text should be on a new page.
</div>
<div style=""page-break-before: always; font-size: 60pt"">
This text should be on a further new page.
</div>
<div style=""page-break-inside: avoid; font-size: 120pt"">
This text should all be on the same page.
</div>
</body>
</html>";