打印多页文档

您已经学习了如何使用Printableinterface打印单页文档。但是,文档的 Long 度通常超过一页。 “分页”是识别文档中分页符并进行相应打印的位置的过程。

如果要打印几张图形图像(每页一张),请使用页面索引遍历这些页面并在每页上打印一张。例如,如果在以下数组中表示多个图像:

BufferedImage[] images = new BufferedImage[10];

然后使用print()方法,如以下代码片段所示:

public int print(Graphics graphics,
           PageFormat pageFormat, int pageIndex)
           throws PrinterException {

    if (pageIndex < images.length) {
        graphics.drawImage(images[pageIndex], 100, 100, null);
        return PAGE_EXISTS;
    } else {
        return NO_SUCH_PAGE:
    }
}

如果文档是连续的,则应用程序必须计算每个页面上可以容纳多少内容,然后在该位置分页。如果文本文档由多行组成,则应用程序必须计算出其中的几行可以完全适合页面。 Point类创建一个表示(x,y)中位置的点

要计算单行文本的高度,请使用FontMetrics类。

Font font = new Font("Serif", Font.PLAIN, 10);
FontMetrics metrics = graphics.getFontMetrics(font);
int lineHeight = metrics.getHeight();

PageFormat参数描述页面的可打印区域。特别是,要查找页面的垂直 Span,请使用以下代码片段:

double pageHeight = pageFormat.getImageableHeight();

使用以下代码片段计算适合页面的行数和分页符数:

int linesPerPage = ((int)pageHeight)/lineHeight);
int numBreaks = (textLines.length-1)/linesPerPage;
int[] pageBreaks = new int[numBreaks];
for (int b=0; b < numBreaks; b++) {
    pageBreaks[b] = (b+1)*linesPerPage; 
}

由于以下原因,使用print()方法来计算可打印区域:

  • 文本度量取决于FontRenderContext,并且隐含在打印机图形返回的FontMetrics对象中,该对象只能在print()方法内部使用。

  • 在打印之前,可能不会公开页面格式。由于如果用户在打印对话框中选择了横向 Pattern,则需要考虑此设置。传递给print()方法的PageFormat对象提供了此信息。

分页符的位置如以下代码片段所示:

/* Draw each line that is on this page.
 * Increment 'y' position by lineHeight
 * for each line.
 */
int y = 0; 
int start = (pageIndex == 0) ? 0 : pageBreaks[pageIndex-1];
int end   = (pageIndex == pageBreaks.length)
                 ? textLines.length : pageBreaks[pageIndex];
for (int line=start; line<end; line++) {
    y += lineHeight;
    g.drawString(textLines[line], 0, y);
}

如果文档包含 100 行,而一个页面上只能容纳 48 行,则应用程序将打印 3 页,并在 48 行和 96 行文本之后显示分页符。其余 4 行打印在最后一页上。此示例的完整代码在PaginationExample.java中。

PaginationExample代码中使用以下简化因素:

  • 每页具有相同的高度。

  • 使用相同的字体。