package com.company.common.core.utils.itext;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import lombok.SneakyThrows;
import java.io.IOException;
/**
* pdf的页眉页脚设置
*
* @author kally
* @date 2022/8/26
*/
public class PdfHeaderFooter extends PdfPageEventHelper {
/**
* 总页数
*/
PdfTemplate totalPage;
/**
* 字体
*/
Font hfFont;
{
try {
hfFont = new Font(BaseFont.createFont("font/msyh.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED), 10);
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 打开文档时,创建一个总页数的模版
*/
@Override
public void onOpenDocument(PdfWriter writer, Document document) {
PdfContentByte cb = writer.getDirectContent();
// 共n页的宽高
totalPage = cb.createTemplate(50, 14);
}
/**
* 一页加载完成触发,写入页眉和页脚
*/
@SneakyThrows
@Override
public void onEndPage(PdfWriter writer, Document document) {
// 首页 不加分页内容
int currentPage = 0;
if (document.getPageNumber() == 1) {
return;
} else {
currentPage = document.getPageNumber() - 1;
}
// 创建一个两列的表格
PdfPTable table = new PdfPTable(2);
try {
// 总宽度为A4纸张宽度
table.setTotalWidth(PageSize.A4.getWidth());
// 锁定列宽
table.setLockedWidth(true);
// 设置每列宽度
table.setWidths(new int[]{50, 50});
PdfPCell cell = new PdfPCell(new Phrase("第" + currentPage + "页/", hfFont));
// 设置水平右对齐
cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
// 设置垂直居中
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
// 隐藏全部边框
cell.disableBorderSide(15);
table.addCell(cell);
// 共x页
Image totalPageImage = Image.getInstance(totalPage);
totalPageImage.setPaddingTop(-10f);
PdfPCell cell1 = new PdfPCell(totalPageImage);
// 设置水平左对齐
cell1.setHorizontalAlignment(Element.ALIGN_LEFT);
// 设置垂直居中
cell1.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell1.disableBorderSide(15);
table.addCell(cell1);
table.writeSelectedRows(0, -1, 0, 50, writer.getDirectContent());
} catch (Exception e) {
throw new ExceptionConverter(e);
}
// 生成左侧页眉
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_LEFT, new Paragraph("***科技有限公司", hfFont),
document.left(), PageSize.A4.getHeight() - 26, 0);
// 生成右侧页眉
ColumnText.showTextAligned(writer.getDirectContent(),
Element.ALIGN_RIGHT, new Paragraph("巡检缺陷识别分析报告", hfFont),
document.right(), PageSize.A4.getHeight() - 26, 0);
// 页眉加下划线
PdfPTable tableHeader = new PdfPTable(1);
tableHeader.setTotalWidth(PageSize.A4.getWidth() - 60);
PdfPCell pCell = new PdfPCell();
pCell.setBorderWidthBottom(0.3f);
tableHeader.addCell(pCell);
// 表格的第一行坐标【x=40;y=734】
tableHeader.writeSelectedRows(0, -1, 30, 814, writer.getDirectContent());
// 页面加水印
PdfContentByte waterMar = writer.getDirectContentUnder();
addWaterMar(waterMar);
}
/**
* 全部完成后,将总页数的pdf模版写到指定位置
*/
@Override
public void onCloseDocument(PdfWriter writer, Document document) {
int total = writer.getPageNumber() - 1;
String text = "共" + total + "页";
ColumnText.showTextAligned(totalPage, Element.ALIGN_MIDDLE, new Paragraph(text, hfFont), 0, 3, 0);
}
/**
* 加水印
*
* @param waterMar {@link Document}
* @throws DocumentException
*/
private void addWaterMar(PdfContentByte waterMar) throws DocumentException {
try {
// 开始设置水印
waterMar.beginText();
// 设置水印透明度
PdfGState gs = new PdfGState();
// 设置填充字体不透明度为0.4f
gs.setFillOpacity(0.2f);
// 设置水印字体参数及大小(字体参数,字体编码格式,是否将字体信息嵌入到pdf中(一般不需要嵌入),字体大小)
waterMar.setFontAndSize(BaseFont.createFont("font/msyh.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED), 120);
// 设置透明度
waterMar.setGState(gs);
// 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度
waterMar.showTextAligned(Element.ALIGN_CENTER, "水印水印", 300, 400, 48);
// 设置水印颜色
waterMar.setColorFill(BaseColor.GRAY);
//结束设置
waterMar.endText();
waterMar.stroke();
} catch (IOException e) {
e.printStackTrace();
}
}
}
问题点汇总:
1、页眉加下划线—表格的第一行坐标【x=40;y=734】
根据下划线的坐标位置动态调整
tableHeader.writeSelectedRows(0, -1, 30, 814, writer.getDirectContent());
2、页脚;共n页
根据共n页的坐标位置动态调整
ColumnText.showTextAligned(totalPage, Element.ALIGN_MIDDLE, new Paragraph(text, hfFont), 0, 3, 0);
3、引用
PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream(pdfFile)); // 添加页眉/页脚/水印 pdfWriter.setPageEvent(new PdfHeaderFooter());