Как разбить страницу на HTML-контент в HTML-рендерере
У меня есть проект, где HTML-код преобразуется в PDF с помощью HTML-рендерера. HTML-код содержит одну таблицу. PDF отображается, но проблема в том, что содержимое таблицы обрезается в конце. Так есть ли решение проблемы?
PdfDocument pdf = new PdfDocument ();
var config = new PdfGenerateConfig()
{
MarginBottom = 20,
MarginLeft = 20,
MarginRight = 20,
MarginTop = 20,
};
//config.PageOrientation = PageOrientation.Landscape;
config.ManualPageSize = new PdfSharp.Drawing.XSize(1080, 828);
pdf = PdfGenerator.GeneratePdf(html, config);
byte[] fileContents = null;
using (MemoryStream stream = new MemoryStream())
{
pdf.Save(stream, true);
fileContents = stream.ToArray();
return new FileStreamResult(new MemoryStream(fileContents.ToArray()), "application/pdf");
}
3 ответа
Насколько я знаю, разрывы страниц не поддерживаются, но я немного поработал (что может работать не во всех случаях), разделив HTML на отдельные страницы с помощью класса разрывов страниц, а затем добавив каждую страницу в PDF
Смотрите пример кода ниже:
//This will only work on page break elements that are direct children of the body element.
//Each page's content must be inside the pagebreak element
private static PdfDocument SplitHtmlIntoPagedPdf(string html, string pageBreakBeforeClass, PdfGenerateConfig config, PdfDocument pdf)
{
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);
var htmlBodyNode = htmlDoc.DocumentNode.SelectSingleNode("//body");
var tempHtml = string.Empty;
foreach (var bodyNode in htmlBodyNode.ChildNodes)
{
if (bodyNode.Attributes["class"]?.Value == pageBreakBeforeClass)
{
if (!string.IsNullOrWhiteSpace(tempHtml))
{
//add any content found before the page break
AddPageToPdf(htmlDoc,tempHtml,config,ref pdf);
tempHtml = string.Empty;
}
AddPageToPdf(htmlDoc,bodyNode.OuterHtml,config,ref pdf);
}
else
{
tempHtml += bodyNode.OuterHtml;
}
}
if (!string.IsNullOrWhiteSpace(tempHtml))
{
//add any content found after the last page break
AddPageToPdf(htmlDoc, tempHtml, config, ref pdf);
}
return pdf;
}
private static void AddPageToPdf(HtmlDocument htmlDoc, string html, PdfGenerateConfig config, ref PdfDocument pdf)
{
var tempDoc = new HtmlDocument();
tempDoc.LoadHtml(htmlDoc.DocumentNode.OuterHtml);
var docNode = tempDoc.DocumentNode;
docNode.SelectSingleNode("//body").InnerHtml = html;
var nodeDoc = PdfGenerator.GeneratePdf(docNode.OuterHtml, config);
using (var tempMemoryStream = new MemoryStream())
{
nodeDoc.Save(tempMemoryStream, false);
var openedDoc = PdfReader.Open(tempMemoryStream, PdfDocumentOpenMode.Import);
foreach (PdfPage page in openedDoc.Pages)
{
pdf.AddPage(page);
}
}
}
Вызовите код следующим образом:
var pdf = new PdfDocument();
var config = new PdfGenerateConfig()
{
MarginLeft = 5,
MarginRight = 5,
PageOrientation = PageOrientation.Portrait,
PageSize = PageSize.A4
};
if (!string.IsNullOrWhiteSpace(pageBreakBeforeClass))
{
pdf = SplitHtmlIntoPagedPdf(html, pageBreakBeforeClass, config, pdf);
}
else
{
pdf = PdfGenerator.GeneratePdf(html, config);
}
Для любого html, который вы хотите иметь на своей странице, просто поместите html в div с классом "pagebreak" (или как вы хотите его называть). Если вы хотите, вы можете добавить этот класс в свой css и дать ему "page-break-before: всегда;", так что HTML будет удобен для печати.
HTMLRenderer должен иметь возможность разбить таблицу на следующую страницу.
Смотрите также:
https://github.com/ArthurHub/HTML-Renderer/pull/41
Убедитесь, что вы используете последнюю версию. Возможно, вам придется добавить эти свойства CSS.
Также посмотрите этот ответ:
/questions/7314721/html-v-pdf-razryiv-stranitsyi-s-pomoschyu-pdfsharp-i-htmlrenderer/7314723#7314723
Я только что придумал, как заставить его работать, вместо того, чтобы переносить страницу внутрь на TD, сделайте это в ТАБЛИЦЕ. Вот код:
table { page-break-inside: avoid; }
В настоящее время я использую следующие версии (на данный момент не работаю над стабильными версиями):HtmlRenderer на v1.5.1-beta1PDFsharp на v1.51.5185-beta