创建PDF文档,页眉页脚是必不可少的一环,页面页脚的作用一般是会存放一些固定的信息,例如当前页面的章节名称,公司logo,页码等等,我这里以下图为例:
位置: 1 : 显示当前页面的所在的版块名称,例如一本书的第几章等
2: 显示当前的用户名或作者之类
3:logo图片
4:当前页码
一、事件
页眉页脚在每一页的布局和逻辑都是一致,除了页码需要跟着页面变动而改变。在itext7 提供了事件出来的方式。代码如下
pdfDoc.addEventHandler(type,IEventHandler);
参数:type : 事件的类型,有四种分别是PdfDocumentEvent.END_PAGE ;PdfDocumentEvent.START_PAGE;PdfDocumentEvent.INSERT_PAGE;PdfDocumentEvent.REMOVE_PAGE。
看名称就是知道分别代表都是页面完成,开始,插入,移除时触发事件
IEventHandler : 触发的事件具体代码,需要自己编写一个类,并实现接口IEventHandler
二、具体代码
1、实现接口IEventHandler的类DemoHeaderFooterHandler.java
public class DemoHeaderFooterHandler implements IEventHandler {private final String imgLogo;private final PdfFont font;public DemoHeaderFooterHandler(final String imgLogo, final PdfFont font) {this.imgLogo = imgLogo;this.font = font;}@Overridepublic void handleEvent(final Event event) {try {final PdfDocumentEvent docEvent = (PdfDocumentEvent) event;final PdfDocument pdfDoc = docEvent.getDocument();final Document doc = new Document(pdfDoc);final PdfPage page = docEvent.getPage();final int pageNumber = pdfDoc.getPageNumber(page);final Rectangle pageSize = page.getPageSize();final float pdfWidth = pageSize.getWidth();final float pdfHeight = pageSize.getHeight();final PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDoc);final Color lineColor = new DeviceRgb(57, 123, 198);pdfCanvas.setLineWidth(1.5f).setStrokeColor(lineColor);final float tableWidth = pdfWidth - doc.getRightMargin() - doc.getLeftMargin();// 页眉final float x0 = doc.getRightMargin(), y0 = pdfHeight - doc.getTopMargin();pdfCanvas.moveTo(x0, y0).lineTo(pdfWidth - doc.getRightMargin(), y0).stroke();final Table headerTable = new Table(2);headerTable.setHeight(30);headerTable.setFixedLayout();headerTable.setWidth(tableWidth);headerTable.setHorizontalAlignment(HorizontalAlignment.CENTER);final Paragraph pageNameParagraph = new Paragraph();// realnameParagraph.setFixedLeading(4f);pageNameParagraph.setVerticalAlignment(VerticalAlignment.BOTTOM);pageNameParagraph.add("页面名称");final Cell pageNameCell = new Cell();pageNameCell.setBorder(Border.NO_BORDER);pageNameCell.add(pageNameParagraph);pageNameCell.setFont(this.font);pageNameCell.setFontSize(12f);pageNameCell.setFontColor(lineColor);pageNameCell.setVerticalAlignment(VerticalAlignment.BOTTOM);headerTable.addCell(pageNameCell);final Paragraph realnameParagraph = new Paragraph();// realnameParagraph.setFixedLeading(4f);realnameParagraph.setVerticalAlignment(VerticalAlignment.BOTTOM);realnameParagraph.add(new Tab()).addTabStops(new TabStop(1000, TabAlignment.RIGHT));realnameParagraph.add("半路凉亭");final Cell realnameCell = new Cell();realnameCell.setBorder(Border.NO_BORDER);realnameCell.add(realnameParagraph);realnameCell.setFont(this.font);realnameCell.setFontSize(12f);realnameCell.setFontColor(lineColor);realnameCell.setVerticalAlignment(VerticalAlignment.BOTTOM);headerTable.addCell(realnameCell);headerTable.setFixedPosition(doc.getLeftMargin(), pdfHeight - doc.getTopMargin(), tableWidth);doc.add(headerTable);// 页脚pdfCanvas.moveTo(x0, doc.getBottomMargin()).lineTo(pdfWidth - doc.getRightMargin(), doc.getBottomMargin()).stroke();final Table table = new Table(2);table.setHeight(40);table.setFixedLayout();table.setWidth(tableWidth);table.setHorizontalAlignment(HorizontalAlignment.CENTER);final Cell imgCell = new Cell();imgCell.setBorder(Border.NO_BORDER);imgCell.add(this.getLogoImage());imgCell.setVerticalAlignment(VerticalAlignment.TOP);table.addCell(imgCell);final String pageNo = String.format("%d", pageNumber);final Paragraph pageNoParagraph = new Paragraph();pageNoParagraph.setFontColor(new DeviceRgb(166, 166, 166));pageNoParagraph.setFontSize(12f);pageNoParagraph.add(new Tab()).addTabStops(new TabStop(1000, TabAlignment.RIGHT));pageNoParagraph.add(pageNo);table.addCell(new Cell().add(pageNoParagraph).setBorder(Border.NO_BORDER));table.setFixedPosition(doc.getLeftMargin(), doc.getBottomMargin() - table.getHeight().getValue(),tableWidth);doc.add(table);System.out.println("***" + table.getHeight());} catch (final Exception e) {e.printStackTrace();throw new NormStarRuntimeException("页脚异常" + e.getMessage());}}private Image getLogoImage() {Image image;try {image = new Image(ImageDataFactory.create(this.imgLogo));image.scaleToFit(75, 100);} catch (final MalformedURLException e) {final String errorMessage = "logo图片";throw new NormStarRuntimeException(errorMessage, e);}return image;}}
2、生成文档的代码
private final String fileImg = "D:/itext-pdf/logo.png";public PdfFont getSongTiFont() throws IOException {return PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", false);}public PdfFont getHeiTiFont() throws IOException {return PdfFontFactory.createFont("D:/itext-pdf/font/heiti.TTF", PdfEncodings.IDENTITY_H,false);}/*** 页眉页脚** @author * @date 3月29日*/@Testpublic void testHeaderFooter() {final File file = new File("D:/itext-pdf/001.pdf");Document doc = null;try {final PdfFont font = this.getSongTiFont();final PdfWriter writer = new PdfWriter(file);final PdfDocument pdfDoc = new PdfDocument(writer);doc = new Document(pdfDoc);final Image img = new Image(ImageDataFactory.create(this.fileImg));img.setHeight(new UnitValue(UnitValue.POINT, 35f));img.setWidth(new UnitValue(UnitValue.POINT, 100f));doc.setMargins(50, 60, 50, 60);pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE,new DemoHeaderFooterHandler(this.fileImg, this.getHeiTiFont()));pdfDoc.addNewPage();final int number = pdfDoc.getNumberOfPages();final float pdfWidth = pdfDoc.getPage(number).getPageSize().getWidth();final float pdfHeight = pdfDoc.getPage(number).getPageSize().getHeight();final Paragraph paragraph = new Paragraph("你好 itext-pdf");paragraph.add("第" + number + "页");paragraph.add("宽:" + pdfWidth + " 高:" + pdfHeight); // 宽:595.0 高:842.0paragraph.setFont(font);paragraph.add(img);doc.add(paragraph);// PdfContentByte cb = writer.getDirectContent();final PdfOutline root = pdfDoc.getOutlines(true);final String title = String.format("Numbers from %s to %s", 1, 10);final Text c = new Text(title);//final TOCTextRenderer renderer = new TOCTextRenderer(root, c);//c.setNextRenderer(renderer);doc.add(new Paragraph(c));pdfDoc.addNewPage();System.out.println("***" + root.getTitle());} catch (final Exception e) {e.printStackTrace();final String errorMessage = "异常";throw new NormStarRuntimeException(errorMessage, e);} finally {if (doc != null) {doc.close();}}}
注意:
1.中文字体问题
页尾页脚中如果有中文字体,则必须使用外部嵌入的字体,如我这里嵌入的黑体,使用默认的宋体,则会报错
2.表格绝对坐标定位
setFixedPosition(); 使用这个方法写入表格时,是以表格的左下角为坐标原点定位的。