itextpdf结合jfinal模版生成pdf文件


jar使用的是红色部分两个,其余的是其余的加强jar,暂时没有用到  

<!--生成pdf--> <!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf --> <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.11</version> </dependency> <!-- https://mvnrepository.com/artifact/com.itextpdf.tool/xmlworker iText-Html渲染--> <dependency> <groupId>com.itextpdf.tool</groupId> <artifactId>xmlworker</artifactId> <version>5.5.11</version> </dependency> <!-- https://mvnrepository.com/artifact/org.freemarker/freemarker 5.iText-Html-Freemarker渲染--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.19</version> </dependency> <!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf 6.Flying Saucer-CSS高级特性支持--> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf</artifactId> <version>9.1.5</version> </dependency> <!-- https://mvnrepository.com/artifact/org.xhtmlrenderer/flying-saucer-pdf-itext5 6.Flying Saucer-CSS高级特性支持--> <dependency> <groupId>org.xhtmlrenderer</groupId> <artifactId>flying-saucer-pdf-itext5</artifactId> <version>9.1.5</version> </dependency> <!--pdf转jpg --> <!-- https://mvnrepository.com/artifact/org.jpedal/jpedal-lgpl --> <!--<dependency> <groupId>org.jpedal</groupId> <artifactId>jpedal-lgpl</artifactId> <version>4.74b27</version> </dependency>--> <!--<dependency> <groupId>com.itextpdf</groupId> <artifactId>itext-asian</artifactId> <version>5.2.0</version> </dependency>--> <!-- https://mvnrepository.com/artifact/com.lowagie/itext --> <!--<dependency> <groupId>com.lowagie</groupId> <artifactId>itext</artifactId> <version>2.1.7</version> </dependency>--> <!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.7</version> </dependency> <!--生成pdf-->

 

工具的结构html

 

这个结构能够适用于不一样的使用方式,这里我写了三种,后续有,还能够继承抽象类就能够了,下边把代码贴出来,能够参考看一下java

1.接口apache

import java.io.OutputStream;
import java.util.Map;

/**
 * 生成pdf的接口
 * 生成pdf都须要把一个字符串写成pdf文件输出到指定的地方
 */
public interface PDF {

    boolean writeToPDF(Map<String, Object> data, String htmlTmp, OutputStream out);
}

2.抽象类ide

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.jfinal.kit.PathKit;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Map;

public abstract class BasePDF implements PDF {
    //字体
    private static String FONT = PathKit.getWebRootPath() + "/js/font/simhei.ttf";

    /**
     * 字体这里设置了默认的,若是使用其余字体须要倒入字体,而后经过这个方法设定字体
     * @param FONT
     */
    public static void setFont(String FONT) {
        BasePDF.FONT = FONT;
    }

    @Override
    public boolean writeToPDF(Map<String, Object> data, String htmlTmp, OutputStream out) {
        String content = templateToString(data, htmlTmp);
        return write(content, out);
    }

    /**
     * 准备生成pdf
     */
    public boolean write(String content, OutputStream out) {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = null;
        try {
            writer = PdfWriter.getInstance(document, out);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        // step 3
        document.open();
        // step 4
        XMLWorkerFontProvider fontImp = new XMLWorkerFontProvider(XMLWorkerFontProvider.DONTLOOKFORFONTS);
        fontImp.register(FONT);
        try {
            XMLWorkerHelper.getInstance().parseXHtml(writer, document,
                    new ByteArrayInputStream(content.getBytes()), null, Charset.forName("UTF-8"), fontImp);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        // step 5
        document.close();
        return true;
    }

    /**
     * 要输出的字符串模板
     */
    public abstract String templateToString(Map<String, Object> data, String htmlTmp);
}

3.jfinal实现类工具

import com.jfinal.template.Engine;
import com.jfinal.template.Template;

import java.util.Map;

public class TemplateToPDFJfinal extends BasePDF {
    protected static Engine myEngine;

    /**
     * 系统启动时初始化,在启动文件中的设置
     */
    public static void setEngine(Engine engine) {
        TemplateToPDFJfinal.myEngine = engine;
    }

    public static Engine getEngine() {
        return myEngine;
    }

    @Override
    public String templateToString(Map<String, Object> data, String htmlTmp) {
        if(myEngine == null){
            throw new RuntimeException("Did not setEngine(Engine engine),You must setEngine(Engine engine) after using this tool");
        }
        
        myEngine.setDevMode(true);
        myEngine.setEncoding("UTF-8");
        Template template = myEngine.getTemplate(htmlTmp);
        return template.renderToString(data);
    }
}

4.代理类测试

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class PDFProxy<T> {
    T target;

    public PDFProxy(T target) {
        this.target = target;
    }

    public Object getInstance() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getSuperclass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        Object invoke = method.invoke(target, args);
                        return invoke;
                    }
                });
    }
}

5.工厂类字体

public class PDFFactory {
    public static PDF getPDF(Class<?> p) {
        PDF pdf = null;
        try {
            pdf = (PDF) p.newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        PDFProxy pdfProxy = new PDFProxy(pdf);
        return (PDF) pdfProxy.getInstance();
    }
}

6.数据封装类this

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;

public class pdfTest {
    public static final String DESTJfinal = "/pdfJfinal.pdf";

    /**
     * 简单写个方法测试 生成pdf
     *
     * @param templateName 模板名称位置
     * @param outPath      输出位置
     * @param pdfClass     使用的是哪一个实现类
     */
    public static void test(String templateName, String outPath, Class<?> pdfClass) {
        //设置字体
        //BasePDF.setFont("/xx/xx.ttf");

        PDF pdf = PDFFactory.getPDF(pdfClass);
        Map<String, Object> m = new HashMap<>();
        m.put("red", "红色");
        try {
            pdf.writeToPDF(m, templateName, new FileOutputStream(new File(outPath)));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

7.使用spa

 /**
     * 测试报告使用
     * 生成这一周的报告
     * /report/handleTestReport
     * 这个会把pdf生成到项目到根目录下,根据需求本身调
     */
    @Clear
    public void handleTestReport() {
        pdfTest.test("/mail/a.html", PathKit.getWebRootPath() + pdfTest.DESTJfinal, TemplateToPDFJfinal.class);
    }

 

好了上边是全部到类代理

下边把基础的辅助资料写一下

字体:我把字体放到根目录下的js下了,具体看图片,根据本身的需求,我写了设置字体的方法没,能够本身设置

模版文件:我放到了根目录下的mail下了

内容是:

<!--要求比较严格,html中的标签必须有开始结束标签, 但标签须要加 /   好比:<meta charset="UTF-8" /> -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>jfinal模板使用</title>
    <style>
        body {
       //比较重要的一点,若是这里设置的字体是咱们后台设置的不同的,是没有的字体,那么,中文就不会显示了,还有就是标签必定要按照规定写,必定要有闭合标签或者 < xxx /> 这样字的
font-family: SimHei,serif; } .pos { position: absolute; left: 200px; top: 5px; width: 200px; font-size: 10px; } .table-one { width: 700px; text-align: center; border-collapse: collapse; } /*细调试*/ .title-big{ font-size: 20px; } .title-middle{ font-size: 16px; } .title-small{ font-size: 13.33px; } .red{ background-color: #E11B22; } .black{ background-color: black; color: white; } </style> </head> <body> <div class="pos"> <!--图片--> <table class="table-one"> <tr> <td colspan="5"> <img alt="tp" style="width: 153px;margin-left: 300px" src="/Users/renjianjun/Downloads/斗图/mao.jpg"/> </td> </tr> </table> <table border="1" class="table-one"> <tr> <td colspan="5" class="title-big black">20px标题</td> </tr> <tr class="title-middle"> <td class="red" rowspan="3"> <table> <tr><td>#(red)这里是取值,为了实验没有多写,只有这三个取值</td></tr> <tr><td>#(red)</td></tr> <tr><td>#(red)</td></tr> </table> </td> <td colspan="4">数据</td> </tr> <tr class="title-middle"> <!-- <td class="red">红色</td>--> <td colspan="4">数据</td> </tr> <tr class="title-middle"> <!-- <td class="red">红色</td>--> <td colspan="4">数据</td> </tr> <tr class="title-middle black"> <td colspan="5">16px二级标题</td> </tr> <tr class="title-small"> <td>13px标题</td> <td>13px数据</td> <td>13px数据</td> <td>13px数据</td> <td>13px数据</td> </tr> <tr class="title-small"> <td>13px标题</td> <td>13px数据</td> <td>13px数据</td> <td>13px数据</td> <td>13px数据</td> </tr> <tr class="title-small"> <td>13px标题</td> <td>13px数据</td> <td colspan="2">13px数据</td> <td>13px数据</td> </tr> <tr> <td class="title-middle">16px标题</td> <td colspan="4" class="title-small">13px数据</td> </tr> <tr> <td class="title-middle">16px标题</td> <td colspan="4" class="title-small">13px数据</td> </tr> <tr> <td class="title-middle">16px标题</td> <td colspan="4" class="title-small">13px数据</td> </tr> <tr> <td class="title-middle">16px标题</td> <td colspan="4" class="title-small">13px数据</td> </tr> <tr> <td class="title-middle">16px标题</td> <td colspan="4" class="title-small">13px数据</td> </tr> </table> </div> </body> </html>

好了这个是模版的内容,下边看一下预览效果:

 可能有些地方使用了代理,又使用了工厂模式,麻烦了,可是一个是本身练手,一个是这样子扩展性仍是不错的。使用起来也简单。

相关文章
相关标签/搜索