Java 生成各种 PDF 实战方案(图片、模板、表格)

本篇文章的重点还是在讲通过java生成pdf,其实如果是单纯的模板填充挺简单的,但是又要填充模板还要动态生成表格就比较麻烦了,因为如果在模板中画表格的框去生成的话,超过模板框的位置就会隐藏,我刚接到需求的时候也是有点难受,在网上也是找了大量的资料,研究了半天,发现好多都是你粘贴我,我粘贴你,最终我也算是搞成了,把这些整合一下,让大家用的好用一些,废话不多说,直接上代码!

这里说一下啊,如果需要生成echarts图片,先去看我的生成echarts图片文章,不然这个搞不了。

模板链接,我把他放到网盘了,需要的可以去下载:

https://pan.baidu.com/s/1YJZtLdiySxUry4h2Gd1V7g 提取码:j1l5

一、pom依赖

首先先引入咱们需要的pom依赖,我这里只粘贴pdf的吧,lombok和hutool经常用我就不粘贴了。

<dependency>
  <groupId>com.itextpdf</groupId>
      <artifactId>itextpdf</artifactId>
      <version>5.5.9</version>
  </dependency>
  <dependency>
      <groupId>com.itextpdf</groupId>
      <artifactId>itext-asian</artifactId>
      <version>5.2.0</version> 
</dependency>

二、生成pdf,模板和图片及动态生成表格

我这个没有搞页眉,只搞了页脚,设置页眉/页脚和水印的类我会在最后粘贴出来,因为这几个案例用的都是一个配置类。

实体类

package com.example.demo.domain;

import lombok.Data;
import lombok.experimental.Accessors;

import java.math.BigDecimal;

@Data
@Accessors(chain = true)
public class DuizhangDomain {
    private String jg;
    private Integer ydz;
    private Integer wdz;
    private BigDecimal dzl;
}
package com.example.demo.domain;

import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
@Data
@Accessors(chain = true)
public class YqTable implements Serializable {
    private String jg;
    private Integer yqs;
}

生成pdf代码

import cn.hutool.core.date.DateUtil;
import com.example.demo.domain.DuizhangDomain;
import com.example.demo.domain.YqTable;
import com.example.demo.pdf.phantom.App;
import com.example.demo.pdf.phantom.PageEvent;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import freemarker.template.TemplateException;
import org.springframework.core.io.ClassPathResource;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
 * 根据模板填充数据及图片,动态生成数据列表
 */
public class CreatePdfEchrtsAndTableMain2 {

    private final static String TITLE = "这个是标题,可有可无";
    public void createPdfFile(HttpServletResponse response) throws IOException, DocumentException, TemplateException {
        //设置请求返回类型
        response.setHeader("Content-Disposition", "attachment; filename=测试.pdf");
        OutputStream outputStream = response.getOutputStream();
        //模板路径,放到项目里用这个ClassPathResource
        ClassPathResource classPathResource = new ClassPathResource("templates/test1.pdf");
        InputStream inputStream = classPathResource.getInputStream();

        PdfReader reader = new PdfReader(inputStream);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        PdfStamper ps = new PdfStamper(reader, bos);

        //设置字体
        final BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
        ArrayList<BaseFont> fontList = new ArrayList<>();
        fontList.add(font);

        //提取表单,这个是模板画好的文本框
        AcroFields s = ps.getAcroFields();
        s.setSubstitutionFonts(fontList);

        s.setFieldProperty("jrfk","textfont",font,null);
        s.setFieldProperty("bjzs","textfont",font,null);
        s.setFieldProperty("type","textfont",font,null);
        s.setFieldProperty("createTime","textfont",font,null);
        s.setFieldProperty("title","textfont",font,null);
        s.setField("jrfk","10");
        s.setField("bjzs","20");
        s.setField("type","日报");
        s.setField("createTime", DateUtil.now());
        s.setField("title", TITLE);



        //添加图片
        PdfContentByte cb = ps.getOverContent(1);
        //添加logo
        Rectangle logo = s.getFieldPositions("logo").get(0).position;
        Image logoImage = Image.getInstance("https://img1.baidu.com/it/u=3646261857,3326755268&fm=253&app=138&size=w931&n=0&f=JPG&fmt=auto?sec=1668186000&t=20050fc88fc3feb1f9d28392f4595ec6");
        //根据域的大小缩放图片,我这里宽度在原有的域基础上加了100,你们可以自己调节
        logoImage.scaleToFit(logo.getWidth() + 100,logo.getHeight());
        logoImage.setAlignment(Image.MIDDLE);
        logoImage.setAbsolutePosition(logo.getLeft(),logo.getBottom());
        cb.addImage(logoImage);

        //获取统计图
        //获取域
        Rectangle rlt = s.getFieldPositions("rlt").get(0).position;
        //热力图
        Image rltImage = Image.getInstance("https://img0.baidu.com/it/u=4043177345,1055141017&fm=253&app=138&size=w931&n=0&f=PNG&fmt=auto?sec=1668186000&t=8cfdc5c95cc0070eb91946d780ee8dc3");
        //根据域大小设置缩放图片
        rltImage.scaleToFit(rlt.getWidth() + 100,rlt.getHeight());
        // 设置居中
        rltImage.setAlignment(Image.MIDDLE);
        //绝对定位
        rltImage.setAbsolutePosition(rlt.getLeft(),rlt.getBottom());
        //图片旋转,这个可以将图片进行一个旋转,看自己需求
//        rltImage.setRotationDegrees(90);
        cb.addImage(rltImage);


        //按机构统计图
       //这个是生成echarts的类,如果需要生成echarts可以去看我的另一个文章,上面前言已经提到了
        App app1 = new App();
        byte[] echarts1 = app1.createEcharts("ajg.ftl");
        Image ajgImage = Image.getInstance(echarts1);
        Rectangle ajg = s.getFieldPositions("ajg").get(0).position;
        // 根据域大小设置缩放图片
        ajgImage.scaleToFit(ajg.getWidth(),400);
        // 设置居中
        ajgImage.setAlignment(Image.MIDDLE);
        // 绝对定位
        ajgImage.setAbsolutePosition(ajg.getLeft(),ajg.getBottom());
        cb.addImage(ajgImage);
        //按机构排名,这个是在图片的基础上还要添加数据,这个模板可以画好
        for (int i = 1; i <= 3; i++) {
            s.setFieldProperty("ajg" + i,"textfont",font,null);
            s.setField("ajg" + i,"机构" + i);
        }
        App app = new App();
        byte[] echarts = app.createEcharts("option.ftl");
        //按业务
        Rectangle ayw = s.getFieldPositi
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

python小小Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值