Как предотвратить разрыв текста между страницами в PDF-файле, созданном itext7.pdfhtml? - PullRequest
0 голосов
/ 16 мая 2018

Я использую 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>";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...