美文网首页
JAVA笔记:itext绘制pdf矢量图

JAVA笔记:itext绘制pdf矢量图

作者: Utopi_a | 来源:发表于2016-03-11 18:10 被阅读3505次

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

    这次的问题是制作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,效果见下图:

    实现效果图.png

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

    相关文章

      网友评论

          本文标题:JAVA笔记:itext绘制pdf矢量图

          本文链接:https://www.haomeiwen.com/subject/ochxlttx.html