jar使用的是红色部分两个,其他的是其他的增强jar,暂时没有用到com.itextpdf itextpdf 5.5.11 com.itextpdf.tool xmlworker 5.5.11 org.freemarker freemarker 2.3.19 org.xhtmlrenderer flying-saucer-pdf 9.1.5 org.xhtmlrenderer flying-saucer-pdf-itext5 9.1.5 org.apache.velocity velocity 1.7
工具的结构
这个结构可以适用于不同的使用方式,这里我写了三种,后续有,还可以继承抽象类就可以了,下边把代码贴出来,可以参考看一下
1.接口
import java.io.OutputStream;import java.util.Map;/** * 生成pdf的接口 * 生成pdf都需要把一个字符串写成pdf文件输出到指定的地方 */public interface PDF { boolean writeToPDF(Mapdata, String htmlTmp, OutputStream out);}
2.抽象类
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(Mapdata, 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 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(Mapdata, 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 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.数据封装类
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); Mapm = new HashMap<>(); m.put("red", "红色"); try { pdf.writeToPDF(m, templateName, new FileOutputStream(new File(outPath))); } catch (FileNotFoundException e) { e.printStackTrace(); } }}
7.使用
/** * 测试报告使用 * 生成这一周的报告 * /report/handleTestReport * 这个会把pdf生成到项目到根目录下,根据需求自己调 */ @Clear public void handleTestReport() { pdfTest.test("/mail/a.html", PathKit.getWebRootPath() + pdfTest.DESTJfinal, TemplateToPDFJfinal.class); }
好了上边是所有到类
下边把基础的辅助资料写一下
字体:我把字体放到根目录下的js下了,具体看图片,根据自己的需求,我写了设置字体的方法没,可以自己设置
模版文件:我放到了根目录下的mail下了
内容是:
jfinal模板使用
20px标题
#(red)这里是取值,为了实验没有多写,只有这三个取值 #(red) #(red) 数据 数据 数据 16px二级标题 13px标题 13px数据 13px数据 13px数据 13px数据 13px标题 13px数据 13px数据 13px数据 13px数据 13px标题 13px数据 13px数据 13px数据 16px标题 13px数据 16px标题 13px数据 16px标题 13px数据 16px标题 13px数据 16px标题 13px数据
好了这个是模版的内容,下边看一下预览效果:
可能有些地方使用了代理,又使用了工厂模式,麻烦了,但是一个是自己练手,一个是这样子扩展性还是不错的。使用起来也简单。