itext 5.5.7包含页眉和页脚的标记PDF的错误读取顺序

时间:2015-09-23 06:44:07

标签: java pdf-generation itext

在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);

    }
}

0 个答案:

没有答案