如何解决从每页 itext 7 java 的第一段中删除前导
我需要在每个页面的第一个 Paragrapg 中删除 Lead 属性(FixedLeading)?
PdfDocument pdf = new PdfDocument(new PdfWriter(DEST));
Document document = new Document(pdf);
setGridForFirstPage(pdf);
document.setMargins(0,25,25);
String line = "Hello! Welcome to iTextPdf";
Paragraph el = new Paragraph(line);
Div div = new Div();
for (int i = 0; i < 30; i++) {
Paragraph element = new Paragraph();
element.add(line + " " + i);
element.setFixedLeading(130);
div.add(element);
}
LayoutResult result = div.createRendererSubTree().setParent(document.getRenderer()).layout(new LayoutContext(new LayoutArea(0,document.getPdfDocument().getDefaultPageSize())));
LayoutResult savePageResult = null;
deleteProperties(result);
savePageResult = div.createRendererSubTree().setParent(document.getRenderer()).layout(new LayoutContext(new LayoutArea(0,document.getPdfDocument().getDefaultPageSize())));
LayoutResult nextPageResult = savePageResult.getoverfloWrenderer().layout(new LayoutContext(new LayoutArea(3,document.getPdfDocument().getDefaultPageSize())));
deleteProperties(nextPageResult);
document.add(div);
document.close();
}
private static void deleteProperties(LayoutResult childRendererListParagraph) {
List<IRenderer> childRenderers = childRendererListParagraph.getSplitRenderer().getChildRenderers();
for (int j = 0; j < childRenderers.size(); j++) {
IRenderer iRendererList = childRenderers.get(j);
if (j == 0) {
if (iRendererList != null && iRendererList.getModelElement().hasProperty(33)) {
iRendererList.getModelElement().deleteOwnProperty(33);
}
}
}
}
它只能工作两页,我尝试使用循环,但没有成功
解决方法
您的方法似乎合理:我想可以通过循环遍历所有溢出渲染器来改进它(也许,我会尝试并在某天更新答案)。
然而,有一种完全不同的方法,对我来说似乎更方便和准确:为什么不覆盖ParagraphRenderer
,这样每次对应的Paragraph
无法容纳时都重置前导一页(因此将移至下一页)。
这就是这样一个扩展类的样子:
class CustomParagraphRenderer extends ParagraphRenderer {
public CustomParagraphRenderer(Paragraph modelElement) {
super(modelElement);
}
@Override
public LayoutResult layout(LayoutContext layoutContext) {
LayoutResult result = super.layout(layoutContext);
if (result.getStatus() != LayoutResult.FULL) {
if (null != result.getOverflowRenderer()) {
result.getOverflowRenderer().setProperty(
Property.LEADING,result.getOverflowRenderer().getModelElement().getDefaultProperty(Property.LEADING));
} else {
// if overflow renderer is null,that could mean that the whole renderer will overflow
setProperty(
Property.LEADING,result.getOverflowRenderer().getModelElement().getDefaultProperty(Property.LEADING));
}
}
return result;
}
@Override
// If not overriden,the default renderer will be used for the overflown part of the corresponding paragraph
public IRenderer getNextRenderer() {
return new CustomParagraphRenderer((Paragraph) this.getModelElement());
}
}
我想强调的几点:
- 在这种情况下应该始终覆盖
getNextRenderer
,否则默认渲染器将用于溢出部分 - 最好不要像您那样更新模型元素的属性,因为如果您想重用该段落,初始属性将已经消失。相反,应该更新渲染器本身的属性(它的属性优先于模型元素的属性,即段落的属性)
这就是您可以使用这样一个类的方式。与您的代码的唯一区别是:
-
setNextRenderer
被调用,以便您的段落与自定义渲染器相关联 -
未设置第一个元素的前导
doc.setMargins(0,25,25); String line = "Hello! Welcome to iTextPdf"; Div div = new Div(); for (int i = 0; i < 30; i++) { Paragraph element = new Paragraph(); element.setNextRenderer(new CustomParagraphRenderer(element)); element.add(line + " " + i); if (0 != i) { element.setFixedLeading(130); } div.add(element); }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。