package com.zdltech.test.pdf;
import com.lowagie.text.pdf.BaseFont;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.*;
public class PDFUtils6 {
/**
* 获取对应pageName的html内容(生产环境java -jar直接run)
*/
private static String getHtmlByPageName2(String filePath) throws IOException {
// /BOOT-INF/classes/templates/dashboard.html
// 返回读取指定资源的输入流
InputStream is = new FileInputStream(new File(filePath));
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String s = "";
StringBuffer sb = new StringBuffer();
while ((s = br.readLine()) != null) {
sb.append(s).append("\n");
}
return sb.toString();
}
/**
* 将HTML转成PD格式的文件。html文件的格式比较严格
* @param htmlFile
* @param pdfFile
* @throws Exception
*/
// <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
public static void html2pdf(String htmlFile, String pdfFile) throws Exception {
// step 1
String url = new File(htmlFile).toURI().toURL().getPath();
System.out.println(url);
// step 2
OutputStream os = new FileOutputStream(pdfFile);
ITextRenderer renderer = new ITextRenderer();
String result = getHtmlByPageName2(url);
// System.out.println(result.substring(1));
System.out.println(result);
renderer.setDocumentFromString(result);
// renderer.setDocumentFromString(result.substring(1));
// renderer.setDocumentFromString(getXmlString());
// renderer.setDocument(url);
// step 3 解决中文支持
ITextFontResolver fontResolver = renderer.getFontResolver();
if("linux".equals(getCurrentOperatingSystem())){
fontResolver.addFont("/Users/jason/Desktop/test/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
}else{
fontResolver.addFont("/Users/jason/Desktop/test/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
fontResolver.addFont("/Users/jason/Desktop/test/simkai.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
}
renderer.layout();
renderer.createPDF(os);
os.close();
System.out.println("create pdf done!!");
}
public static String getCurrentOperatingSystem(){
String os = System.getProperty("os.name").toLowerCase();
System.out.println("---------当前操作系统是-----------" + os);
return os;
}
public static String getXmlString() {
String xmlString="<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n" +
"<html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\"/>\n" +
" <title>Hello World</title>\n" +
"\t<style>\n" +
"\t table.table-separate th{\n" +
" font-weight:bold;\n" +
" font-size:14px;\n" +
" border-top:1px solid #F3EDE9 !important;\n" +
" }\n" +
" table.table-separate td{\n" +
" padding: 13px 0;\n" +
" font-weight:100;\n" +
" }\n" +
" .table-separate td.tit{\n" +
" background-color: #f4f9fe;\n" +
" font-weight:normal;\n" +
" padding:22px 0;\n" +
" width:15%;\n" +
" }\n" +
" .table-separate td.cont{\n" +
" text-align: left;\n" +
" padding:16px 22px;\n" +
" width:85%;\n" +
" line-height:175%;\n" +
" }\n" +
" .table-separate.no-border th{\n" +
" border:none;\n" +
" text-align: left;\n" +
" }\n" +
" .table-separate.no-border td{\n" +
" text-align: left;\n" +
" border:none;\n" +
" }\n" +
"\t@page {\n" +
"\tsize:210mm 297mm;//纸张大小A4\n" +
"\tmargin: 0.25in;\n" +
"\t-fs-flow-bottom: \"footer\";\n" +
"\t-fs-flow-left: \"left\";\n" +
"\t-fs-flow-right: \"right\";\n" +
"\tborder: thin solid black;\n" +
"\tpadding: 1em;\n" +
"\t}\n" +
"\t#footer {\n" +
"\tfont-size: 90%; font-style: italic;\n" +
"\tposition: absolute; top: 0; left: 0;\n" +
"\t-fs-move-to-flow: \"footer\";\n" +
"\t}\n" +
"\t#pagenumber:before {\n" +
"\tcontent: counter(page);\n" +
"\t}\n" +
"\t#pagecount:before {content: counter(pages);\n" +
"\t}\n" +
"\ttable {\n" +
"\t\t\tborder-collapse: collapse;\n" +
"\t\t\ttable-layout: fixed;\n" +
"\t\t\tword-break:break-all;\n" +
"\t\t\tfont-size: 10px;\n" +
"\t\t\twidth: 100%;\n" +
"\t\t\ttext-align: center;\n" +
"\t}\n" +
"\ttd {\n" +
"\t\tword-break:break-all;\n" +
"\t\tword-wrap : break-word;\n" +
"\t}\n" +
"\t</style>\n" +
"\t</head>\n" +
"<body style = \"font-family: SimSun;\">\n" +
"<div id=\"footer\" style=\"\"> Page <span id=\"pagenumber\"/> of <span id=\"pagecount\"/> </div>\n" +
"<div id=\"main\">\n" +
" <div style=\"max-width:600px;margin:0 auto;padding:10px;\">\n" +
" <div style=\"text-align: center; padding: 5mm 0;\">\n" +
" <div style=\"font-weight: bold; font-size: 30px;\"> HI Fudi&More</div>\n" +
" <div> THANK YOU FOR SHOPPING WITH Fudi&More!</div>\n" +
" </div>\n" +
" <div style=\"border: 1px solid black; background-color: #f8f8f8; padding: 4mm;\">\n" +
" <div style=\"font-size: 17px; font-weight: bold; border-bottom: 1px solid black; padding-bottom: 5mm;\"> ORDER DETAILS</div>\n" +
" <div style=\"padding-top: 10px;\">\n" +
" <div><strong>Order: </strong>D-8C2Y Placed on 29/09/2019 10:04</div>\n" +
" <div><strong>Carrier: </strong>Delivery</div>\n" +
" <div><strong>Payment: </strong>Cash Payment</div>\n" +
" </div>\n" +
" </div>\n" +
" <div style=\"margin-top: 4mm;\">\n" +
" <table class=\"table-separate\" cellpadding=\"0\" cellspacing=\"0\" style=\"max-width:600px;margin:0 auto;padding:10px;\">\n" +
" <thead>\n" +
" <tr style=\"text-align: center; height: 40px;\">\n" +
" <th style=\"width: 90px; background-color: #f8f8f8; border-top: 1px solid black; border-left: 1px solid black; border-right: 1px solid black;\">\n" +
" Reference\n" +
" </th>\n" +
" <th colspan=\"2\" style=\"background-color: #f8f8f8; border-top: 1px solid black; border-right: 1px solid black;\">Product</th>\n" +
" <th style=\"width: 110px; background-color: #f8f8f8; border-top: 1px solid black; border-right: 1px solid black;\">Unit price</th>\n" +
" <th style=\"width: 80px; background-color: #f8f8f8; border-top: 1px solid black; border-right: 1px solid black;\">Quantity</th>\n" +
" <th style=\"width: 90px; background-color: #f8f8f8; border-top: 1px solid black; border-right: 1px solid black;\">Total price</th>\n" +
" </tr>\n" +
" </thead>\n" +
" <tbody>\n" +
" <tr style=\"text-align: center; \">\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black;\">\n" +
" Main\n" +
" </td>\n" +
" <td colspan=\"2\"\n" +
" style=\"border-top: 1px solid black; border-bottom:1px solid black; border-right: 1px solid black; text-align: left; padding: 010px;\">\n" +
" SweetSour Chicken\n" +
" </td>\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-right: 1px solid black;\">€ 7.00</td>\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-right: 1px solid black;\">1</td>\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-right: 1px solid black;\">€ 7.00</td>\n" +
" </tr>\n" +
" <tr style=\"text-align: center; \">\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black;\">\n" +
" Main\n" +
" </td>\n" +
" <td colspan=\"2\"\n" +
" style=\"border-top: 1px solid black; border-bottom:1px solid black; border-right: 1px solid black; text-align: left; padding: 010px;\">\n" +
" Black Bean Stir Fry\n" +
" </td>\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-right: 1px solid black;\">€ 9.00</td>\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-right: 1px solid black;\">1</td>\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-right: 1px solid black;\">€ 9.00</td>\n" +
" </tr>\n" +
" <tr style=\"text-align: center; \">\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black;\">\n" +
" Pizzas\n" +
" </td>\n" +
" <td colspan=\"2\"\n" +
" style=\"border-top: 1px solid black; border-bottom:1px solid black; border-right: 1px solid black; text-align: left; padding: 010px;\">\n" +
" Test Design Your Own 8\" Pizza\n" +
" </td>\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-right: 1px solid black;\">€ 6.00</td>\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-right: 1px solid black;\">1</td>\n" +
" <td style=\"border-top: 1px solid black; border-bottom: 1px solid black; border-right: 1px solid black;\">€ 6.00</td>\n" +
" </tr>\n" +
" </tbody>\n" +
" <tfoot>\n" +
" <tr style=\"text-align: center; height: 8mm;\">\n" +
" <td colspan=\"5\"\n" +
" style=\"text-align: right; width: 90px; background-color: #f8f8f8; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 0 10px;\">\n" +
" Item:\n" +
" </td>\n" +
" <td style=\"background-color: #f8f8f8; border-bottom: 1px solid black; border-right: 1px solid black;\">3</td>\n" +
" </tr>\n" +
" <tr style=\"text-align: center; height: 8mm;\">\n" +
" <td colspan=\"5\"\n" +
" style=\"text-align: right; width: 90px; background-color: #f8f8f8; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 0 10px;\">\n" +
" Subtotal:\n" +
" </td>\n" +
" <td style=\"background-color: #f8f8f8; border-bottom: 1px solid black; border-right: 1px solid black;\">€24.00</td>\n" +
" </tr>\n" +
" <tr style=\"text-align: center; height: 8mm;\">\n" +
" <td colspan=\"5\"\n" +
" style=\"text-align: right; width: 90px; background-color: #f8f8f8; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 0 10px;\">\n" +
" Deliver Fee:\n" +
" </td>\n" +
" <td style=\"background-color: #f8f8f8; border-bottom: 1px solid black; border-right: 1px solid black;\">+€2.00</td>\n" +
" </tr>\n" +
" <tr style=\"text-align: center; height: 8mm;\">\n" +
" <td colspan=\"5\"\n" +
" style=\"text-align: right; width: 90px; background-color: #f8f8f8; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 0 10px;\">\n" +
" Discount:\n" +
" </td>\n" +
" <td style=\"background-color: #f8f8f8; border-bottom: 1px solid black; border-right: 1px solid black;\">-€0.00</td>\n" +
" </tr>\n" +
" <tr style=\"text-align: center; height: 8mm;\">\n" +
" <td colspan=\"5\"\n" +
" style=\"text-align: right; width: 90px; background-color: #f8f8f8; border-bottom: 1px solid black; border-left: 1px solid black; border-right: 1px solid black; padding: 0 10px;\">\n" +
" Total:\n" +
" </td>\n" +
" <td style=\"background-color: #f8f8f8; border-bottom: 1px solid black; border-right: 1px solid black;\">€24.00</td>\n" +
" </tr>\n" +
" </tfoot>\n" +
" </table>\n" +
" </div>\n" +
" <div>\n" +
" <div style=\"border: 1px solid black; background-color: #f8f8f8; padding:5mm; margin-top: 5mm;\">\n" +
" <div style=\"font-size: 17px; font-weight: bold; border-bottom: 1px solid black; padding-bottom: 15px;\"> DELIVERY ADDRESS</div>\n" +
" <div style=\"padding-top: 10px;\">\n" +
" <div><strong>guan</strong> ☎ <strong>13656690321</strong></div>\n" +
" <div> 1024/ Edenhall,ModelFarmRd,Cork,爱尔兰,A 2048</div>\n" +
" </div>\n" +
" </div>\n" +
" </div>\n" +
" <div style=\"font-size: 13px;\"><p>You can review your order and download your invoice from the \"<a target=\"_blank\"\n" +
" href=\"http://www.fudiandmore.ie/#/FudiIndex/Order1\">Order\n" +
" history</a>\"section of your customer account by clicking \"<a target=\"_blank\" href=\"http://www.fudiandmore.ie/#/FudiIndex/Personalcenter1\">My\n" +
" account</a>\" on ourshop.</p></div>\n" +
" <hr style=\"border-width: 5px;\"/>\n" +
" <div> Fudi,More powered by <a target=\"_blank\" href=\"http://www.fudiandmore.ie\">A2BLiving</a></div>\n" +
" </div>\n" +
"</div>\n" +
"</body>\n" +
"</html>";
StringBuffer stringBuffer=new StringBuffer();
return xmlString;
}
public static void main(String[] args) {
// String htmlFile = "/home/lbj/sign.jsp";
// String pdfFile = "/home/lbj/sign.pdf";
String htmlFile = "/Users/jason/Desktop/test/aaa/aaa.html";
// String htmlFile = "/Users/jason/Desktop/test/pdftest.html";
String pdfFile = "/Users/jason/Desktop/test/pdftest30.pdf";
try {
PDFUtils6.html2pdf(htmlFile, pdfFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.0.3</version>
</dependency>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
<style>
@page {
size: A4;
margin: 0;
}
body{
zoom:0.8;
transform: scale(0.8);
}
.fontSize16 {
font-size: 16px !important;
}
.cllor3B7 {
color: #3B76B5 !important;
}
.posAbsolute {
position: absolute !important;
}
.posRelative {
position: relative !important;
}
.textAlignLeft {
text-align: left
}
.textAlignRight {
text-align: right
}
.voucher_body {
/* position: relative;width: 954px;height: 424px;margin-left: -477px;margin-top: -212px;top: 50%;left: 50%; */
position: relative;
}
.voucher {
position: relative;
width: 954px;
height: 424px;
background-size: 82% 82% !important;
z-index: 999;
}
.printBtn {
position: absolute;
left: 50%;
margin-left: -100px !important;
}
.voucherPrint {
position: fixed;
width: 954px;
height: 424px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: initial !important;
z-index: 99999;
display: none;
}
.voucherPDF {
position: fixed;
width: 954px;
height: 424px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: initial !important;
z-index: 999999;
display: none;
}
.openBg {
background: url('https://www.zchfax.com/data/temp/0_15723304043.jpg') no-repeat !important;
}
.openBg2 {
background: url('/Users/jason/Desktop/test/aaa/open@2x.png') no-repeat !important;
}
.financingBg {
background: url('financing@2x.png') no-repeat !important;
}
.trasterBg {
background: url('transter@2x.png') no-repeat !important;
}
.vouStatus {
left: 124px;
top: 65px;
}
.vouStatus>span {
color: #EA2A41 !important;
}
.voucher .voNumber {
right: 25%;
top: 50px;
color: #EA2A41 !important;
}
.voucher .voNumber2 {
left: 120px;
bottom: 16px;
color: #EA2A41 !important;
}
.voucherContent .gsName {
top: 98px;
}
.voucherContent .skName {
top: 98px;
}
.voucherDer {
width: 296px;
}
.voucherContent .openDer {
width: 288px;
}
.voucherContent .shNumber {
top: 129px;
}
.voucherContent .shNumber2 {
top: 129px;
}
.voucherContent .moneyNumber {
top: 169px;
}
.moneyALL {
right: 23.5%;
top: 184px;
height: 30px;
width: 296px;
}
/* width: 100%;
height: 100%;
*/
.monyList {
width: 100%;
height: 100%;
align-items: center;
}
.monyList>div {
float: left;
width: 8.33%;
height: 30px;
padding: 5px 0;
text-align: center;
color: #3B76B5 !important;
}
.voucherContent .openDate {
top: 209px;
}
.voucherContent .openEleName {
top: 241px;
}
.voucherContent .payDate {
top: 209px;
}
.voucherContent .voucherLeft {
left: 124px;
}
.voucherContent .voucherRight {
right: 121px;
}
</style>
</head>
<body style="font-family: SimSun;line-height:1;font-size:10.0pt;">
<div class="textAlignCenter masking_alt" id="forPrint">
<div class="voucher openBg office">
<div class="voucherDer vouStatus textAlignLeft voucherLeft fontSize16 posAbsolute"><span>已签收</span></div>
<p class="voNumber fontSize16 posAbsolute">BL20200615101522932</p>
<div class="voucherContent">
<div class="gsName voucherDer posAbsolute textAlignLeft voucherLeft"><span
class="fontSize16 cllor3B7">泽诚控股有限公司</span></div>
<div class="skName posAbsolute textAlignLeft voucherDer voucherRight"><span
class="fontSize16 cllor3B7">陕西泽诚置业有限公司</span></div>
<div class="shNumber posAbsolute textAlignLeft voucherDer voucherLeft"><span
class="fontSize16 color2B2">91610132MA6X53QN7L</span></div>
<div class="shNumber2 posAbsolute textAlignLeft voucherDer voucherRight"><span
class="fontSize16 color2B2">8351515313513852</span></div>
<div class="moneyNumber posAbsolute textAlignLeft openDer voucherLeft"><span
class="fontSize16 cllor3B7">(大写)伍拾万元</span></div>
<div class="moneyALL posAbsolute textAlignLeft">
<div class="monyList">
<div class="moneyOne"></div>
<div class="moneyOne"></div>
<div class="moneyOne"></div>
<div class="moneyOne">$</div>
<div class="moneyOne">6</div>
<div class="moneyOne">0</div>
<div class="moneyOne">5</div>
<div class="moneyOne">0</div>
<div class="moneyOne">0</div>
<div class="moneyOne">0</div>
<div class="moneyOne">0</div>
<div class="moneyOne">0</div>
</div>
</div>
<div class="openDate posAbsolute textAlignLeft voucherDer voucherLeft"><span
class="fontSize16 cllor3B7">2020-06-15</span></div>
<div class="openEleName posAbsolute textAlignLeft voucherDer voucherLeft"><span
class="fontSize16 cllor3B7"></span></div>
<div class="payDate posAbsolute textAlignLeft voucherDer voucherRight"><span
class="fontSize16 cllor3B7">2025-06-30</span></div>
</div>
<div class="fontSize16 posAbsolute voNumber2 textAlignLeft voucherDer"><span></span></div>
</div>
</div>
</body>
</html>
这就完了.直接运行没问题。还有比如 & 在正文中的要转义 & 要不然报错,格式一定要正确,</>结束符一定要有,标准也要有
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"> <html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">
这个缺了你可以试试,出了问题你自己该,还有一点很重要,body 中指定字体,不指定的,中文你就不要想它出现了。还有一些 分页啥的,样式里写好就行,要是超宽了,那就自己看着实例的样式改改,大概就好了。
如果HTML中有图片,注意使用 网络图片(http://xxxxxx.png等),Mac下面图片可以使用绝对路径,Win上面不行,故推荐大家使用网络地址图片
HTML中注意:开始要设置,并且一定要设置字体