java使用wkhtmltopdf将html页面生成pdf并且加水印

wkhtmltopdf 专栏收录该内容
2 篇文章 0 订阅
package com.json.manager.controller.util;

import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.*;
import org.anyline.net.HttpResult;
import org.anyline.net.HttpUtil;
import org.apache.commons.lang3.StringUtils;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;


public class HtmlToPdf {
    //wkhtmltopdf在系统中的路径
    //private static final String toPdfTool = "F://wkhtml//wkhtmltopdf//bin//wkhtmltopdf.exe";

    /**
     * html转pdf
     * toPdfTool:D\:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf
     *
     * @param toPdfTool 应用软件安装路径
     * @param srcPath   html路径,可以是硬盘上的路径,也可以是网络路径htmlPath + "/js/mg/typical/caseinfo/caseM?id=" + ID
     * @param destPath  pdf保存路径src/main/resources/templates/
     * @return 转换成功返回true
     */

    public static boolean convert(String toPdfTool, String srcPath, String destPath) {

        File file = new File(destPath);
        File parent = file.getParentFile();
        //如果pdf保存路径不存在,则创建路径
        if (!parent.exists()) {
            parent.mkdirs();
        }
        StringBuilder cmd = new StringBuilder();
        cmd.append(toPdfTool);
        cmd.append(" ");
        // cmd.append("  --header-line");//页眉下面的线
        // cmd.append("  --header-center 这里是页眉这里是页眉这里是页眉这里是页眉 ");//页眉中间内容
//        cmd.append(" --viewport-size 1280x1024  ");
        cmd.append(" --page-size A4 ");
        //cmd.append("  --margin-top 30mm ");//设置页面上边距 (default 10mm)
        cmd.append(" --header-spacing 5 ");//    (设置页眉和内容的距离,默认0)
        //       cmd.append(" --disable-smart-shrinking ");
        cmd.append(srcPath);
        cmd.append(" ");
        cmd.append(destPath);

        boolean result = true;
        Process proc = null;
        HtmlToPdfInterceptor error = null;
        HtmlToPdfInterceptor output = null;
        try {
            proc = Runtime.getRuntime().exec(cmd.toString());
            error = new HtmlToPdfInterceptor(proc.getErrorStream());
            output = new HtmlToPdfInterceptor(proc.getInputStream());
            error.start();
            output.start();
            proc.waitFor();
        } catch (Exception e) {
            result = false;
            e.printStackTrace();
        } finally {
            proc.destroy();
        }

        return result;
    }

    /**
     * 生成水印,加密在这里实现
     *
     * @param sourceFilePath    源文件路径
     * @param fileWaterMarkPath 水印生成文件路径
     * @param waterMarkName     水印文字
     * @throws Exception
     */
    public static void setWaterMarkForPDF(String sourceFilePath, String fileWaterMarkPath, String waterMarkName) throws Exception {
        //String waterPath = Class.class.getClass().getResource("/1.png").getPath();
        //String waterPath = "src/main/resources/templates/3607.png";
        PdfReader reader = new PdfReader(sourceFilePath);
        PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(fileWaterMarkPath));

        int total = reader.getNumberOfPages() + 1;
        // 加入水印
        PdfContentByte under = null;
        // 设置水印透明度
        PdfGState gs = new PdfGState();
        // 设置填充字体不透明度为0.2f
        gs.setFillOpacity(0.1f);
//        Image img = Image.getInstance(waterPath);
//        img.setAbsolutePosition(30, 100);//坐标
//        img.setRotation(-20);//旋转 弧度
//        img.setRotationDegrees(-35);//旋转 角度
//        img.scaleAbsolute(200, 100);//自定义大小
//        img.scalePercent(100);//依照比例缩放
        // 设置水印字体参数及大小
        BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
        if (StringUtils.isBlank(waterMarkName)) {
            waterMarkName = "Tech Mahindra";
        }

        int j = waterMarkName.length();
        char c = 0;
        int rise = 0;
        for (int i = 1; i < total; i++)  // 每一页都加水印
        {
            rise = 500;
            under = stamp.getUnderContent(i);
            // 添加图片
            //under.addImage(img);
            under.beginText();
            under.setColorFill(Color.BLACK);
            under.setFontAndSize(bf, 60);
            under.setGState(gs);
            // 设置水印文字字体倾斜 开始
            if (j >= 15) {
                under.setTextMatrix(200, 120);
                for (int k = 0; k < j; k++) {
                    under.setTextRise(rise);
                    c = waterMarkName.charAt(k);
                    under.showText(c + "");
                    rise -= 20;
                }
            } else {
                under.setTextMatrix(100, 200);
                for (int k = 0; k < j; k++) {
                    under.setTextRise(rise);
                    c = waterMarkName.charAt(k);
                    under.showText(c + "");
                    rise -= 27;
                }
            }
            // 字体设置结束
            under.endText();
        }

        stamp.close();
        reader.close();
    }

/**
 * 生成水印,加密在这里实现,图片水印
 *
 * @param sourceFilePath    源文件路径
 * @param fileWaterMarkPath 水印生成文件路径
 * @param waterMarkName     水印文字
 * @throws Exception
 */
public static void setWaterMarkForPDFIMG(String sourceFilePath, String fileWaterMarkPath, String waterMarkName) throws Exception {
    //String waterPath = Class.class.getClass().getResource("/1.png").getPath();
    String waterPath = "src/main/resources/templates/waterPath.png";//图片路径图片背景为无色,至于pdf文字上
    PdfReader reader = new PdfReader(sourceFilePath);
    PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(fileWaterMarkPath));

    int total = reader.getNumberOfPages() + 1;
    // 加入水印
    PdfContentByte under = null;
    // 设置水印透明度
    PdfGState gs = new PdfGState();
    // 设置填充字体不透明度为0.2f
    gs.setFillOpacity(0.1f);
    Image img = Image.getInstance(waterPath);

    // 设置水印字体参数及大小
    BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
    Rectangle pageSizeWithRotation = null;
    final float IMAGE_SIZE = 0.7f;//图片缩放比例,大小0
    float plainWidth = img.getPlainWidth() * IMAGE_SIZE;
    float plainHeight = img.getPlainHeight() * IMAGE_SIZE;
    // 每一页都加水印
    for (int i = 1; i < total; i++) {
        // 获取每一页的高度、宽度
        pageSizeWithRotation = reader.getPageSizeWithRotation(i);

        float pageHeight = pageSizeWithRotation.getHeight();
        float pageWidth = pageSizeWithRotation.getWidth();

        img.scaleAbsolute(plainWidth, plainHeight);//设置图片大小
        // img.setAlignment(Image.UNDERLYING); // 在字下面
        //设置水印图片的坐标。
        img.setAbsolutePosition(pageWidth - plainWidth, pageHeight - plainHeight-80);

        under = stamp.getOverContent(i); //在内容上方添加水印
        // 添加图片
        under.addImage(img);
        under.beginText();
        under.setColorFill(Color.BLACK);
        under.setFontAndSize(bf, 30);
        under.setGState(gs);
        // 设置水印文字字体倾斜 开始
        // 字体设置结束
        under.endText();
    }

    stamp.close();
    reader.close();
}

    /**
     * 铺满页面的pdf
     *
     * @param fileWaterMarkPath 输出文件的位置
     * @param input             原PDF位置
     * @param waterMarkName     添加水印描述
     * @throws DocumentException
     * @throws IOException
     */
    public static void setWatermark(String fileWaterMarkPath, String input, String waterMarkName)
            throws DocumentException, IOException {

        PdfReader reader = new PdfReader(input);
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(fileWaterMarkPath));

        // 获取总页数 +1, 下面从1开始遍历
        int total = reader.getNumberOfPages() + 1;
        // 使用classpath下面的字体库
        BaseFont base = null;
        try {
            //方法三:使用资源字体(ClassPath)    
            String os = System.getProperty("os.name");
            if (os.startsWith("Windows")) {
                base = BaseFont.createFont("src/main/resources/templates/windows/simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            } else {
                base = BaseFont.createFont("/cse/web/cse-casepo/WEB-INF/classes/templates/linux/simsun.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            }

            //base = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
            // base = BaseFont.createFont("/calibri.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        } catch (Exception e) {
            // 日志处理
            e.printStackTrace();
        }

        // 间隔
        int interval = -10;
        // 获取水印文字的高度和宽度
        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());
        System.out.println("textH: " + textH);
        System.out.println("textW: " + textW);

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

        Rectangle pageSizeWithRotation = null;
        PdfContentByte content = null;
        for (int i = 1; i < total; i++) {
            // 在内容上方加水印
            //content = stamper.getOverContent(i);
            // 在内容下方加水印
            content = stamper.getUnderContent(i);
            content.saveState();
            content.setGState(gs);

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

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

//            // 根据纸张大小多次添加铺满页面, 水印文字成30度角倾斜
//            for (int height = interval + textH; height < pageHeight; height = height + textH * 6) {
//                for (int width = interval + textW; width < pageWidth + textW; width = width + textW * 4) {
//                    content.showTextAligned(Element.ALIGN_RIGHT, waterMarkName, width - textW, height - textH, 20);
//                }
//            }

//            // 根据纸张大小多次添加, 只增加一种水印,单个水印
            content.showTextAligned(Element.ALIGN_CENTER, waterMarkName, pageWidth / 2, pageHeight / 2, 45);
            content.endText();
        }

        // 关流
        stamper.close();
        reader.close();
    }

    private HttpResult uploadFileSys(Map<String, File> files) {
        String token = "MwQeRwyD7iyfnfTnMAgle5AafSxxOXe1";
        HttpResult txt = HttpUtil.upload("http://file.qnlm.ac/up?token=" + token, files);
        return txt;
    }
}   

1.铺满页面水印

2.单个水印在liunx部署存在中文无法识别问题改为图片水印实现,图片背景为无色效果如下

3.图片水印

  • 1
    点赞
  • 2
    评论
  • 2
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论 2 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:博客之星2020 设计师:CSDN官方博客 返回首页

打赏作者

^止境^

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值