关于PDF嵌入背景图的实现

1 篇文章 0 订阅

因为业务需要,导出PDF时需要嵌入一张背景图,使用的技术是com.itextpdf,然后在往上苦苦搜索不可得,最后经过自己研究终于解决了该问题,所以分享给大家。

导出一张简单PDF代码

public static void main(String[] args)  throws Exception {
		Document doc = new Document();
		doc.setPageSize(PageSize.A4);//设置为A4大小
		PdfWriter pdfWriter = PdfWriter.getInstance(doc, new FileOutputStream("E:/dmeo.pdf"));
		// 设置自定义翻页
		PdfPageEvent pageEvent = new PdfPageEvent();
		pdfWriter.setPageEvent(pageEvent);
		doc.open();
		// 新页
		doc.newPage();
		// 嵌入背景图
		doc.newPage();
		// 设置背景图
		Image image = Image.getInstance("E:/bg_test.png");
		image.setAbsolutePosition(0, 0);
		image.scaleAbsolute(PageSize.A4); // A4的配置
		doc.add(image);
		// 设置上间距
		Paragraph paragraph = new Paragraph(" ");
		paragraph.setLeading(40);
		paragraph.setAlignment(Element.ALIGN_LEFT);
		doc.add(paragraph);
		// 内容
		for (int i = 0; i < 100; i++) {
			paragraph = new Paragraph("Hello World!!!");
			paragraph.setAlignment(Element.ALIGN_LEFT);
			doc.add(paragraph);
		}

		// 将缓存刷入到文件
		pdfWriter.flush();
		doc.close();
		pdfWriter.close();
		System.out.println("导出完毕");
	}

然后我们看看效果:

在这里插入图片描述
可以到,第一页背景是嵌入成功,但是第二页背景并没有嵌入,原因也很简单,因为我们只给第一页嵌入了背景图,但新的问题来了,第二页是自动生成的,这时候有可爱的小伙伴会想到在输出打印哪里每打印一次都进行一次设置背景图,首先不说效率问题,当真的去这样做的话,你会发现是行不通的,原因我就不在这里说,大家有兴趣可以跟下源码,此处不做多的赘述,直接上解决方案:
首先需要跟进

PdfWriter pdfWriter = PdfWriter.getInstance(doc, new FileOutputStream(“E:/dmeo.pdf”));

public static PdfWriter getInstance(final Document document, final OutputStream os)
    throws DocumentException {
        PdfDocument pdf = new PdfDocument();
        document.addDocListener(pdf);
        PdfWriter writer = new PdfWriter(pdf, os);
        pdf.addWriter(writer);
        return writer;
    }

PdfDocument 这个对象就是我们此次的重点,pdf的写入分页都是由这个PdfDocument 对象进行的,所以我们需要继承该对象,在其写入之后做一些事情。

public class MyPdfDocument extends PdfDocument {

	private Document document;

	private boolean isNewPage = true;

	public MyPdfDocument(Document document) {
		this.document = document;
	}

	@Override
	public boolean add(Element element) throws DocumentException {
		// 判断是否快写满了,如果是,进行换页,并设置背景图和上间距
		float currentHeight = this.currentHeight;
		if(currentHeight > (PageSize.A4.getHeight() - 200)) {
			try {
				document.newPage();
				// 设置背景图
				Image image = Image.getInstance("E:/bg_test.png");
				image.setAbsolutePosition(0, 0);
				image.scaleAbsolute(PageSize.A4); // A4的配置
				document.add(image);
				// 设置上间距
				Paragraph paragraph = new Paragraph(" ");
				paragraph.setLeading(40);
				paragraph.setAlignment(Element.ALIGN_LEFT);
				document.add(paragraph);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		boolean flag = super.add(element);
		return flag;
	}

}

当然仅仅定义了我们的PdfDocument 还不够,因为这时候你会发现,PdfWriter尽让不支持我们传入自己定义的PdfDocument ,所以我们还需要继承PdfWriter配置一个我们想要的对象

public class MyPdfWriter extends PdfWriter {

	public MyPdfWriter(final PdfDocument document, final OutputStream os) {
		super(document, os);
		pdf = document;
		directContentUnder = new PdfContentByte(this);
		directContent = directContentUnder.getDuplicate();
	}

	public static PdfWriter getInstance(final Document document, final OutputStream os)
			throws DocumentException {
		// 使用我们自己的PdfDocument 
		MyPdfDocument pdf = new MyPdfDocument(document);
		document.addDocListener(pdf);
		PdfWriter writer = new MyPdfWriter(pdf, os);
		pdf.addWriter(writer);
		return writer;
	}

}

然后还需要获取我们自己的PdfWriter

public static void main(String[] args)  throws Exception {
		Document doc = new Document();
		doc.setPageSize(PageSize.A4);
		// 获取我们自己定义的PdfWriter 
		PdfWriter pdfWriter = MyPdfWriter.getInstance(doc, new FileOutputStream("E:/dmeo.pdf"));
		// 设置自定义翻页
		PdfPageEvent pageEvent = new PdfPageEvent();
		pdfWriter.setPageEvent(pageEvent);
		doc.open();
		// 新页
		doc.newPage();
		// 嵌入背景图
		doc.newPage();
		...
}

我们来看效果:
在这里插入图片描述
以上便是该文章所有的内容

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值