Itext7 - 自动调整图像大小
Itext7 - Auto resize image
我使用 iText(版本 7.1.1)使用 HtmlConverter(html2pdf 版本 2.0.1)将 html 转换为 pdf:
public static ByteArrayOutputStream htmlToPDFStream(String htmlBody)
throws DocumentException, IOException {
ConverterProperties props = new ConverterProperties();
FontProvider fp = new DefaultFontProvider(true, false, false);
for (String font : FONTS) {
FontProgram fontProgram = FontProgramFactory.createFont(font);
fp.addFont(fontProgram);
}
props.setFontProvider(fp);
com.itextpdf.kernel.pdf.PdfWriter writer = new com.itextpdf.kernel.pdf.PdfWriter(outputStream);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
List<IElement> elements = HtmlConverter.convertToElements(new ByteArrayInputStream(htmlBody.getBytes(StandardCharsets.UTF_8)), props);
for (IElement element : elements) {
document.add((IBlockElement)element);
}
document.close();
return outputStream;
}
如果 HTML 字符串包含小图像(小于默认页面大小 A4),效果很好。
但如果我的图像大于默认页面宽度,结果将是 pdf 格式的裁剪图像。
如果图像大于默认的 pdf 页面大小以适合,是否有任何方法告诉 iText 自动调整大小?
布局中的图像具有自动缩放功能 属性,这应该会产生所需的行为。您需要定义一个自定义 ITagWorker
才能真正将此 属性 添加到生成的图像元素中。
您还必须定义自定义 ITagWorkerFactory
才能使用新的 ITagWorker
图像。
代码非常简单,你只需要把所有的东西仔细地联系在一起就可以了:
class CustomImageWorker extends ImgTagWorker {
public CustomImageWorker(IElementNode element, ProcessorContext context) {
super(element, context);
}
@Override
public IPropertyContainer getElementResult() {
return ((Image)super.getElementResult()).setAutoScale(true);
}
}
ITagWorkerFactory customFactory = new DefaultTagWorkerFactory() {
@Override
public ITagWorker getCustomTagWorker(IElementNode tag, ProcessorContext context) {
if (TagConstants.IMG.equals(tag.name())) {
return new CustomImageWorker(tag, context);
} else {
return null;
}
}
};
之后,只需将标签工厂设置为道具:props.setTagWorkerFactory(customFactory);
CSS 级别的另一种解决方案是根据媒体设备设置(例如设备宽度和高度)指定不同的图像宽度和高度。请参阅 @media
CSS 规则文档。
UPD 如果您没有为图像定义任何 width
或 height
CSS 属性,您可以比较它们的大小页面大小,但请记住 px 到 pt 的转换率。示例:
@Override
public IPropertyContainer getElementResult() {
Image result = ((Image)super.getElementResult());
if (!processed) {
float imageWidth = result.getImageScaledWidth();
float pageMargin = 36 * 2;
float maxWidth = PageSize.A4.getWidth() - pageMargin;
float maxHeight = PageSize.A4.getHeight() - pageMargin;
if (imageWidth * 0.75 > maxWidth) {
result.scaleToFit(maxWidth / 0.75f, maxHeight / 0.75f);
}
processed = true;
}
return result;
}
我使用 iText(版本 7.1.1)使用 HtmlConverter(html2pdf 版本 2.0.1)将 html 转换为 pdf:
public static ByteArrayOutputStream htmlToPDFStream(String htmlBody)
throws DocumentException, IOException {
ConverterProperties props = new ConverterProperties();
FontProvider fp = new DefaultFontProvider(true, false, false);
for (String font : FONTS) {
FontProgram fontProgram = FontProgramFactory.createFont(font);
fp.addFont(fontProgram);
}
props.setFontProvider(fp);
com.itextpdf.kernel.pdf.PdfWriter writer = new com.itextpdf.kernel.pdf.PdfWriter(outputStream);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
List<IElement> elements = HtmlConverter.convertToElements(new ByteArrayInputStream(htmlBody.getBytes(StandardCharsets.UTF_8)), props);
for (IElement element : elements) {
document.add((IBlockElement)element);
}
document.close();
return outputStream;
}
如果 HTML 字符串包含小图像(小于默认页面大小 A4),效果很好。 但如果我的图像大于默认页面宽度,结果将是 pdf 格式的裁剪图像。
如果图像大于默认的 pdf 页面大小以适合,是否有任何方法告诉 iText 自动调整大小?
布局中的图像具有自动缩放功能 属性,这应该会产生所需的行为。您需要定义一个自定义 ITagWorker
才能真正将此 属性 添加到生成的图像元素中。
您还必须定义自定义 ITagWorkerFactory
才能使用新的 ITagWorker
图像。
代码非常简单,你只需要把所有的东西仔细地联系在一起就可以了:
class CustomImageWorker extends ImgTagWorker {
public CustomImageWorker(IElementNode element, ProcessorContext context) {
super(element, context);
}
@Override
public IPropertyContainer getElementResult() {
return ((Image)super.getElementResult()).setAutoScale(true);
}
}
ITagWorkerFactory customFactory = new DefaultTagWorkerFactory() {
@Override
public ITagWorker getCustomTagWorker(IElementNode tag, ProcessorContext context) {
if (TagConstants.IMG.equals(tag.name())) {
return new CustomImageWorker(tag, context);
} else {
return null;
}
}
};
之后,只需将标签工厂设置为道具:props.setTagWorkerFactory(customFactory);
CSS 级别的另一种解决方案是根据媒体设备设置(例如设备宽度和高度)指定不同的图像宽度和高度。请参阅 @media
CSS 规则文档。
UPD 如果您没有为图像定义任何 width
或 height
CSS 属性,您可以比较它们的大小页面大小,但请记住 px 到 pt 的转换率。示例:
@Override
public IPropertyContainer getElementResult() {
Image result = ((Image)super.getElementResult());
if (!processed) {
float imageWidth = result.getImageScaledWidth();
float pageMargin = 36 * 2;
float maxWidth = PageSize.A4.getWidth() - pageMargin;
float maxHeight = PageSize.A4.getHeight() - pageMargin;
if (imageWidth * 0.75 > maxWidth) {
result.scaleToFit(maxWidth / 0.75f, maxHeight / 0.75f);
}
processed = true;
}
return result;
}