如何使用 iText7 和 pdfHtml 缩放背景图像?
How can I scale a background image using iText7 and pdfHtml?
我正在尝试升级到最新版本的 iText,但我 运行 遇到了一些问题。目前我们使用 Apache Velocity 模板,然后使用 iText 将生成的 HTML 转换为 pdf。
我们有一张大图像 (2220 x 3248) 作为背景包含在 PDF 中。我已将模板缩减为最低限度的测试。
<html>
<head>
<style type="text/css">
@page {
margin-top:57px;
margin-bottom:50px;
margin-left: 110px;
margin-right: 40px;
padding-top:160px;
padding-bottom:5px;
background-image:url('templates/background.png');
background-size:100% 100%;
background-position:top left;
}
</style>
</head>
<body>
<h1>Background Image Test</h1>
</body>
</html>
然后我使用以下代码呈现 PDF。
public void render(PdfRendererContext ctx) throws Exception {
ConverterProperties properties = new ConverterProperties();
PdfWriter writer = new PdfWriter((OutputStream) ctx.getOutput().getOutput());
PdfDocument pdf = new PdfDocument(writer);
properties.setBaseUri("path/to/files");
HtmlConverter.convertToPdf((String) ctx.getInput().getInput(), pdf, properties);
}
这会转换 PDF,我基本上得到了我想要的,但背景图像不再缩放。该图像应该是页面周围的边框,中间有一个徽标,但正如您所见,该图像比整个页面大得多。
我试过几种不同的方法来改变背景大小,但都没有成功。有什么方法可以缩放类似于我需要的背景图像吗?
很遗憾,pdfHTML 尚不支持 background-size
CSS 属性。有一个带有 post-processing 的解决方案,您可以使用它通过 iText Core 将背景图像添加到您的 PDF 文档。因此,您不会在 HTML 中定义任何背景图像,而是将它们添加到 post 处理阶段。以下是代码如何查找所描述的方法:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Converting to a memory stream to process the document in memory afterwards before flushing to disk
HtmlConverter.convertToPdf(htmlStream, baos);
PdfDocument pdfDocument = new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())),
new PdfWriter(new File("C:/path/to/out.pdf")));
ImageData imageData = ImageDataFactory.create("C:/path/to/background.png");
// Page size of the output HTML document
Rectangle pageSize = PageSize.A4;
Image image = new Image(imageData).scaleAbsolute(pageSize.getWidth(), pageSize.getHeight());
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
PdfPage page = pdfDocument.getPage(i);
// newContentStreamBefore just adds some content on the back layer, to be shown behind other content
PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDocument);
new Canvas(pdfCanvas, pdfDocument, pageSize).add(image);
}
pdfDocument.close();
我正在尝试升级到最新版本的 iText,但我 运行 遇到了一些问题。目前我们使用 Apache Velocity 模板,然后使用 iText 将生成的 HTML 转换为 pdf。
我们有一张大图像 (2220 x 3248) 作为背景包含在 PDF 中。我已将模板缩减为最低限度的测试。
<html>
<head>
<style type="text/css">
@page {
margin-top:57px;
margin-bottom:50px;
margin-left: 110px;
margin-right: 40px;
padding-top:160px;
padding-bottom:5px;
background-image:url('templates/background.png');
background-size:100% 100%;
background-position:top left;
}
</style>
</head>
<body>
<h1>Background Image Test</h1>
</body>
</html>
然后我使用以下代码呈现 PDF。
public void render(PdfRendererContext ctx) throws Exception {
ConverterProperties properties = new ConverterProperties();
PdfWriter writer = new PdfWriter((OutputStream) ctx.getOutput().getOutput());
PdfDocument pdf = new PdfDocument(writer);
properties.setBaseUri("path/to/files");
HtmlConverter.convertToPdf((String) ctx.getInput().getInput(), pdf, properties);
}
这会转换 PDF,我基本上得到了我想要的,但背景图像不再缩放。该图像应该是页面周围的边框,中间有一个徽标,但正如您所见,该图像比整个页面大得多。
我试过几种不同的方法来改变背景大小,但都没有成功。有什么方法可以缩放类似于我需要的背景图像吗?
很遗憾,pdfHTML 尚不支持 background-size
CSS 属性。有一个带有 post-processing 的解决方案,您可以使用它通过 iText Core 将背景图像添加到您的 PDF 文档。因此,您不会在 HTML 中定义任何背景图像,而是将它们添加到 post 处理阶段。以下是代码如何查找所描述的方法:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Converting to a memory stream to process the document in memory afterwards before flushing to disk
HtmlConverter.convertToPdf(htmlStream, baos);
PdfDocument pdfDocument = new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())),
new PdfWriter(new File("C:/path/to/out.pdf")));
ImageData imageData = ImageDataFactory.create("C:/path/to/background.png");
// Page size of the output HTML document
Rectangle pageSize = PageSize.A4;
Image image = new Image(imageData).scaleAbsolute(pageSize.getWidth(), pageSize.getHeight());
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
PdfPage page = pdfDocument.getPage(i);
// newContentStreamBefore just adds some content on the back layer, to be shown behind other content
PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDocument);
new Canvas(pdfCanvas, pdfDocument, pageSize).add(image);
}
pdfDocument.close();