如何仅在 itext 7 表的每一页(最终)的第一行重复列值?
How to repeat column value only on first row in each page (eventual) in itext 7 tables?
我需要实现一个看起来像图片中的 table,每个页面的 table 的第一行仅重复 1 或 2 列值,最终呈现。
我尝试使用 Footer HandleEvent
如果 page > 1
.
我在特定位置添加 canvas
这个解决方案存在一个问题:如果 table 仅在第一页呈现(在 table 之后有 3 行文本),在第二页我找到了我的文本第 1 e 2 列(ID 和姓名)。
有什么方法建议吗?
我想弄清楚 table 事件处理是否仍然存在于 itext7 中(setTableEvent` setter 不再适用于 Table itext7)?
// ...
Footer footerHandler = new Footer();
pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, footerHandler);
// ...
public virtual void HandleEvent(Event @event) {
PdfDocumentEvent docEvent = (PdfDocumentEvent)@event;
PdfDocument pdf = docEvent.GetDocument();
PdfPage page = docEvent.GetPage();
int pageNumber = pdf.GetPageNumber(page);
// ...
if (pageNumber !=1) {
// get size of rectangle from file...
Rectangle rect = new Rectangle(float.Parse(m.X_LABELNOME), float.Parse(m.Y_LABELNOME), float.Parse(m.WIDTH_LABELNOME), float.Parse(m.HEIGHT_LABELNOME));
pdfCanvas = new PdfCanvas(page);
Canvas mycanvas = new Canvas(pdfCanvas, rect);
mycanvas.SetFontSize(9f);
Paragraph mytext = new Paragraph(ID_Variable or Name Variable).SetTextAlignment(TextAlignment.CENTER);
mycanvas.Add(mytext);
mycanvas.Close();
// ...
您可以自定义 TableRenderer
并覆盖其布局逻辑,以将单元格从 table 的前一部分复制到下一部分。
这是一个如何操作的示例(请注意,此代码依赖于一些 TableRenderer
本机实现细节,因此无法保证此代码适用于 iText 7 的所有未来更新) :
private static class CustomTableRenderer extends TableRenderer {
public CustomTableRenderer(Table modelElement) {
super(modelElement);
}
@Override
public LayoutResult layout(LayoutContext layoutContext) {
LayoutResult result = super.layout(layoutContext);
if (result.getStatus() == LayoutResult.PARTIAL) {
CustomTableRenderer overflowRenderer = (CustomTableRenderer) result.getOverflowRenderer();
// Modify first two columns
for (int i = 0; i < 2; i++) {
CellRenderer previousTablePartCell = overflowRenderer.rows.get(0)[i];
overflowRenderer.rows.get(0)[i] = (CellRenderer) ((Cell) previousTablePartCell.getModelElement()).createRendererSubTree().setParent(this);
}
}
return result;
}
@Override
public IRenderer getNextRenderer() {
return new CustomTableRenderer((Table) getModelElement());
}
}
现在我们需要做的就是将这个自定义渲染器设置为我们的 table。完整代码:
Document document = new Document(pdfDocument);
Table table = new Table(3).useAllAvailableWidth();
for (int i = 0; i < 10; i++) {
table.addCell(new Paragraph("Hello " + i));
table.addCell(String.valueOf(i));
StringBuilder sb = new StringBuilder();
for (int j = 0; j < 20; j++) {
sb.append(UUID.randomUUID()).append("\n");
}
table.addCell(sb.toString());
}
table.setNextRenderer(new CustomTableRenderer(table));
document.add(table);
视觉效果:
我需要实现一个看起来像图片中的 table,每个页面的 table 的第一行仅重复 1 或 2 列值,最终呈现。
我尝试使用 Footer HandleEvent
如果 page > 1
.
这个解决方案存在一个问题:如果 table 仅在第一页呈现(在 table 之后有 3 行文本),在第二页我找到了我的文本第 1 e 2 列(ID 和姓名)。
有什么方法建议吗?
我想弄清楚 table 事件处理是否仍然存在于 itext7 中(setTableEvent` setter 不再适用于 Table itext7)?
// ...
Footer footerHandler = new Footer();
pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, footerHandler);
// ...
public virtual void HandleEvent(Event @event) {
PdfDocumentEvent docEvent = (PdfDocumentEvent)@event;
PdfDocument pdf = docEvent.GetDocument();
PdfPage page = docEvent.GetPage();
int pageNumber = pdf.GetPageNumber(page);
// ...
if (pageNumber !=1) {
// get size of rectangle from file...
Rectangle rect = new Rectangle(float.Parse(m.X_LABELNOME), float.Parse(m.Y_LABELNOME), float.Parse(m.WIDTH_LABELNOME), float.Parse(m.HEIGHT_LABELNOME));
pdfCanvas = new PdfCanvas(page);
Canvas mycanvas = new Canvas(pdfCanvas, rect);
mycanvas.SetFontSize(9f);
Paragraph mytext = new Paragraph(ID_Variable or Name Variable).SetTextAlignment(TextAlignment.CENTER);
mycanvas.Add(mytext);
mycanvas.Close();
// ...
您可以自定义 TableRenderer
并覆盖其布局逻辑,以将单元格从 table 的前一部分复制到下一部分。
这是一个如何操作的示例(请注意,此代码依赖于一些 TableRenderer
本机实现细节,因此无法保证此代码适用于 iText 7 的所有未来更新) :
private static class CustomTableRenderer extends TableRenderer {
public CustomTableRenderer(Table modelElement) {
super(modelElement);
}
@Override
public LayoutResult layout(LayoutContext layoutContext) {
LayoutResult result = super.layout(layoutContext);
if (result.getStatus() == LayoutResult.PARTIAL) {
CustomTableRenderer overflowRenderer = (CustomTableRenderer) result.getOverflowRenderer();
// Modify first two columns
for (int i = 0; i < 2; i++) {
CellRenderer previousTablePartCell = overflowRenderer.rows.get(0)[i];
overflowRenderer.rows.get(0)[i] = (CellRenderer) ((Cell) previousTablePartCell.getModelElement()).createRendererSubTree().setParent(this);
}
}
return result;
}
@Override
public IRenderer getNextRenderer() {
return new CustomTableRenderer((Table) getModelElement());
}
}
现在我们需要做的就是将这个自定义渲染器设置为我们的 table。完整代码:
Document document = new Document(pdfDocument);
Table table = new Table(3).useAllAvailableWidth();
for (int i = 0; i < 10; i++) {
table.addCell(new Paragraph("Hello " + i));
table.addCell(String.valueOf(i));
StringBuilder sb = new StringBuilder();
for (int j = 0; j < 20; j++) {
sb.append(UUID.randomUUID()).append("\n");
}
table.addCell(sb.toString());
}
table.setNextRenderer(new CustomTableRenderer(table));
document.add(table);
视觉效果: