使用itextpdf+XMLWorkerHelper+velocity使用模板生成pdf

公司最近要生成一个pdf,最开始的想法是直接使用前端渲染,这样好处是带有样式,而且好看,,而且按道理说,直接使用pdfdebug.js渲染会简单很多,结果网上 抄写了一个,,发现各种问题兼容的问题。。。本人一个后端,调试了半天,真的是无语,,谷歌渲染不上echarts在某个版本中,,而且还存在不同电脑上,,清晰度不同的问题,,,无语了,,而且还不支持ie。。。。。结果麻油办法,,只好换成后端生成pdf了,,后端生成pdf的好处就是不用调试兼容性的问题。。。爽歪歪,,不想在搞浏览器兼容问题的首选。

1、先初始化velocity,我们公司使用的gbk,所以这里是gbk。。。
private static boolean init() {
VELOCITY_CONTEXT.put(“input.encoding”, “GBK”);
VELOCITY_CONTEXT.put(“output.encoding”, “GBK”);
VELOCITY_CONTEXT.put(“resource.loader”, “file”);
VELOCITY_CONTEXT.put(“file.resource.loader.class”,
“org.apache.velocity.runtime.resource.loader.FileResourceLoader”);
VELOCITY_CONTEXT.put(“file.resource.loader.cache”, “true”);
VELOCITY_CONTEXT.put(“file.resource.loader.path”, “E:/workSpace/aaa/WebRoot/WEB-INF”);//设置模板加载的路径。。
try {
Velocity.init(VELOCITY_CONTEXT);
} catch (Exception e) {
return false;
}
return true;
}

2、获取html模板,,然后拿出来,,然后渲染,,,但是有个问题噢,,不太支持字体,,还有一些css的样式。。
private ByteArrayOutputStream createTemplate(String templatePath, Object pdfData) {
// 取得velocity上下文
VelocityContext context = new VelocityContext();
context.put(“data”, pdfData);
StringWriter writer = new StringWriter();
try {
Template template = Velocity.getTemplate(templatePath, Charset.defaultCharset().name());
template.merge(context, writer);
} catch (Exception e) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintWriter filewriter = new PrintWriter(baos, true);
filewriter.println(writer.toString());
filewriter.close();
return baos;
}

其中templatePath,直接写放在1步骤目录下的html文件即可。pdfData就是Map。。。。里面存放各种渲染在html上的数据

3、 获取到html的输出流
ByteArrayOutputStream templateOutputStream =createTemplate(templatePath, pdfData);
// 2.使用itext创建PDF
byte[] temp = new String(templateOutputStream.toByteArray(), Charset.defaultCharset().name()).getBytes(“UTF-8”);

   ByteArrayInputStream templateInputStream = new ByteArrayInputStream(temp);

    createPDF(templateInputStream, outputStream);

4、
private void createPDF(InputStream templateInputStream, OutputStream pdfOutStream) throws IOException, DocumentException {
Rectangle rectangle = PageSize.A4;
rectangle = PageSize.A4.rotate();
Document document = new Document(rectangle);
PdfWriter writer = PdfWriter.getInstance(document, pdfOutStream);
document.open();
XMLWorkerHelper.getInstance().parseXHtml(writer, document, templateInputStream,XMLWorkerHelper.class.getResourceAsStream("/default.css"), Charset.forName(“UTF-8”),new myfont());
document.close();
}

html模板:
<!doctype html>

aaa img src="$data.src" 就是一个普通的img标签。。。这博客显示不出来 ${data.ddd}

使用velocity的语法${data.ddd}赋值,可以自行百度。。。跟html一样,但是有些样式不支持。
其中我使用了两种字体simhei,SimSun,因此在createpdf里面我加了一个自定义font类myfont,,一般SimSun是自带有的,所以我加了simhei的字体,所有的字体都得自己加,,

public class myfont extends XMLWorkerFontProvider {

private Logger log = Logger.getLogger(myfont.class);

@Override
public Font getFont(final String fontname, final String encoding,
                    final boolean embedded, final float size, final int style,
                    final BaseColor color) {
    BaseFont bf = null;
    try {
        String url = "c:\\windows\\fonts\\simhei.ttf";
        String os = System.getProperties().getProperty("os.name");
        if (os != null && os.toLowerCase().indexOf("linux") > -1) {//linux
            url = "/usr/share/fonts/simhei.ttf";
        }
        if(fontname.equals("simhei")){
            bf = BaseFont.createFont(url,BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
        }else{
           return super.getFont(fontname, encoding, size, style);
        }
    } catch (DocumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    Font font = new Font(bf, 16, style, color);
    font.setColor(color);
    return font;
}

其中我还需要引入一个图片,但是发现老是引入不上去。。最后调试了好久,终于引入上去了src="$data.src" 语法是跟普通的赋值是不一样的。
pdfData 就是一个Map map = new HashMap();
map.put(“src”,“e://23123131.jpg”);
map.put(“ddd”,“hahahah”);

设置字体大小 Font font = new Font(bf, 16, style, color);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值