iText使用html生成pdf

iText是java的一个类库,可以直接生成pdf文档,或者通过html模板生成pdf文档。使用html生成文档的方式比较方便前端同事开发页面(后端开发大部分审美确实是呵呵……),所以一般选用此种方式。
先列出此种方式容易遇到的几个问题:

  1. html标签需要严格闭合,不然会报错。如</p>,<br></br>,<img></img>等。注意,不支持<img src = "" />此类写法。
  2. 如果html中有引用图片,那么图片必须使用绝对路径,并且加上"file:///"前缀。
  3. 中文支持问题,由于itext默认不支持中文,所以需要手动指定中文字体。字体文件一般可以在window系统的C:\Windows\Fonts路径找到,如果使用liunx系统,可以将字体文件直接复制到liunx下使用。
    如果html中有需要动态替换的内容,建议使用ftl文件代替html文件。话不多说,直接上代码。
    ftl模板:
<html>
<head>
  <title>ECO 模板</title>
</head>
<body style="margin:0; padding:0; font-family: STFANGSO.TTF;">
  <div style="width:190mm; margin:0 auto; padding:0">
    <div style="padding:30px;">
      <div style="display:table; width:100%; margin:0 auto;">
        <table border="0" cellpadding="0" cellspacing="0" width="100%" align="left" style="border-collapse: collapse; margin:10px 0">
          <tbody>
            <tr>
              <td width="50%">
                <table>
                  <tr>
                    <td valign="middle">
                      <img src="${sinnetCloudPic}" alt="logo" width="120" height="42" style="vertical-align: middle;" ></img>&nbsp;
                      <span style="color:rgba(255, 147, 16, 1); font-size:13px; font-weight: bold; padding-left: 10px">有限公司</span>
                    </td>
                  </tr>
                  <tr><td style="padding:20px 0"></td></tr>
                  <tr>
                    <td style="font-size:16px;font-weight: bold;padding:5px 0;line-height:32px;list-style: none;">客户名称:</td>
                  </tr>
                  <tr>
                    <td style="word-break: break-all;font-size:14px; font-weight: normal; line-height:28px;">${customerName}</td>
                  </tr>
                  <tr>
                    <td style="font-size:16px;font-weight: bold;padding:5px 0;line-height:32px;list-style: none;">公司地址:</td>
                  </tr>
                  <tr>
                    <td style="word-break: break-all;font-size:14px; font-weight: normal; line-height:28px;">${customerAddress}</td>
                  </tr>
                </table>
              </td>
              <td width="50%">
                <table width="100%">
                  <tr>
                    <td colspan="2" style="font-size:14px;line-height: 24px;">付款通知</td>
                  </tr>
                  <tr>
                    <td colspan="2" style="font-size:14px;line-height: 24px;">如果您遇到任何关于账户账单问题,请通过邮件联系我们。</td>
                  </tr>
                  <tr>
                    <td colspan="2" style="font-size:14px;line-height: 24px;">客服邮箱:</td>
                  </tr>
                  <tr>
                    <td colspan="2" style="padding:10px 0; font-size:14px; font-weight:bold; text-align:left; ">付款账单总览</td>
                  </tr>
                  <tr>
                    <td style="color:rgba(53, 53, 53, 1); font-size:14px; padding:10px 0; border-top:1px dashed rgba(255, 147, 16, 1);">账单号:</td>
                    <td style="color:rgba(53, 53, 53, 1); font-size:14px; text-align:right; padding:10px 0; border-top:1px dashed rgba(255, 147, 16, 1);">${orderBillCode}</td>
                  </tr>
                  <tr>
                    <td colspan="2" style="font-size:12px; color:rgba(204,204,204,1); padding:0px 0px 10px 0; margin:0">进行电子资金转账付款时,请务必引用上述账单号。</td>
                  </tr>
                  <tr>
                    <td style="color:rgba(53, 53, 53, 1); font-size:14px;  padding:10px 0; border-top:1px dashed rgba(255, 147, 16, 1);">账单通知日期:</td>
                    <td style="color:rgba(53, 53, 53, 1); font-size:14px; padding:10px 0; border-top:1px dashed rgba(255, 147, 16, 1); text-align:right;">${billDate}</td>
                  </tr>
                  <tr>
                    <td style="color:rgba(53, 53, 53, 1); font-size:14px;  padding:10px 0; border-top:1px dashed rgba(255, 147, 16, 1);">账单总金额:</td>
                    <td style="color:rgba(53, 53, 53, 1); font-size:14px; padding:10px 0; border-top:1px dashed rgba(255, 147, 16, 1); text-align:right;">${billMoney}</td>
                  </tr>
                </table>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
     </div>
</div>
</body>
</html>

pom.xml

<!-- 生成pfd-->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.12</version>
</dependency>
<dependency>
    <groupId>com.itextpdf.tool</groupId>
    <artifactId>xmlworker</artifactId>
    <version>5.5.8</version>
</dependency>
<!-- ftl模板-->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.22</version>
</dependency>

Ftl工具类

package com.sinnet.eco.utils;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

public class GuoFtlUtil {

    /**
     * ftl文件替换数据并返回字符串
     *
     * @param ftlDir
     * @param ftlName
     * @param paramMap
     * @return
     * @throws IOException
     * @throws TemplateException
     */
    public static String ftlToString(String ftlDir, String ftlName, Map paramMap) throws IOException, TemplateException {
        Configuration cfg = new Configuration(Configuration.getVersion());
        cfg.setDefaultEncoding("UTF-8");
        cfg.setNumberFormat("0.00");
        cfg.setDirectoryForTemplateLoading(new File(ftlDir));
        Template template = cfg.getTemplate(ftlName);
        StringWriter writer = new StringWriter();
        template.process(paramMap, writer);
        writer.flush();
        String htmlTemplate = writer.toString();
        writer.close();
        return htmlTemplate;
    }
}

pdf工具类

package com.sinnet.eco.utils;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;

import java.io.*;
import java.nio.charset.Charset;

/**
 * 生成pdf工具类
 *
 * @author guoj
 * @date 2019-08-22
 */
public class GuoPdfUtil {

    /**
     * html模板的String生成pdf
     *
     * @param htmlTemplate
     * @param pdfPathName
     * @throws IOException
     * @throws DocumentException
     */
    public static void htmlTemplateToPdf(String htmlTemplate, String pdfPathName) throws IOException, DocumentException {
        File pdf = new File(pdfPathName);
        if (!pdf.getParentFile().exists()) {
            pdf.getParentFile().mkdirs();
        }
        if (pdf.exists()) {
            pdf.delete();
        }
        Document document = new Document(PageSize.LETTER);
        PdfWriter pdfWriter = PdfWriter.getInstance(document,
                new FileOutputStream(pdfPathName));
        XMLWorkerHelper worker = XMLWorkerHelper.getInstance();
        document.open();
        worker.parseXHtml(pdfWriter, document, new ByteArrayInputStream(htmlTemplate.getBytes("UTF-8")), Charset.forName("UTF-8"), new AsianFontProvider());
        document.close();
    }

    /**
     * 字体类
     */
    public static class AsianFontProvider extends XMLWorkerFontProvider {


        public AsianFontProvider() {
            super(null, null);
        }

        //    @Override
//    public Font getFont(final String fontname, String encoding, float size, final int style) {
//        String fntname = fontname;
//        if (fntname == null) {
//            /**
//             * 使用的windows里的宋体,可将其文件放资源文件中引入
//             */
//            String os = System.getProperties().getProperty("os.name");
//            if (os.startsWith("win") || os.startsWith("Win")) {
//                fntname = "simsun";
//            } else {
//                fntname = "simsun";
//            }
            fntname = "宋体";
//        }
//        if (size == 0) {
//            size = 4;
//        }
//        System.out.print("-----fntname:"+fntname);
//        return super.getFont(fntname, encoding, size, style);
//    }

        @Override
        public Font getFont(String fontname, String encoding, boolean embedded, float size, int style, BaseColor color) {
            //字体文件路径
            String name = "";
            //华文仿宋
            String fontNameDefault = "STFANGSO.TTF";
            if (fontname != null) {
                /**
                 * 可以在html中指定字体,如在body中指定:font-family: SimSun.ttc;
                 */
                fontNameDefault = fontname;
            }
            String os = System.getProperties().getProperty("os.name").toLowerCase();
            if (os.startsWith("win")) {
                name = "E:/test/pdf/billpdf/ftl/" + fontNameDefault + "";
            } else {
                name = "/data/eco/billpdf/ftl/" + fontNameDefault + "";
            }
            //如果是ttc,需要如下处理
            if (name.toLowerCase().contains("ttc")) {
                name += ",1";
            }
            Font font = null;
            try {
                font = new Font(BaseFont.createFont(name, BaseFont.IDENTITY_H, BaseFont.EMBEDDED));
                font.setStyle(style);
                font.setColor(color);
                if (size > 0) {
                    font.setSize(size);
                }
            } catch (DocumentException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return font;
        }
    }

}

运行结果截图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值