我使用iText7使用pdfhtml的converttopdf()
方法将HTML转换为PDF。我想为我的PDF文档中的几个特定页面更改页面方向。这些页面的内容是动态的,我们无法猜测有多少页面应该处于横向(即动态表的内容可能需要一个以上的页面)
当前情况:我创建了一个自定义工作者(实现了ITagWorker),该工作者在标签
后面对页面进行景观化
public byte[] generatePDF(String html) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfWriter pdfWriter = new PdfWriter(byteArrayOutputStream);
PdfDocument pdfDocument = new PdfDocument(pdfWriter);
try {
ConverterProperties properties = new ConverterProperties();
properties.setTagWorkerFactory(
new DefaultTagWorkerFactory() {
@Override
public ITagWorker getCustomTagWorker(
IElementNode tag, ProcessorContext context) {
if ("landscape".equalsIgnoreCase(tag.name())) {
return new LandscapeDivTagWorker();
}
return null;
}
} );
MediaDeviceDescription mediaDeviceDescription = new MediaDeviceDescription(MediaType.PRINT);
properties.setMediaDeviceDescription(mediaDeviceDescription);
HtmlConverter.convertToPdf(html, pdfDocument, properties);
} catch (IOException e) {
e.printStackTrace();
}
pdfDocument.close();
return byteArrayOutputStream.toByteArray();
}
自定义工作者:
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>
<p>Display in portrait</p>
<div class="landscape">
<p>display in landscape</p>
…
<table>
..
</table>
</div>
ps:我遵循这个提示,通过使用自定义的CssApplierFactory来更改PDF(由html创建)中的某些页面的页面方向,但结果是相同的=>只是使用landscape类的第一个页面在landscape中,而表的其他内容在landscape中
做起来其实相当棘手,但整个机制还是足够灵活的,能够容纳这种需求。
我们将致力于支持以下语法:
<p>Display in portrait</p>
<landscape>
<div>
<p>display in landscape</p>
<p>content</p>
.....
<p>content</p>
</div>
</landscape>
<p> After portrait </p>
首先,我们需要将HTML内容转换为元素,然后将这些元素添加到文档中,而不是直接的HTML->PDF转换。这是必要的,因为在HTML的情况下,CSS规范规定了一个单独的页面大小处理机制,它不够灵活,无法满足您的需求,因此我们将使用本机iText布局机制。
其思想是,除了通过向areabreak
传递参数来自定义新页面大小之外,我们还将更改pdfdocument
的默认页面大小,以便使用该自定义新页面大小创建所有后续页面。为此,我们需要一直通过pdfdocument
。高级代码如下所示:
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFilePath));
ConverterProperties properties = new ConverterProperties();
properties.setTagWorkerFactory(new CustomTagWorkerFactory(pdfDocument));
Document document = new Document(pdfDocument);
List<IElement> elements = HtmlConverter.convertToElements(new FileInputStream(inputHtmlPath), properties);
for (IElement element : elements) {
if (element instanceof IBlockElement) {
document.add((IBlockElement) element);
}
}
pdfDocument.close();
自定义标记工作者工厂也几乎没有变化--它只是将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;
}
}
grandapedivtagworker
的思想是创建一个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);
}
}
因此,您将得到与屏幕截图中类似的页面设置:
为了将html转换为pdf,我使用了IText7的API convertToDocument,传递参数模板的ByteArrayInputStream、PDFDocument和ConvertProperties。 相关代码段: “PDF间接对象属于其他PDF文档。请将对象复制到当前PDF文档。” 转换属性的创建 在每次调用convertToDocument API之前创建对象 我是不是漏掉了什么?
本文向大家介绍如何使用wkhtml2pdf将html页面转换为pdf,包括了如何使用wkhtml2pdf将html页面转换为pdf的使用技巧和注意事项,需要的朋友参考一下 本文将指导您安装可以将HTML页面或HTML输出转换为PDF格式的工具。如果我们需要将Pdf发送给一组客户或客户,以及发送报告而不是HTML(您可以通过PDF格式通过电子邮件发送)的报告,则此功能还将有助于生成Pdf的代码。为您
给定一个包含纵向页面的现有 PDF 文件,我该如何以编程方式(使用 .NET)处理该文件,以便在横向页面上生成具有相同内容的新文件。 新页面应该充分利用可用的横向宽度。页面数量可能会增加,因为现有的纵向页面可能不适合一个横向页面。 背景故事:我们使用Google Sheets REST API来生成pdf文档。如果有很多列,文档可能会很宽。不幸的是,Google Drive REST API总是以
我有一个从LibreOffice Writer导出的PDF文件。这里有一个例子。一些页面具有纵向,其他页面具有横向。我正在使用Linux,当我在evice或Foxit Reader中查看文件时,它会正确显示,即所有文本行都是水平的。它也可以在我的打印机上用A4纸正确打印:横向页面逆时针旋转90度,使文本行垂直。 问题是:文档将在另一台设备(出版商中)上打印,我被告知所有页面都必须具有纵向方向。我不
我想更改PDF文档中特定几页的页面方向。PDF文档是使用html2pdf在html模板外创建的。它是这样的:如果页面的内容(通常是一个表格)太宽而不能以纵向显示,则以横向显示页面。 按照[如何将页面旋转为横向,页面内容应该为纵向iTextpdf][1]中的提示 [1]:如何将页面旋转成横向,页面内容应该在纵向iTextpdf中我已经创建了我的自定义标签和TagWorker。 } 问题是:首先,这没
` 在此输入代码