Java 在itext 7中将html转换为pdf时,如何仅为某些页面获得横向方向?
我使用pdfHTML的Java 在itext 7中将html转换为pdf时,如何仅为某些页面获得横向方向?,java,itext,landscape,itext7,html2pdf,Java,Itext,Landscape,Itext7,Html2pdf,我使用pdfHTML的convertToPDF()方法,使用iText7将HTML转换为PDF。我想更改PDF文档中几个特定页面的页面方向。这些页面的内容是动态的,我们无法猜测横向中应该有多少页面(即,动态表的内容可以占用多个页面) 当前情况:我创建了一个自定义工作程序(实现ITagWorker),该工作程序对标签 自定义工作人员: public class LandscapeDivTagWorker implements ITagWorker { @Override publ
convertToPDF()
方法,使用iText7将HTML转换为PDF。我想更改PDF文档中几个特定页面的页面方向。这些页面的内容是动态的,我们无法猜测横向中应该有多少页面(即,动态表的内容可以占用多个页面)
当前情况:我创建了一个自定义工作程序(实现ITagWorker),该工作程序对标签
自定义工作人员:
public class LandscapeDivTagWorker implements ITagWorker {
@Override
public void processEnd(IElementNode element, ProcessorContext context) {
}
@Override
public boolean processContent(String content, ProcessorContext context) {
return false;
}
@Override
public boolean processTagChild(ITagWorker childTagWorker, ProcessorContext context) {
return false;
}
@Override
public IPropertyContainer getElementResult() {
return new AreaBreak(new PageSize(PageSize.A4).rotate());
}
}
有没有一种方法可以定义应该在横向视图中显示的所有内容
比如:
<p>Display in portrait</p>
<landscape>
<div>
<p>display in landscape</p>
…
<table>
..
</table>
</div>
</landscape>
以纵向显示
景观展示
…
..
或者使用CSS类:
<p>Display in portrait</p>
<div class="landscape">
<p>display in landscape</p>
…
<table>
..
</table>
</div>
以纵向显示
景观展示
…
..
结果=>1页纵向,另一页横向(所有div内容应为横向)
PS:我遵循这个提示,使用了一个定制的CssApplierFactory,但结果是一样的=>只不过使用横向类的第一个页面是横向的,而表格的其他内容是纵向的做这件事实际上相当棘手,但整个机制仍有足够的灵活性来满足这一要求 我们将致力于支持以下语法:
<p>Display in portrait</p>
<landscape>
<div>
<p>display in landscape</p>
<p>content</p>
.....
<p>content</p>
</div>
</landscape>
<p> After portrait </p>
自定义标记工作程序工厂也几乎没有变化-它只是将PdfDocument
传递给标记工作程序:
private static class CustomTagWorkerFactory extends DefaultTagWorkerFactory {
PdfDocument pdfDocument;
public CustomTagWorkerFactory(PdfDocument pdfDocument) {
this.pdfDocument = pdfDocument;
}
@Override
public ITagWorker getCustomTagWorker(IElementNode tag, ProcessorContext context) {
if ("landscape".equalsIgnoreCase(tag.name())) {
return new LandscapeDivTagWorker(tag, context, pdfDocument);
}
return null;
}
}
LandscapeDivTagWorker
的思想是创建一个Div
包装器,将
标记的内部内容放在那里,但也用AreaBreak
元素将其包围-前一个将强制使用横向方向的新分页符,并更改整个文档的默认页面大小,同时接下来的一个将恢复所有内容-强制拆分为纵向页面大小,并将默认页面大小设置为纵向。请注意,我们还使用setNextRenderer
为AreaBreak
设置一个自定义呈现程序,以实际设置该中断时的默认页面大小:
private static class LandscapeDivTagWorker extends DivTagWorker {
private PdfDocument pdfDocument;
public LandscapeDivTagWorker(IElementNode element, ProcessorContext context, PdfDocument pdfDocument) {
super(element, context);
this.pdfDocument = pdfDocument;
}
@Override
public IPropertyContainer getElementResult() {
IPropertyContainer baseElementResult = super.getElementResult();
if (baseElementResult instanceof Div) {
Div div = new Div();
AreaBreak landscapeAreaBreak = new AreaBreak(new PageSize(PageSize.A4).rotate());
landscapeAreaBreak.setNextRenderer(new DefaultPageSizeChangingAreaBreakRenderer(landscapeAreaBreak, pdfDocument));
div.add(landscapeAreaBreak);
div.add((IBlockElement) baseElementResult);
AreaBreak portraitAreaBreak = new AreaBreak(new PageSize(PageSize.A4));
portraitAreaBreak.setNextRenderer(new DefaultPageSizeChangingAreaBreakRenderer(portraitAreaBreak, pdfDocument));
div.add(portraitAreaBreak);
baseElementResult = div;
}
return baseElementResult;
}
}
自定义区域分隔符渲染器的实现非常简单-我们仅将默认页面大小设置为PdfDocument
-其余部分在默认实现下完成,我们从以下扩展:
private static class DefaultPageSizeChangingAreaBreakRenderer extends AreaBreakRenderer {
private PdfDocument pdfDocument;
private AreaBreak areaBreak;
public DefaultPageSizeChangingAreaBreakRenderer(AreaBreak areaBreak, PdfDocument pdfDocument) {
super(areaBreak);
this.pdfDocument = pdfDocument;
this.areaBreak = areaBreak;
}
@Override
public LayoutResult layout(LayoutContext layoutContext) {
pdfDocument.setDefaultPageSize(areaBreak.getPageSize());
return super.layout(layoutContext);
}
}
因此,您将获得与屏幕截图上类似的页面设置:
非常感谢您的回复,它工作得很好:)但是,当我尝试转换包含另一个带有横向标记的模板时(如
),我在将元素添加到文档中时遇到了一个循环(包含横向标记的元素有问题)调试后,我在第二个for循环的RootRenderer类的addChild方法中找到了该循环。你知道吗?我通过删除一个CSS类修复了这个问题,该类包含以下样式分页符:avoid代码>
private static class LandscapeDivTagWorker extends DivTagWorker {
private PdfDocument pdfDocument;
public LandscapeDivTagWorker(IElementNode element, ProcessorContext context, PdfDocument pdfDocument) {
super(element, context);
this.pdfDocument = pdfDocument;
}
@Override
public IPropertyContainer getElementResult() {
IPropertyContainer baseElementResult = super.getElementResult();
if (baseElementResult instanceof Div) {
Div div = new Div();
AreaBreak landscapeAreaBreak = new AreaBreak(new PageSize(PageSize.A4).rotate());
landscapeAreaBreak.setNextRenderer(new DefaultPageSizeChangingAreaBreakRenderer(landscapeAreaBreak, pdfDocument));
div.add(landscapeAreaBreak);
div.add((IBlockElement) baseElementResult);
AreaBreak portraitAreaBreak = new AreaBreak(new PageSize(PageSize.A4));
portraitAreaBreak.setNextRenderer(new DefaultPageSizeChangingAreaBreakRenderer(portraitAreaBreak, pdfDocument));
div.add(portraitAreaBreak);
baseElementResult = div;
}
return baseElementResult;
}
}
private static class DefaultPageSizeChangingAreaBreakRenderer extends AreaBreakRenderer {
private PdfDocument pdfDocument;
private AreaBreak areaBreak;
public DefaultPageSizeChangingAreaBreakRenderer(AreaBreak areaBreak, PdfDocument pdfDocument) {
super(areaBreak);
this.pdfDocument = pdfDocument;
this.areaBreak = areaBreak;
}
@Override
public LayoutResult layout(LayoutContext layoutContext) {
pdfDocument.setDefaultPageSize(areaBreak.getPageSize());
return super.layout(layoutContext);
}
}