【问题标题】:Java printing. Prints only one page when using `Book` classJava 打印。使用 `Book` 类时只打印一页
【发布时间】:2013-04-16 05:47:16
【问题描述】:

我使用Book 类在打印 PDF 文档时为页面提供不同的方向。

但是当我使用 Book 类时,只打印第一页。其他页面不打印。但是Book#getNumberOfPages 回复我4

我的代码如下所示:

   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;

                }
            };
    }

请注意:我使用此代码打印文档:

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

即我不使用旧 API:

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

【问题讨论】:

  • 我不明白您为什么要进行如此扩展,而您可以简单地 new SimpleDoc(psStream, DocFlavor.INPUT_STREAM.AUTOSENSE, null); 其中psStream 是您的 PDF 文件的 InputStream
  • @MadProgrammer 因为并非所有打印机都支持 PDF 格式。所以我将PDF文件转换为图像并将其打印为图像。我认为问题与PAGE_EXISTSNO_SUCH_PAGE 有关...使用Book 时我需要如何返回PAGE_EXISTSNO_SUCH_PAGE?我的用法对吗?
  • 使用像这里这样的可打印书籍:stackoverflow.com/a/4256155/2382406

标签: java printing


【解决方案1】:

解决办法是在“书”中放置最大打印页数,可能是 3 或 10,这并不意味着它会打印所有 10,只标记书的大小:

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

【讨论】:

    【解决方案2】:

    这是我整理的测试代码……

    它不打印 PDF,而是测试页面方向和页数的变化。

    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;
    
            }
        }
    }
    

    从外观上看,您的needStop 放错了位置。仅当实际上不需要打印更多页面时才应调用此方法,但我阅读您的代码的方式(我可能是错的)似乎想跳过最后一页。

    但是,经过测试,您似乎并不需要它(因为Book 知道它要打印多少页;))

    【讨论】:

    • 是的,在删除 needStop 后,它会以不同的行为工作。现在我的第一页打印了两次,最后一页根本没有打印...
    • 您可以将页面索引传递给它,并在打印时直接从pdfFile 中提取页面,而不是传递PDFPage...另外,尝试输入System.out 以查看哪个页面API 实际上是在尝试打印
    【解决方案3】:

    你应该像这样实现Printableprint()方法:

    @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;
    }
    

    为此,您必须引用您的book 实例,这可以通过使用上述print() 方法定义实现Printable 接口的内部类Page 来实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-31
      • 2023-03-27
      • 2011-06-04
      • 2011-12-31
      相关资源
      最近更新 更多