JAVA笔记:itext绘制pdf矢量图

好久没有更新过博客了,近期收到了一次匿名打赏和一次麦子学院的邀请,感觉还是非常有成就感的。本来是打算自己写点笔记,记录一下心境的地方,没想到还是有小小的帮助到别人,个人还是非常开心的。

这次的问题是制作pdf报表中遇到的,以前曾经也做过一些pdf报表,目前比较常见的方式主要有这样几种:

  • 使用Flying Sauser结合itext将html转换成pdf,缺点比较明显,第一是Flying Sauser对html的要求非常严格,所以制作html模板的时候是非常耗时费力的,而且效率相对也比较低。
  • 使用Adobe Acrobat,装好之后用Acrobat从一个word,excel或者pdf中转换一个pdf模板,直接写一个简单的word再生成一个pdf表单,之后编辑文本域的名字属性等,根据名字在Java中导入。这样可以很方便的实现pdf填空效率也比较高,但是缺点也是有的,对于去动态插入一些表格会相对比较麻烦。
  • 第三就是直接使用itext来实现了,灵活效率也比较高,但是就是开发会比较麻烦。

为了照顾道项目中的灵活性,所以我打算将所有要用到的一些格式和组件进行封装,以方便调整和复用。其中比较麻烦的一点就是需要在pdf中插入统计图,类似于echarts的统计图形。jfreechats是JAVA上比较常用的一套统计图工具,但是图形实在是有点丑,为了满足和与页面echart的效果相似的要求,我决定用Graphics2D来实现绘图,制作成图片导入pdf。

但是之后无意中发现itext提供绘制矢量图的api,但是中文文档太少了,我这里简单介绍一下。

import com.itextpdf.awt.PdfGraphics2D;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;

import java.awt.Graphics2D;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class LargeTemplate {    
    public static final String DEST = "results/graphics2d/large_template.pdf";    
    public static void main(String[] args) throws IOException, DocumentException { 
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new LargeTemplate().createPdf(DEST);    
}    
public void createPdf(String dest) throws IOException, DocumentException {
        float width = 602;
        float height = 15872;
        float maxHeight = 5000;
        Document document = new Document(new Rectangle(width, maxHeight));
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(DEST));
        document.open();
        PdfContentByte canvas = writer.getDirectContent();
        PdfTemplate template = canvas.createTemplate(width, height);   //绘制图形模板
        Graphics2D g2d = new PdfGraphics2D(template, width, height); //绘图接口,继承自Graphics2D
        for (int x = 10; x < width; x += 100) {
            for (int y = 10; y < height; y += 100) {
                g2d.drawString(String.format("(%s,%s)", x, y), x, y);
            }
        }
        g2d.dispose();
        int pages = ((int)height / (int)maxHeight) + 1;
        for (int p = 0; p < pages; ) {
            p++;
            canvas.addTemplate(template, 0, (p * maxHeight) - height);
            document.newPage();
        }
        document.close();
    }
}

所以其实是非常简单的,只需要实例化一个PdfGraphics2D,之后操作就见Graphics2D的api文档了,Graphics2D的文档还是比较好找的。图形的是绘制在PdfTemplate上的,这个就相当于一个图形框,图形在页面的位置就由该图形框来确定。PdfContentByte是相当于一个浮在整个pdf上面的一个透明图层,一个上层的元素容器。

我实现了一个绘制雷达图的api,效果见下图:

JAVA笔记:itext绘制pdf矢量图_第1张图片
实现效果图.png

绘制在pdf内部的一个矢量图形,放大不会失真,效果还是非常不错的,之后打算用空余时间实现一些比较漂亮的常见统计图,当做自己的一个小开源项目吧~

你可能感兴趣的:(JAVA笔记:itext绘制pdf矢量图)