linux 下安装和使用 wkhtmltopdf工具 Html转PDF

1. uname -a 查看 linux内核版本

2. wkhtmltopdf linux 乱码解决
(1)下载字体库 (2)复制到linux系统 /usr/share/fonts 下 即可

3.
curl -O https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox-0.12.5-1.centos7.x86_64.rpm
或者
wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox-0.12.5-1.centos7.x86_64.rpm

yum install -y fontconfig libX11 libXext libXrender libjpeg libpng xorg-x11-fonts-75dpi xorg-x11-fonts-Type1

rpm -ivh wkhtmltox-0.12.5-1.centos7.x86_64.rpm

whereis wkhtmltopdf / which wkhtmltopdf

中文字体:
mkdir -p /usr/share/fonts/chinese/TrueType

上传字体 rz

测试 : wkhtmltopdf index.html index.pdf

工具类如下图:直接可用

package com.hebi.xiaohe.xyang.utils;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hebi.xiaohe.xyang.exception.XunyangException;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;

import ch.qos.logback.core.rolling.helper.RenameUtil;

/**
 * @Author: gaofeng_peng
 * @Date: 2018/7/5 13:13
 * 实现A4纸页面 并且横向显示(不设置则为纵向)
 * Document document = new Document(PageSize.A4.rotate());
 */
public class Html2PDFUtils {
   
   private static final Logger logger = LoggerFactory.getLogger(Html2PDFUtils.class);
   
   // wkhtmltopdf在系统中的路径
   private static final String softsPath = "D:\\winApp\\wkhtmltopdf\\bin\\wkhtmltopdf.exe";

   /**
    * html转pdf
    *
    * @param srcPath         html路径
    * @param pdfLocationPath pdf保存路径
    * @return 转换成功返回true
    */
   public static boolean convert(String srcPath, String pdfLocationPath, String systemOs) throws Exception {
      String toPdfTool = "";
      if (systemOs.toLowerCase().startsWith("win")) {
         toPdfTool = softsPath;// Html2PDFUtils.class.getClassLoader().getResource("wkhtmltox/bin/wkhtmltopdf.exe").getPath();
      } else {
         toPdfTool = "";
      }
      StringBuilder cmd = new StringBuilder();
      cmd.append(toPdfTool);
      cmd.append(" ");
      cmd.append("  --background");
      cmd.append(" --debug-javascript");
      cmd.append("  --header-line");// 页眉下面的线
      cmd.append(" --header-spacing 10 ");// (设置页眉和内容的距离,默认0)

      cmd.append(srcPath);
      cmd.append(" ");
      cmd.append(pdfLocationPath);

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

   public static void main(String[] args) throws Exception {
//      iTextHm2PdfTest();
//    String sourcePath = "E:\\home\\index.html";
      String sourcePath = "E:\\home\\pdf_temp.html";
      String destPath = "E:\\home\\pdf_temp-" + UUID.randomUUID().toString() + ".pdf";
      // wkhtmltopdf在系统中的路径
      String softsPath = "D:\\winApp\\wkhtmltopdf\\bin\\wkhtmltopdf.exe";

      boolean isSuccess = convert(sourcePath, destPath, System.getProperty("os.name"));
      if (isSuccess) {
         String fileWaterMarkPath = "E:\\home\\pdf_temp-" + UUID.randomUUID().toString() + ".pdf";
           setWaterMarkForPDF(destPath, fileWaterMarkPath, "徐志");
//       addWaterMark(destPath, fileWaterMarkPath, "徐志", 400, 880);
      }
   }
   
   public static void waterPicForPdf(String sourcePdfPath, String waterPdfPath, String waterPicPath) throws Exception {
      try {
         PdfReader reader = new PdfReader(sourcePdfPath);
         PdfStamper stamp = new PdfStamper(reader, new FileOutputStream(waterPdfPath));
         
         int totalPage = reader.getNumberOfPages() + 1;
         
         PdfContentByte content;
          PdfGState state = new PdfGState();
          
          for (int i = 1; i < totalPage; i++) {
             content = stamp.getOverContent(i);   // 水印在上层
            
             state.setFillOpacity(0.2f);          // 设置透明度为0.2
               content.setGState(state);
               
               content.addImage(singletonWaterMarkImage(waterPicPath, 100, 300));
               content.addImage(singletonWaterMarkImage(waterPicPath, 250, 300));
         }
          
          stamp.close();
          reader.close();
      } catch (Exception e) {
         logger.error("add water to pdf exception : {}", e);
         throw new XunyangException("add water to pdf exception " + XunyangException.getTrace(e));
      }
   }
   
    /**
     * 对一个图片对象设置展示位置等信息,该对象重复利用,减少PDF文件大小
     * @param waterPath 图片位置
     * @param xPosition 横坐标
     * @param yPosition 纵坐标
     */
    private static Image singletonWaterMarkImage(String waterPath, float xPosition, float yPosition) throws Exception{
       Image waterMarkImage = Image.getInstance(waterPath);
        waterMarkImage.setAbsolutePosition(xPosition, yPosition);  // 坐标
        waterMarkImage.setRotation(-20);                     // 旋转 弧度
        waterMarkImage.setRotationDegrees(-45);                   // 旋转 角度
        waterMarkImage.scaleAbsolute(200, 100);                // 自定义大小
        waterMarkImage.scalePercent(100);                    // 依照比例缩放
        return waterMarkImage;
    }
   
   /**
    * 生成水印,加密在这里实现
    * @param sourceFilePath    源文件路径
    * @param fileWaterMarkPath 水印生成文件路径
    * @throws Exception
    */
   public static void setWaterMarkForPDF(String sourceFilePath, String fileWaterMarkPath, String waterMarkName)
         throws Exception {
      String waterPath = "E:\\中images\\xuzhi.jpg";// Class.class.getClass().getResource("E:\\xuzhi.jpg").getPath();
      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();
        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); // 水印underContent下层
         // 转换透明度(默认为50%)
         float diaphaneityF = 0.5f;
         under = stamp.getOverContent(i); // 水印上层
         // 设置透明度
         gs.setFillOpacity(diaphaneityF);
         gs.setStrokeOpacity(diaphaneityF);
         under.setGState(gs);
         
         // 添加图片
            under.addImage(img);
         under.beginText();
         under.setColorFill(BaseColor.BLUE);
         // under.setRGBColorFill(40, 125, 231);// 文字颜色
         under.setFontAndSize(bf, 30);

         // 设置水印文字字体倾斜 开始
         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(180, 100);
            for (int k = 0; k < j; k++) {
               under.setTextRise(rise);
               c = waterMarkName.charAt(k);
               under.showText(c + "");
               rise -= 18;
            }
         }
         // 字体设置结束
         under.endText();
      }

      stamp.close();
      reader.close();
   }
   
   static class HtmlToPdfInterceptor extends Thread {
      private InputStream is;

      public HtmlToPdfInterceptor(InputStream is) {
         this.is = is;
      }

      public void run() {
         try {
            InputStreamReader isr = new InputStreamReader(is, "utf-8");
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
               System.out.println(line.toString()); // 输出内容
            }
         } catch (IOException e) {
            e.printStackTrace();
         }
      }
   }

   /**
    * 
    * 【功能描述:添加图片和文字水印】 【功能详细描述:功能详细描述】
    * 
    * @param srcFile    待加水印文件
    * @param destFile   加水印后存放地址
    * @param text       加水印的文本内容
    * @param textWidth  文字横坐标
    * @param textHeight 文字纵坐标
    * @throws Exception
    */
   public static void addWaterMark(String srcFile, String destFile, String text, int textWidth, int textHeight)
         throws Exception {
      // 待加水印的文件
      PdfReader reader = new PdfReader(srcFile);
      // 加完水印的文件
      PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(destFile));
      int total = reader.getNumberOfPages() + 1;
      PdfContentByte content;
      // 设置字体
      BaseFont font = BaseFont.createFont();
      // 循环对每页插入水印
      for (int i = 1; i < total; i++) {
         // 水印的起始
         content = stamper.getUnderContent(i);
         // 开始
         content.beginText();
         // 设置颜色 默认为蓝色
         content.setColorFill(BaseColor.BLUE);
         // content.setColorFill(Color.GRAY);
         // 设置字体及字号
         content.setFontAndSize(font, 38);
         // 设置起始位置
         // content.setTextMatrix(400, 880);
         content.setTextMatrix(textWidth, textHeight);
         // 开始写入水印
         content.showTextAligned(Element.ALIGN_LEFT, text, textWidth, textHeight, 45);
         content.endText();
      }
      stamper.close();
   }
   
   public static void generateWaterPdf () throws Exception {
      // 实现A4纸页面 并且横向显示(不设置则为纵向)
      Document document = new Document(); // PageSize.A4.rotate()
      PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream("E:/home/in1-c00d842d-d365-4aba-a457-72b73054b7eb.pdf"));
      // 打开文档
      document.open();
      // 创建第一页(如果只有一页的话,这一步可以省略)
      document.newPage();

      // 加入水印
      PdfContentByte waterMar = pdfWriter.getDirectContentUnder();
      // 开始设置水印
      waterMar.beginText();
      // 设置水印透明度
      PdfGState gs = new PdfGState();
      // 设置填充字体不透明度为0.4f
      gs.setFillOpacity(0.4f);
      try {
         // 设置水印字体参数及大小 (字体参数,字体编码格式,是否将字体信息嵌入到pdf中(一般不需要嵌入),字体大小)
         waterMar.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 60);
         // 设置透明度
         waterMar.setGState(gs);
         // 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度
         waterMar.showTextAligned(Element.ALIGN_RIGHT, "www.tomatocc.com", 500, 430, 45);
         // 设置水印颜色
         waterMar.setColorFill(BaseColor.GRAY);
         // 结束设置
         waterMar.endText();
         waterMar.stroke();
      } catch (IOException e) {
         e.printStackTrace();
      } finally {
         waterMar = null;
         gs = null;
      }

      // 加入文档内容
      document.add(new Paragraph("my first pdf demo"));
      // 关闭文档
      document.close();
      pdfWriter.close();
   }
   
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值