【PPDF工具类】 Java操作PDF之iText超入门,html转pdf,增加水印

PDF工具类需要的pom依赖

    <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.xhtmlrenderer</groupId>
            <artifactId>flying-saucer-pdf-itext5</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
        </dependency>

  

 

工具类代码

 

package com.common.base.utils;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xhtmlrenderer.layout.SharedContext;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.util.Collections;
import java.util.List;

public class PDFUtil {

    protected static Logger logger = LoggerFactory.getLogger(PDFUtil.class);

    private static int interval = -5;
    private static final String osName = System.getProperty("os.name");

    public static void genreatePdfFromHtml(String html, String pdfPath) {
        genreatePdfFromHtml(html, "", pdfPath);
    }

    /***
     * PDF引入图片
     * imagePath 图片地址
     */
    public static void genreatePdfFromHtml(String html, String imagePath, String pdfPath) {
        genreatePdfFromHtml(html, imagePath, getFontPath(), pdfPath);
    }

    public static void genreatePdfFromHtml(String html, String imagePath, String fontPath, String pdfPath) {
        genreatePdfFromHtml(html, imagePath, Collections.singletonList(fontPath), pdfPath);
    }

    public static void genreatePdfFromHtml(String html, String imageRootPath, List<String> fontPaths, String pdfPath) {
        ITextRenderer render = new ITextRenderer();
        ITextFontResolver resolver = render.getFontResolver();
        SharedContext sharedContext = render.getSharedContext();
        setFont(resolver, fontPaths);
        render.setDocumentFromString(html);
        setBaseUrl(sharedContext, imageRootPath);
        FileOutputStream os = null;
        try {
            os = new FileOutputStream(pdfPath);
            render.layout();
            render.createPDF(os);
        } catch (DocumentException | IOException var17) {
            logger.error("create pdf file error", var17);
        } finally {
            render.finishPDF();
            if (os != null) {
                try {
                    os.close();
                } catch (IOException var16) {
                    logger.error("close output stream error", var16);
                }
            }

        }

    }


    private static void setFont(ITextFontResolver resolver, List<String> fontPaths) {
        if (!CollectionUtils.isEmpty(fontPaths)) {
            fontPaths.stream().forEach((fontPath) -> {
                try {
                    resolver.addFont(fontPath, "Identity-H", false);
                } catch (IOException | DocumentException var3) {
                    logger.error("set font error", var3);
                }

            });
        }
    }

    private static void setBaseUrl(SharedContext sharedContext, String imageRootPath) {
        if (imageRootPath != null && !"".equals(imageRootPath)) {
            String imageUrl = "";
            if (osName != null && osName.toLowerCase().contains("windows")) {
                imageUrl = "file:/" + imageRootPath;
            } else if (osName != null && osName.toLowerCase().contains("linux")) {
                imageUrl = "file:///" + imageRootPath;
            }

            sharedContext.setBaseURL(imageUrl);
        }
    }


    /**
     * @param outPutFile    输出文件
     * @param srcPdfPath    原PDF位置
     * @param waterMarkName 页脚添加水印
     * @throws DocumentException
     * @throws IOException
     */
    public static void addWatermark(File outPutFile, String srcPdfPath, String waterMarkName) {
        try {
            PdfReader reader = new PdfReader(srcPdfPath);
            PdfStamper stamper = new PdfStamper(reader, new BufferedOutputStream(new FileOutputStream(outPutFile)));
            BaseFont base = BaseFont.createFont(getFontPath(), "Identity-H", BaseFont.NOT_EMBEDDED);
            Rectangle pageRect = null;
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.3f);
            gs.setStrokeOpacity(0.4f);
            int total = reader.getNumberOfPages() + 1;

            JLabel label = new JLabel();
            FontMetrics metrics;
            int textH = 0;
            int textW = 0;
            label.setText(waterMarkName);
            metrics = label.getFontMetrics(label.getFont());
            textH = metrics.getHeight();
            textW = metrics.stringWidth(label.getText());

            PdfContentByte under;
            for (int i = 1; i < total; i++) {
                pageRect = reader.getPageSizeWithRotation(i);
                under = stamper.getOverContent(i);
                under.saveState();
                under.setGState(gs);
                under.beginText();
                under.setFontAndSize(base, 20);

                // 水印文字成30度角倾斜
                //你可以随心所欲的改你自己想要的角度
                for (int height = interval + textH; height < pageRect.getHeight();
                     height = height + textH * 4) {
                    for (int width = interval + textW; width < pageRect.getWidth() + textW;
                         width = width + textW * 3) {
                        under.showTextAligned(Element.ALIGN_LEFT
                                , waterMarkName, width - textW,
                                height - textH, 30);
                    }
                }
                // 添加水印文字
                under.endText();
            }
            stamper.close();
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    private static String getFontPath(){
        return Thread.currentThread().getContextClassLoader().getResource("").getPath() + "msyh.ttf";
    }

}

 

 

注意:  字体没有使用内嵌字体,使用的是微软的msyh.ttf,需要下载msyh.ttf放到资源文件根目录

 

posted @ 2020-12-09 15:09  火羽  阅读(432)  评论(0编辑  收藏  举报