html2pdf加水印

思路

  1. 先通过freemarker模板将数据渲染出来生成html静态页面
  2. 通过itext的html2pdf组件将html页面转换成pdf
  3. 通过itext包下的ColumnText.showTextAligned(final PdfContentByte canvas, final int alignment, final Phrase phrase, final float x, final float y, final float rotation)方法添加循环水印

依赖

<dependency>
	<groupId>com.itextpdf</groupId>
	<artifactId>html2pdf</artifactId>
	<version>1.0.2</version>
</dependency>
<dependency>
	<groupId>com.lowagie</groupId>
	<artifactId>itext</artifactId>
	<version>4.2.1</version>
</dependency>
<dependency>
	<groupId>com.itextpdf</groupId>
	<artifactId>font-asian</artifactId>
	<version>7.0.3</version>
</dependency>

工具类


@Slf4j
@Component
public class PdfUtil {

    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    private static ConverterProperties converterProperties;

    static {
        converterProperties = new ConverterProperties();
        // 提供解析用的字体
        FontProvider fp = new FontProvider();
        // 添加标准字体库、无中文
        fp.addStandardPdfFonts();
        try {
            // 自定义字体路径、解决中文
            fp.addDirectory(ResourceUtils.getURL(ResourceUtils.CLASSPATH_URL_PREFIX + "static/fonts").getPath());
        } catch (FileNotFoundException e) {
            log.error("加载字体库异常");
        }
        converterProperties.setFontProvider(fp);
    }

    /**
     * freemarker渲染html
     */
    public String renderTrainDutyReport(Map<String, Object> data) {
        try (Writer out = new StringWriter()) {
            // 获取模板,并设置编码方式
            Template template = freeMarkerConfigurer.getConfiguration().getTemplate("train_duty.ftl");
            // 合并数据模型与模板
            //将合并后的数据和模板写入到流中,这里使用的字符流
            template.process(data, out);
            out.flush();
            return out.toString();
        } catch (Exception e) {
            log.error("加载freemarker模板失败");
            throw new ServiceException("加载freemarker模板失败");
        }
    }

    /**
     * html2pdf
     *
     * @param html html字符串
     * @return byte[]
     * @throws IOException IOException
     */
    public byte[] convert(String html) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        HtmlConverter.convertToPdf(html, outputStream, converterProperties);
        byte[] result = outputStream.toByteArray();
        outputStream.close();
        return result;
    }


    /**
     * 循环增加水印
     * @param source 源文件
     * @param text 水印文字
     * @return 加过水印的文件字节数组
     * @throws Exception 异常
     */
    public byte[] addWaterMark(byte[] source, String text) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        Font watermarkFont = FontFactory
                .getFont(ResourceUtils.getURL(
                        ResourceUtils.CLASSPATH_URL_PREFIX + "static/fonts").getPath()+"/simhei.ttf",
                BaseFont.IDENTITY_H, BaseFont.SUPERSCRIPT_SIZE,
                Font.BOLD, new GrayColor(0.9f));
        PdfReader reader = new PdfReader(source);
        PdfStamper stamp = new PdfStamper(reader, outputStream);
        PdfContentByte under;
        int pageSize = reader.getNumberOfPages();// 原pdf文件的总页数
        for (int i = 1; i <= pageSize; i++) {
            under = stamp.getUnderContent(i);// 水印在之前文本下
            for (int m = 0; m < 5; m++) {
                for (int n = 0; n < 5; n++) {
                    ColumnText.showTextAligned(under, Element.ALIGN_CENTER, new Phrase(text,watermarkFont),
                            (50.5f + m * 150), (40.0f + n * 150),45);
                }
            }
        }
        stamp.close();// 关闭
        reader.close();
        byte[] bytes = outputStream.toByteArray();
        // TODO
//        Path path = Paths.get("D:\\1111.pdf");
//        Files.write(path, bytes);
        outputStream.close();
        return bytes;
    }
}

猜你喜欢

转载自www.cnblogs.com/yxb-blog/p/12675702.html