简体   繁体   中英

Java printing. Prints only one page when using `Book` class

I use Book class to provide different orientation to pages when printing PDF document.

But when I use Book class prints only first page. Other pages doesn't printing. But Book#getNumberOfPages return me 4 .

My code looks like this:

   public static getDoc(DocAttributeSet dset) {
        final PDFFile pdfFile = new PDFFile(buf);
            Book book = new Book();
            for (int i=0; i<pdfFile.getNumPages(); i++) {
                PDFPage page = pdfFile.getPage(i);
                PageFormat pageFormat =  new PageFormat();

                if (page.getAspectRatio() >= 1) {
                    pageFormat.setOrientation(PageFormat.LANDSCAPE);
                } else {
                    pageFormat.setOrientation(PageFormat.PORTRAIT);
                }
                boolean needStop = false;
                if (pdfFile.getNumPages() - 1 == i ) { // if latest page, then stopping ('needStop' = NO_SUCH_PAGE)
                    needStop = true;
                }
                book.append(getPrintable(page, needStop), pageFormat);
            }
          return new SimpleDoc(book, DocFlavor.SERVICE_FORMATTED.PAGEABLE, dset);
      }    

    private static Printable getPrintable(final PDFPage page, final boolean needStop) {
            return new Printable() {
                public int print(Graphics g, PageFormat pageFormat, int index) throws PrinterException {
                    if (needStop) {
                        return NO_SUCH_PAGE;
                    }

                    // no scaling, center PDF
                    ... // code omitted

                    return PAGE_EXISTS;

                }
            };
    }

Please note : I'm use this code to print document:

DocPrintJob job = prn.createPrintJob();
job.print(myDoc, aset);

ie I not use old API:

Book bk = new Book();       
job.setPageable(bk);    

解决方案是在“书”中放置要打印的最大页数,可能是3或10,这并不意味着它将全部打印10张,仅标记书的大小:

book.append(getPrintable(page, needStop), pageFormat, numPages);

This is the test code I put together...

It doesn't print PDF's but test's the change in page orientation and page count.

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import static java.awt.print.Printable.NO_SUCH_PAGE;
import static java.awt.print.Printable.PAGE_EXISTS;
import java.awt.print.PrinterException;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.DocAttributeSet;
import javax.print.attribute.HashDocAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;

public class TestBook {

    public static void main(String[] args) {
        DocFlavor psInFormat = DocFlavor.INPUT_STREAM.AUTOSENSE;

        HashDocAttributeSet docAttSet = new HashDocAttributeSet();
        Doc myDoc = getDoc(docAttSet);
        PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
        PrintService[] services = PrintServiceLookup.lookupPrintServices(psInFormat, aset);

        // this step is necessary because I have several printers configured  
        PrintService myPrinter = null;
        for (int i = 0; i < services.length; i++) {
            String svcName = services[i].toString();
            System.out.println("service found: " + svcName);
            if (svcName.contains("DocuCentre-III C3100")) {
                myPrinter = services[i];
                System.out.println("my printer found: " + svcName);
                break;
            }
        }

        if (myPrinter != null) {
            DocPrintJob job = myPrinter.createPrintJob();
            try {
                job.print(myDoc, aset);

            } catch (Exception pe) {
                pe.printStackTrace();
            }
        } else {
            System.out.println("no printer services found");
        }
    }

    public static SimpleDoc getDoc(DocAttributeSet dset) {
        Book book = new Book();
        for (int i = 0; i < 4; i++) {
            PageFormat pageFormat = new PageFormat();

            if (i % 2 == 0) {
                pageFormat.setOrientation(PageFormat.LANDSCAPE);
            } else {
                pageFormat.setOrientation(PageFormat.PORTRAIT);
            }
            boolean needStop = false;
            if (3 == i) { // 'needStop' = NO_SUCH_PAGE
                needStop = true;
            }
            book.append(getPrintable(i, needStop), pageFormat);
        }
        System.out.println("Book = " + book.getNumberOfPages());
        return new SimpleDoc(book, DocFlavor.SERVICE_FORMATTED.PAGEABLE, dset);
    }

    private static Printable getPrintable(int page, boolean needStop) {
        return new MyPage(page, needStop);
    }

    public static class MyPage implements Printable {

        private int page;
        private boolean needStop;

        public MyPage(int page, boolean needStop) {
            this.page = page;
            this.needStop = needStop;
        }

        public int print(Graphics g, PageFormat pageFormat, int index) throws PrinterException {
            g.translate((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY());
            System.out.println("Printing " + page);
            Font font = new Font("Arial", Font.BOLD, 128);
            g.setColor(Color.BLACK);
            g.setFont(font);
            g.drawString(String.valueOf(index), 0, g.getFontMetrics().getAscent());

//            if (needStop) {
//                return NO_SUCH_PAGE;
//            }
            return PAGE_EXISTS;

        }
    }
}

From the looks of it, your needStop was misplaced. This should only be called when no more pages actually need to be printed, but the way I read your code (and I could be wrong) it seemed to want to skip the last page.

However, after testing, it would seem you don't actually need it (as the Book knows how many pages it wants to print ;))

You should implement print() method of Printable like this:

@Override
public int print(Graphics g, PageFormat pf, int pageNumber)
        throws PrinterException {
    if (pageNumber < book.getNumberOfPages()) {
        // Printing code here

        return PAGE_EXISTS;
    }
    return NO_SUCH_PAGE;
}

For this, you must have reference to your book instance which can be achieved by making a inner class Page implementing Printable interface with the above print() method definition.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM