因为业务需要,导出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();
...
}
我们来看效果:
以上便是该文章所有的内容