在itext 5.5.7中,我发现包含页眉和页脚的标记PDF的读取顺序不正确。
包含页眉和页脚的标记PDF具有以下结构:
文档 页面内容 标题 页脚
并阅读并以相同的顺序阅读。
不正确:标签排序应为页眉/页面内容/页脚。
来源:
package pdf;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
public class ReportPdf {
private Random random = new Random();
private Font font = new Font(Font.FontFamily.COURIER, 11);
public static void main(String[] args) {
ReportPdf report = new ReportPdf();
try {
String fileName = "report.pdf";
report.generatePdf(fileName);
} catch (FileNotFoundException e) {
System.err.println(e);
} catch (DocumentException e) {
System.err.println(e);
}
}
private void generatePdf(String fileName) throws DocumentException, FileNotFoundException {
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(fileName));
writer.setPdfVersion(PdfWriter.VERSION_1_7);
writer.setViewerPreferences(PdfWriter.DisplayDocTitle);
writer.setTagged();
writer.createXmpMetadata();
document.setMargins(10, 10, 60, 10);
document.open();
final PdfPageHeader header = new PdfPageHeader(writer, 10) {
public PdfPTable createTable(int pageNumber, Image total) {
PdfPTable table = new PdfPTable(3);
table.setTotalWidth(500);
table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
table.addCell(new Phrase("Header"));
table.addCell(new Phrase(String.format("Page %d of ", pageNumber)));
PdfPCell pageTotal = new PdfPCell(total);
pageTotal.setBorder(Rectangle.NO_BORDER);
table.addCell(pageTotal);
return table;
}
};
writer.setPageEvent(header);
document.add(createContent());
document.close();
}
private PdfPTable createContent() {
PdfPTable table = new PdfPTable(4);
table.setHeaderRows(1);
table.setWidthPercentage(100f);
for (int i = 1; i <= 4; i++) {
table.addCell(new PdfPCell(new Phrase("#" + i)));
}
for (int i = 0; i < 200; i++) {
fillRow(table);
}
return table;
}
private void fillRow(PdfPTable table) {
for (int j = 0; j < 3; j++) {
Phrase phrase = new Phrase(String.valueOf(random.nextInt()), font);
PdfPCell cell = new PdfPCell(phrase);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);
}
}
public abstract class PdfPageHeader extends PdfPageEventHelper {
private final float marginTop;
private List<PdfTemplate> templates = new ArrayList<PdfTemplate>();
public PdfPageHeader(final PdfWriter writer, final float marginTop) {
this.marginTop = marginTop;
}
public void onEndPage(final PdfWriter writer, final Document document) {
Rectangle rect = document.getPageSize();
PdfTemplate template = writer.getDirectContent().createTemplate(20, 16);
Image total = null;
try {
total = Image.getInstance(template);
} catch (BadElementException e) {
e.printStackTrace();
}
total.setAccessibleAttribute(PdfName.ALT, new PdfString("Total"));
templates.add(template);
PdfPTable table = createTable(writer.getPageNumber(), total);
if (table != null) {
PdfPTableHeader header = new PdfPTableHeader();
PdfPTableBody tbody = table.getBody();
PdfContentByte canvas = writer.getDirectContent();
PdfContentByte[] canvases = new PdfContentByte[]{canvas,
canvas.getDuplicate(), canvas.getDuplicate(),
canvas.getDuplicate()};
canvases[PdfPTable.TEXTCANVAS].openMCBlock(table);
canvases[PdfPTable.TEXTCANVAS].openMCBlock(header);
canvases[PdfPTable.TEXTCANVAS].closeMCBlock(header);
canvases[PdfPTable.TEXTCANVAS].openMCBlock(tbody);
table.writeSelectedRows(0, -1, document.leftMargin(),
rect.getTop(marginTop), writer.getDirectContent());
canvases[PdfPTable.TEXTCANVAS].closeMCBlock(tbody);
canvases[PdfPTable.TEXTCANVAS].closeMCBlock(table);
}
}
public void onCloseDocument(final PdfWriter writer, final Document document) {
Font font = new Font(Font.FontFamily.COURIER, 15);
Phrase phrase = new Phrase(String.valueOf(writer.getPageNumber() - 1), font);
for (PdfTemplate template : templates) {
ColumnText.showTextAligned(template, Element.ALIGN_LEFT, phrase, 2, 2, 0);
}
}
public abstract PdfPTable createTable(final int pageNumber, final Image total);
}
}