技术联盟

Itext html转PDF,解决中文不显示与样式问题

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&amp;More</div>\n" +
                "            <div> THANK YOU FOR SHOPPING WITH Fudi&amp;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:&nbsp;</strong>D-8C2Y Placed on 29/09/2019 10:04</div>\n" +
                "                <div><strong>Carrier:&nbsp;</strong>Delivery</div>\n" +
                "                <div><strong>Payment:&nbsp;</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;\">&euro; 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;\">&euro; 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;\">&euro; 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;\">&euro; 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;\">&euro; 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;\">&euro; 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;\">&euro;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;\">+&euro;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;\">-&euro;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;\">&euro;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> &#9742; <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>

这就完了.直接运行没问题。还有比如 & 在正文中的要转义 &amp; 要不然报错,格式一定要正确,</>结束符一定要有,标准也要有

<!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中注意:开始要设置,并且一定要设置字体

Share this:

码字很辛苦,转载请注明来自技术联盟《Itext html转PDF,解决中文不显示与样式问题》

评论