iText使用ColumnDocumentRenderer双栏布局时如何实现两栏底部对齐
问题描述
我正在使用ColumnDocumentRenderer绘制双栏排版的PDF内容。
相关实现代码如下:
public void ManipulatePdf(string dest) { PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest)); Document doc = new Document(pdfDoc, PageSize.A4); doc.SetMargins(55f, 55f, 45f, 55f); var interval = 20f; var columnWidth = (doc.GetPdfDocument().GetDefaultPageSize().GetWidth() - 110 - interval) / 2; var pageHeight = doc.GetPdfDocument().GetDefaultPageSize().GetHeight() - 110; var baseText = "We have seen too many reports, too many words, too many good intentions, too many families torn apart, and too many excruciatingly painful deaths to see yet more delays in taking collective action."; var pTitle = new Paragraph(baseText); pTitle.SetFontSize(20); pTitle.SetTextAlignment(iText.Layout.Properties.TextAlignment.JUSTIFIED); doc.Add(pTitle); var currentYLine = doc.GetRenderer().GetCurrentArea().GetBBox().GetTop(); Rectangle[] columns = { new Rectangle(55, 55, columnWidth, currentYLine - 55), new Rectangle(55 + columnWidth + interval, 55, columnWidth, currentYLine - 55) }; doc.SetRenderer(new ColumnDocumentRenderer(doc, columns)); for (int i = 1; i <= 12; i++) { var text = baseText; for (int j = 1; j <= i; j++) { text += " Additional Text. "; } var p = new Paragraph(text); p.SetTextAlignment(iText.Layout.Properties.TextAlignment.JUSTIFIED); doc.Add(p); if (i == 6) { var tp = new Paragraph("Introduction"); tp.SetFontSize(20); tp.SetMarginTop(50); tp.SetTextAlignment(iText.Layout.Properties.TextAlignment.JUSTIFIED); doc.Add(tp); } } doc.Close(); }
上述代码生成的PDF效果如下图所示:
同一页的两栏内容底部未齐平,需要调整实现两栏底部处于同一水平线的对齐效果。
解决方案
iText 7自带的ColumnDocumentRenderer默认没有栏尾平衡逻辑,内容按顺序填充,第一栏填满后才会填充第二栏,自然会出现同页两栏底部不对齐的问题。可通过以下两种方式实现对齐:
- 自定义支持栏尾平衡的Renderer(通用场景推荐)
核心是重写ColumnDocumentRenderer的页面刷新逻辑,在单页内容正式输出前自动校准两栏高度:- 重写
Flush()方法,在页面写出前先获取当前页两个栏位已渲染内容的实际底部Y坐标 - 取更靠近页脚的坐标值作为对齐基准,也就是内容更长的栏位的底部位置
- 计算短栏剩余的垂直空白高度,将空白均匀分配到短栏内的段落、标题块的下边距中,排版要求更高的场景也可以分配到行间距上,注意避开图片、表格这类固定高度的不可拉伸元素
- 重新触发短栏的布局计算,确认两栏底部坐标一致后,再执行默认的页面刷新输出逻辑
- 重写
- 手动校准(固定内容简单场景)
如果文档内容固定、不需要动态适配不同长度文本,可以在内容填充完成后,直接获取两栏内容的实际高度差,给短栏最后一个内容块设置对应数值的下边距,将最后一行内容推到和另一栏底部齐平的位置即可。
注意:多页双栏文档需要逐页执行高度校准,不要跨页分配垂直间距,否则会出现排版错位。
内容的提问来源于stack exchange,提问作者Steven Li
相关产品推荐
相关产品推荐

