PdfUtils.java
package com.tdmconsult.ete.utils;
import com.tdmconsult.ete.configuration.MyConfigurationProperties;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import lombok.experimental.UtilityClass;
import org.openpdf.text.Element;
import org.openpdf.text.Image;
import org.openpdf.text.pdf.BaseFont;
import org.openpdf.text.pdf.PdfReader;
import org.openpdf.text.pdf.PdfStamper;
import org.springframework.core.io.ClassPathResource;
import org.xhtmlrenderer.layout.SharedContext;
import org.xhtmlrenderer.pdf.ITextRenderer;
@UtilityClass
public class PdfUtils {
public static final String STATIC_PDF_FONTS_RESOURCE_DIR = "book/fonts/";
public static final String STATIC_IMG_RESOURCE_DIR = "book/img/";
public static final String FONT_NORMAL = "LiberationSans-Regular.ttf";
public static final String FONT_BOLD = "LiberationSans-Bold.ttf";
public static final String FONT_ITALIC = "LiberationSans-Italic.ttf";
public static final String FONT_BOLDITALIC = "LiberationSans-BoldItalic.ttf";
private String getFontPath(final String fontFileName) throws IOException {
final var fontResource = new ClassPathResource(
STATIC_PDF_FONTS_RESOURCE_DIR + fontFileName,
Thread.currentThread().getContextClassLoader());
return fontResource.getURL().toString();
}
private String getImagePath() throws IOException {
final var imgResource = new ClassPathResource(
STATIC_IMG_RESOURCE_DIR,
Thread.currentThread().getContextClassLoader());
return imgResource.getURL().toString();
}
public void renderToOutputStream(
final String xhtml,
final MyConfigurationProperties.Pdf properties,
final OutputStream os) throws IOException {
final ITextRenderer renderer = new ITextRenderer();
final SharedContext sharedContext = renderer.getSharedContext();
sharedContext.setPrint(true);
sharedContext.setInteractive(false);
renderer.getFontResolver().addFont(getFontPath(FONT_NORMAL), BaseFont.IDENTITY_H, true);
renderer.getFontResolver().addFont(getFontPath(FONT_BOLD), BaseFont.IDENTITY_H, true);
renderer.getFontResolver().addFont(getFontPath(FONT_ITALIC), BaseFont.IDENTITY_H, true);
renderer.getFontResolver().addFont(getFontPath(FONT_BOLDITALIC), BaseFont.IDENTITY_H, true);
renderer.setDocumentFromString(xhtml);
renderer.layout();
renderer.createPDF(os);
}
public void renderWatermarkOnEachPage(
final InputStream is,
final MyConfigurationProperties.Pdf properties,
final OutputStream os) throws IOException {
final var baseFont = BaseFont.createFont(getFontPath(FONT_BOLD), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
try (
final var reader = new PdfReader(is);
final var stamper = new PdfStamper(reader, os)) {
for (var pageIndex = 1; pageIndex <= reader.getNumberOfPages(); pageIndex++) {
final var content = stamper.getOverContent(pageIndex);
final var pageSize = reader.getPageSize(pageIndex);
content.beginText();
content.setFontAndSize(baseFont, properties.getFontSize());
content.setRGBColorFill(255, 128, 128, 128);
final var xCenter = BigDecimal.valueOf(pageSize.getLeft())
.add(BigDecimal.valueOf(pageSize.getRight()))
.divide(BigDecimal.valueOf(2));
final var yCenter = BigDecimal.valueOf(pageSize.getTop())
.add(BigDecimal.valueOf(pageSize.getBottom()))
.divide(BigDecimal.valueOf(2));
content.showTextAligned(
Element.ALIGN_CENTER,
properties.getWatermark(),
xCenter.floatValue(),
yCenter.add(BigDecimal.valueOf(100)).floatValue(), 25);
content.endText();
}
}
}
public void renderLogoOnEachPage(
final InputStream is,
final MyConfigurationProperties.Pdf properties,
final OutputStream os) throws IOException {
final var logo = Image.getInstance(getImagePath() + properties.getLogoImageFileName());
final var scalingFactor = new BigDecimal(properties.getLogoImageScale());
logo.scaleToFit(
BigDecimal.valueOf(logo.getPlainWidth()).divide(scalingFactor, RoundingMode.CEILING).floatValue(),
BigDecimal.valueOf(logo.getPlainHeight()).divide(scalingFactor, RoundingMode.CEILING).floatValue());
try (
final var reader = new PdfReader(is);
final var stamper = new PdfStamper(reader, os)) {
for (var pageIndex = 1; pageIndex <= reader.getNumberOfPages(); pageIndex++) {
final var content = stamper.getOverContent(pageIndex);
final var pageSize = reader.getPageSize(pageIndex);
logo.setAbsolutePosition(
pageSize.getWidth() - logo.getScaledWidth() - properties.getLogoImageWidthOffset(),
pageSize.getHeight() - logo.getScaledHeight() - properties.getLogoImageHeightOffset());
content.addImage(logo);
}
}
}
}