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(); } }