owl*_*ool 9 java itext page-break-inside xmlworker
我们正在使用带有XML Worker的iText 5.5.7,并且遇到了长表的问题,其中在页面末尾运行的行被分成两个到下一页(见图).
我们尝试page-break-inside:avoid;按照预防页面中断的建议使用iText,XMLWorker和iText在HTML表格中的PDF页面之间切换但没有效果.
我们试过了
<tbody>并应用分页符避免(没有效果)tr, td和应用分页符(无效)td在a中div并应用分页符(itext一旦到达页面结尾就停止处理行)我们的印象page-break-inside:avoid是受到支持但尚未看到对此的确认.是否有使用XML worker创建此效果的示例或最佳实践,或者是执行此级别操作所需的Java API?
干杯
目前正在分页的行:
.NET开发人员,但您应该能够轻松地翻译以下C#代码.
任何时候默认的XML Worker实现都不能满足您的需求,您基本上只需要查看源代码.首先,看看是否XML Worker在Tags类中支持您想要的标记.有一个很好的实现<table>支持page-break-inside:avoid样式,但它只适用于<table>级别,而不是行<tr>级别.幸运的是,覆盖Table的End()方法并没有那么多工作.
如果不支持该标记,则需要通过继承AbstractTagProcessor来滚动自己的自定义标记处理器,但不是为了这个答案.
无论如何,对代码.page-break-inside:avoid我们可以使用自定义HTML属性并充分利用两个方面,而不是通过改变样式的行为来吹走默认实现:
public class TableProcessor : Table
{
// custom HTML attribute to keep <tr> on same page if possible
public const string NO_ROW_SPLIT = "no-row-split";
public override IList<IElement> End(IWorkerContext ctx, Tag tag, IList<IElement> currentContent)
{
IList<IElement> result = base.End(ctx, tag, currentContent);
var table = (PdfPTable)result[0];
if (tag.Attributes.ContainsKey(NO_ROW_SPLIT))
{
// if not set, table **may** be forwarded to next page
table.KeepTogether = false;
// next two properties keep <tr> together if possible
table.SplitRows = true;
table.SplitLate = true;
}
return new List<IElement>() { table };
}
}
Run Code Online (Sandbox Code Playgroud)
并且生成一些测试的简单方法HTML:
public string GetHtml()
{
var html = new StringBuilder();
var repeatCount = 15;
for (int i = 0; i < repeatCount; ++i) { html.Append("<h1>h1</h1>"); }
var text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer vestibulum sollicitudin luctus. Curabitur at eros bibendum, porta risus a, luctus justo. Phasellus in libero vulputate, fermentum ante nec, mattis magna. Nunc viverra viverra sem, et pulvinar urna accumsan in. Quisque ultrices commodo mauris, et convallis magna. Duis consectetur nisi non ultrices dignissim. Aenean imperdiet consequat magna, ac ornare magna suscipit ac. Integer fermentum velit vitae porttitor vestibulum. Morbi iaculis sed massa nec ultricies. Aliquam efficitur finibus dolor, et vulputate turpis pretium vitae. In lobortis lacus diam, ut varius tellus varius sed. Integer pulvinar, massa quis feugiat pulvinar, tortor nisi bibendum libero, eu molestie est sapien quis odio. Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
// default iTextSharp.tool.xml.html.table.Table (AbstractTagProcessor)
// is at the <table>, **not <tr> level
html.Append("<table style='page-break-inside:avoid;'>");
html.AppendFormat(
@"<tr><td style='border:1px solid #000;'>DEFAULT IMPLEMENTATION</td>
<td style='border:1px solid #000;'>{0}</td></tr>",
text
);
html.Append("</table>");
// overriden implementation uses a custom HTML attribute to keep:
// <tr> together - see TableProcessor
html.AppendFormat("<table {0}>", TableProcessor.NO_ROW_SPLIT);
for (int i = 0; i < repeatCount; ++i)
{
html.AppendFormat(
@"<tr><td style='border:1px solid #000;'>{0}</td>
<td style='border:1px solid #000;'>{1}</td></tr>",
i, text
);
}
html.Append("</table>");
return html.ToString();
}
Run Code Online (Sandbox Code Playgroud)
最后是解析代码:
using (var stream = new FileStream(OUTPUT_FILE, FileMode.Create))
{
using (var document = new Document())
{
PdfWriter writer = PdfWriter.GetInstance(
document, stream
);
document.Open();
// instantiate custom tag processor and add to `HtmlPipelineContext`.
var tagProcessorFactory = Tags.GetHtmlTagProcessorFactory();
tagProcessorFactory.AddProcessor(
new TableProcessor(),
new string[] { HTML.Tag.TABLE }
);
var htmlPipelineContext = new HtmlPipelineContext(null);
htmlPipelineContext.SetTagFactory(tagProcessorFactory);
var pdfWriterPipeline = new PdfWriterPipeline(document, writer);
var htmlPipeline = new HtmlPipeline(htmlPipelineContext, pdfWriterPipeline);
var cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true);
var cssResolverPipeline = new CssResolverPipeline(
cssResolver, htmlPipeline
);
var worker = new XMLWorker(cssResolverPipeline, true);
var parser = new XMLParser(worker);
using (var stringReader = new StringReader(GetHtml()))
{
parser.Parse(stringReader);
}
}
}
Run Code Online (Sandbox Code Playgroud)
完整来源.
维护默认实现 - 首先<table>保持在一起而不是分成两页:
自定义实现在第二个中将行保持在一起<table>: