package com.ads.common.util;


import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.util.Matrix;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

/**
 * @author: stamm
 * @Date: 2021/10/25/10:12
 */
@Slf4j
@SuppressWarnings("all")
public class PdfUtil {

    /**
     * pdfbox 水印
     *
     * @param sourcePdf 资源目录
     * @param targetPdf 目标目录
     * @param ts        水印内容
     * @param path      自定义字体模板路径
     * @throws Exception
     */
    private static void usePDFBox(String sourcePdf, String targetPdf, String ts, String path) throws Exception {
        File sourcePDF = new File(sourcePdf);
        File targetPDF = new File(targetPdf);
        PDDocument doc = PDDocument.load(sourcePDF);
        doc.setAllSecurityToBeRemoved(true);
        // 水印文字

        for (PDPage page : doc.getPages()) {
            // 透明度
            PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
            graphicsState.setNonStrokingAlphaConstant(0.2f);
            graphicsState.setAlphaSourceFlag(true);

            PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);
            cs.setGraphicsStateParameters(graphicsState);
            // CMYK颜色
            cs.setNonStrokingColor(100, 0, 40, 0);
            cs.beginText();
            // 引入外部字体
            cs.setFont(PDType0Font.load(doc, new File(path)), 30);
            //cs.setFont(PDType1Font.TIMES_ROMAN, 30);
            // 旋转的角度，用弧度表示；水平移动300；纵向移动200
            cs.setTextMatrix(Matrix.getRotateInstance(0.6, 300f, 200f));
            cs.showText(ts);
            cs.endText();

            cs.close();
        }
        doc.save(targetPDF);
    }


    /**
     * @param bos           目标输出文件的位置
     * @param input         原PDF位置
     * @param waterMarkName 页脚添加水印
     * @throws DocumentException
     * @throws IOException
     */
    public static void setWatermark(BufferedOutputStream bos, String input, String waterMarkName) {
        PdfReader reader = null;
        PdfStamper stamper = null;
        BaseFont base = null;
        try {
            reader = new PdfReader(input);
            //pdf文件加密处理
            reader.unethicalreading = true;
            stamper = new PdfStamper(reader, bos);
            // 获取总页数 +1, 下面从1开始遍历
            int total = reader.getNumberOfPages() + 1;
            // 使用classpath下面的字体库
            //base = BaseFont.createFont();
            base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            // 间隔
            int interval = -100;
            // 获取水印文字的高度和宽度
            int textH = 0, textW = 0;
            JLabel label = new JLabel();
            label.setText(waterMarkName);
            FontMetrics metrics = label.getFontMetrics(label.getFont());
            textH = metrics.getHeight();
            textW = metrics.stringWidth(label.getText());

            // 设置水印透明度
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.4f);
            gs.setStrokeOpacity(0.4f);

            Rectangle pageSizeWithRotation;
            PdfContentByte content;
            for (int i = 1; i < total; i++) {
                // 在内容上方加水印
                content = stamper.getOverContent(i);
                // 颜色 RGBA
                content.setColorFill(new BaseColor(192, 192, 192));
                // 在内容下方加水印
                content.saveState();
                content.setGState(gs);

                // 设置字体和字体大小
                content.beginText();
                content.setFontAndSize(base, 20);

                // 获取每一页的高度、宽度
                pageSizeWithRotation = reader.getPageSizeWithRotation(i);
                float pageHeight = pageSizeWithRotation.getHeight();
                float pageWidth = pageSizeWithRotation.getWidth();

                // 根据纸张大小多次添加， 水印文字成30度角倾斜
                for (int height = interval + textH; height < pageHeight; height = height + textH * 8) {
                    for (int width = interval + textW; width < pageWidth + textW; width = width + textW * 2) {
                        content.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, 30);
                    }
                }
                // 文字居中；水印文字；X坐标；Y坐标；旋转角度
                //content.showTextAligned(Element.ALIGN_CENTER, waterMarkName, 300, 200, 30);
                content.endText();
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    stamper.close();
                }
            } catch (Exception e) {
                log.info("PdfStamper 关闭异常！");
                e.printStackTrace();
            }
            if (reader != null) {
                reader.close();
            }

        }
    }


    /**
     * pdf to image
     *
     * @param sourcePdf pdf source file path
     */
    public static int toImages(String sourcePdf) {
        if (StringUtils.isEmpty(sourcePdf)) {
            log.error("pdf source file path cannot be empty!");
        }
        int numberOfPages = 0;
        byte[] pdfBytes = null;
        try {
            pdfBytes = Files.readAllBytes(Paths.get(sourcePdf));
            // 图片目录
            File imagesDirectory = new File(sourcePdf.substring(0, sourcePdf.lastIndexOf('.')));
            if (!imagesDirectory.exists()) {
                imagesDirectory.mkdirs();
            }
            PDDocument pdDocument = PDDocument.load(pdfBytes);
            PDFRenderer pdfRenderer = new PDFRenderer(pdDocument);
            // 总页数
            numberOfPages = pdDocument.getNumberOfPages();
            int pageStartIndex = 0;
            int pageEndIndex = numberOfPages - 1;
            for (int i = pageStartIndex; i <= pageEndIndex; i++) {
                BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(i, 250);
                ImageIO.write(bufferedImage, "png", new File(imagesDirectory.getPath() + File.separator + (i + 1) + ".png"));
            }
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
        return numberOfPages;
    }


    public static void main(String[] args) throws Exception {

        //usePDFBox("E:\\111.pdf","E:\\333.pdf","Z21HJQLISZPWOYXXXX");

        // 将pdf文件先加水印然后输出
        //setWatermark(new BufferedOutputStream(new FileOutputStream(new File("E:\\444.pdf"))), "E:\\111.pdf", "陆迪龙12345");
        toImages("D:\\Project\\沪上阿姨\\test_file\\能源费核算改造方案.pdf");
    }

}
