根据网上java io.woo.htmltopdf依赖库在windows测试能运行,一旦部署到线上总是报依赖的so文件找不到,按照官网文档安装各种ubuntu下依赖都不行,只能放弃。因此本文直接用linux或者windows上htmltopdf工具,执行命令行的方式进行。itextpdf样式不好,也是放弃的。调用addhtml生成html,在调用htmlToPdf生成PDF。
1. 下载工具包
windows上水印添加需要配置环境。
下载地址?wkhtmltopdf
ubuntu下载
apt install wkhtmltopdf
2.?代码实现
package com.xxxx.tools;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
/**
* * @Creator Jacky
* * @CreateTime 2022/2/22
* * @Description
*/
public class HtmlTools {
public static String LINUX_PATH = "/usr/bin/xvfb-run /usr/bin/wkhtmltopdf";
public static String WINDOWS_PATH = "C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe";
public static boolean addHtml(JSONObject jsonObject, String path){
//用于存储html字符串
StringBuilder html = new StringBuilder();
//输入HTML文件内容
html.append("<html xmlns=\"http://www.w3.org/1999/xhtml\">").append("\n");
html.append("<head>").append("\n");
html.append("<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">").append("\n");
//html.append("<meta charset=\"utf-8\">").append("\n");
//html.append("<title>简历</title>").append("\n");
getCss(html);
html.append("</head>").append("\n");
html.append("<body style='font-family: SimSun,serif;word-wrap:break-word;word-break: break-all;'>").append("\n");
getBody(html,jsonObject);
html.append("</body></html>").append("\n");
try{
File f = new File(path);
if (f.getParentFile() == null) {
Objects.requireNonNull(f.getParentFile()).isDirectory();
}
// 创建文件
f.getParentFile().mkdirs();
//将HTML文件内容写入文件中
FileOutputStream fileOutputStream=new FileOutputStream(path);
PrintStream printStream=new PrintStream(fileOutputStream);
// 转码,转化为utf-8
String htmls = new String(html.toString().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
printStream.println(htmls);
fileOutputStream.flush();
printStream.flush();
fileOutputStream.close();
printStream.close();
return true;
}catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static boolean htmlToPdf(String outputFile,String htmlPath) {
File outFile = new File(outputFile);
if (!outFile.exists()) {
outFile.getParentFile().mkdirs();
}
String toPdfTool = "";
StringBuilder cmd = new StringBuilder();
if (!System.getProperty("os.name").contains("Windows")) {
// 非windows 系统
toPdfTool =LINUX_PATH;
}else{
toPdfTool = WINDOWS_PATH;
}
cmd.append(toPdfTool);
cmd.append(" ");
cmd.append(" ");
cmd.append(htmlPath);
cmd.append(" ");
cmd.append(" ");
cmd.append(outputFile);
System.out.println(cmd);
boolean result = true;
try {
String html = new String(cmd.toString().getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
Process proc = Runtime.getRuntime().exec(html);
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 getCss(StringBuilder html){
html.append("<style type=\"text/css\">").append("\n");
html.append("@page:left{margin: 0cm;}").append("\n");
html.append("@page:right{margin: 0cm;}").append("\n");
html.append(".resumeDetails .t1 {width: 90%;margin: 0 auto;padding: 0 20px 20px 20px;background: #ffffff;border-radius: 10px;}").append("\n");
html.append(".resumeDetails .t3 {border-left: 4px solid #00abc3;padding-left: 8px;line-height: 1;font-size: 28px;margin: 30px 0 20px;font-weight: bold;color: #333333; }").append("\n");
html.append(".resumeDetails .t12 {position: relative;padding: 20px 40px 30px;}").append("\n");
html.append(".resumeDetails .t5 {font-size: 32px;font-weight: bold;color: #333333;margin: 24px 0;}").append("\n");
html.append(".resumeDetails .t6 { font-size: 24px;color: #666666;margin: 24px 0 40px; }").append("\n");
html.append(".resumeDetails .t10 { position: absolute;right: 50px;top: 50px;width: 78px;height: 78px;display: flex; }").append("\n");
html.append(".resumeDetails .t10 .headImg { width: 78px;height: 78px;border-radius: 50%; }").append("\n");
html.append(".resumeDetails .t10 .sexIcon { width: 16px;height: 16px;position: absolute;right: 0;bottom: 0; }").append("\n");
html.append(".resumeDetails .t4 .t8>p { font-size: 26px;font-weight: bold;display: inline-block;vertical-align: top;color: #333333;line-height: 1;padding-right: 20px;margin-right: 20px; }").append("\n");
html.append(".resumeDetails .t4 .t9>p { display: inline-block;padding: 4px 20px;background: #f3f7fa;border-radius: 5px;margin-right: 10px;font-size: 22px;color: #999999; }").append("\n");
html.append(".resumeDetails .t4 .t7 { border-right: 2px solid #999999; }").append("\n");
html.append(".resumeDetails .t4>div { display: flex;margin-top: 10px;font-size: 24px;color: #666666; }").append("\n");
html.append(".resumeDetails .t4 .a1 { display: block; }").append("\n");
html.append(".resumeDetails .t4 .a1 span { margin-right: 30px; }").append("\n");
html.append(".resumeDetails .t4 .a1 .a2 { margin-bottom: 10px; }").append("\n");
html.append(".resumeDetails .t4 .a1 .a2 img { height: 112px;border-radius: 9px;margin-right: 12px;margin-bottom: 12px; }").append("\n");
html.append("</style>").append("\n");
}
public static void getBody(StringBuilder html,JSONObject jsonObject){
Integer def = jsonObject.getInteger("pdf_lang");
html.append("<div class=\"resumeDetails\">").append("\n");
html.append("<div class=\"t1\">").append("\n");
html.append("<div class=\"t12\" id=\"pdfDom\">").append("\n");
if(!StringUtils.isEmpty(jsonObject.getString("pdf_info"))){
//个人模块
ResumePdfInfo pdfInfo = (ResumePdfInfo)jsonObject.get("pdf_info");
if(pdfInfo!=null){
html.append("<div class=\"t5\">").append(pdfInfo.getNickName()).append("</div>\n");
html.append("<div class=\"t6\">").append("\n");
html.append("<span>")
.append(pdfInfo.getEducation()).append(" | ")
.append(pdfInfo.getCityName()).append(" | ")
.append(pdfInfo.getAge()).append(" | ")
.append(pdfInfo.getMobile()).append(" | ")
.append(pdfInfo.getEmail()).append("</span>\n");
html.append("</div>").append("\n");
}
}
if(!StringUtils.isEmpty(jsonObject.getString("pdf_info"))){
//个人模块
ResumePdfInfo pdfInfo = (ResumePdfInfo)jsonObject.get("pdf_info");
if(pdfInfo!=null){
html.append("<div class=\"t10\">").append("\n");
html.append("<div>").append("\n");
if(!StringUtils.isEmpty(pdfInfo.getImageUrl())){
html.append("<img class=\"headImg\" src=\"").append(pdfInfo.getImageUrl()).append("\" alt=\"\"/>").append("\n");
}else{
html.append("<img class=\"headImg\" src=\"xxxxx\"/>").append("\n");
}
if(pdfInfo.getGender()!=null){
if(pdfInfo.getGender()==1){
html.append("<img class=\"sexIcon\" src=\"xxx\"/>").append("\n");
}else{
html.append("<img class=\"sexIcon\" src=\"https://xxxx\"/>").append("\n");
}
}
html.append("</div>").append("\n");
html.append("</div>").append("\n");
}
}
html.append("</div>").append("\n");
html.append("</div>").append("\n");
html.append("</div>").append("\n");
}
}
package com.xxxx.tools;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* * @Creator Jacky
* * @CreateTime 2022/3/15
* * @Description
*/
public class HtmlToPdfInterceptor extends Thread {
private InputStream is;
public HtmlToPdfInterceptor(InputStream is){
this.is = is;
}
@Override
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();
}
}
}
|