使用Java在双面模式下打印横向文档

4

我有一个使用JasperReports报告需要在双面打印的情况下以横向模式打印。在此之上,我需要支持PCL5和PCL6打印驱动程序。

在互联网上搜索后,我发现了以下代码片段来完成这个任务:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

import javax.print.PrintService;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.Sides;

public class PrintingTest {

    public static void main(String[] args) {
        try {
            //This are for configuration purpose
            String orientation = "LANDSCAPE";
            String duplexMode = "LONG_EDGE";

            int pageOrientation = 0;

            PrintRequestAttributeSet atr = new HashPrintRequestAttributeSet();
            if ("Landscape".equals(orientation)) {

                atr.add(OrientationRequested.LANDSCAPE);
                pageOrientation = PageFormat.LANDSCAPE;

            } else if ("Reverse_Landscape".equals(orientation)) {

                atr.add(OrientationRequested.REVERSE_LANDSCAPE);
                pageOrientation = PageFormat.REVERSE_LANDSCAPE;

            } else {
                atr.add(OrientationRequested.PORTRAIT);
                pageOrientation = PageFormat.PORTRAIT;
            }

            if ("LONG_EDGE".equals(duplexMode)) {
                atr.add(Sides.TWO_SIDED_LONG_EDGE);
            } else {
                atr.add(Sides.TWO_SIDED_SHORT_EDGE);
            }

            //Printing to the default printer
            PrintService printer = javax.print.PrintServiceLookup
                    .lookupDefaultPrintService();
            //Creating the printing job
            PrinterJob printJob = PrinterJob.getPrinterJob();

            printJob.setPrintService(printer);

            Book book = new Book();
            PageFormat pageFormat = printJob.defaultPage();

            pageFormat.setOrientation(pageOrientation);

            // Appending a exampledocument to the book
            book.append(new ExampleDocument(), pageFormat);

            // Appending another exampledocument to the book
            book.append(new ExampleDocument(), pageFormat);

            // Setting the Pageable to the printjob
            printJob.setPageable(book);

            try {
                // Here a could show the print dialog
                // printJob.printDialog(atr);

                // Here I pass the previous defined attributes
                printJob.print(atr);
            } catch (Exception PrintException) {
                PrintException.printStackTrace();
            }

        } catch (PrinterException ex) {
            ex.printStackTrace();
        }
    }

    public static final int MARGIN_SIZE = 72;

    private static class ExampleDocument implements Printable {

        public int print(Graphics g, PageFormat pageFormat, int page) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.translate(pageFormat.getImageableX(),
                    pageFormat.getImageableY());
            // Only on the first two documents...
            if (page <= 1) {
                // Prints using one inch margin
                g2d.drawString("Printing page " + page + " - duplex...",
                        MARGIN_SIZE, MARGIN_SIZE);
                return (PAGE_EXISTS);
            }

            return (NO_SUCH_PAGE);
        }
    }
}

这在 PCL6 上运行正常,但是在 PCL5 上测试时,我发现 LONG_EDGE 和 SHORT_EDGE 规则被简单地忽略了。在这两种情况下,作业都被发送为 LONG_EDGE。这不是一个问题,除非 Java AWT 打印 API 通过逆时针旋转所有页面 90º 解决横向打印的问题,导致它看起来像是在 SHORT_EDGE 模式下打印。
注:我能够使用 SWT API 在纵向和横向的情况下使用 SHORT_EDGE 和 LONG_EDGE 配置正确地进行打印。但是我无法将 jasper 打印请求转换为 SWT 兼容的打印请求。
我的问题是:有人遇到过这种情况吗?该如何解决?
根据我的观察,我找到了以下可能的解决方案:
  1. 强制 AWT 发送作为横向打印请求而不是让它旋转页面并发送纵向打印请求;
  2. 找到一种方法,在页面处于横向模式时,反转 LONG_EDGE 和 SHORT_EDGE 命令。请注意,对于此解决方案,我将不得不纠正这两者都被视为 LONG_EDGE 请求的问题。
  3. 将 JasperReports 转换为使用 SWT 打印 API。

为什么需要 PCL5 要求? - Thorbjørn Ravn Andersen
由于我们的项目正在从 Delphi 平台迁移到 Java,我们必须保持对旧版本功能的支持。 我们希望避免将 PCL6 打印机驱动程序添加为我们 Java 版本的要求。 今天,我们准备在“SWT”中运行打印例程,对于“PCL5”,或者在“AWT”中运行打印例程,对于“PCL6”,用于双面横向报表。 在“SWT”中的问题是,为了打印,我需要将报表页面作为图像保存在内存中处理,这对于某些用户站点来说非常沉重。 - vkrausser
1个回答

1

我不确定这是否有帮助,但我6年前遇到过这个问题,唯一的解决方法是利用打印机(Xerox)通过.xpf文件接收打印指令。 例如:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xpif SYSTEM "xpif-v02012.dtd">
<xpif cpss-version="2.01" version="1.0" xml:lang="en">
<xpif-operation-attributes>
    <job-name syntax="name" xml:lang="en" xml:space="preserve">job name</job-name>
    <requesting-user-name syntax="name" xml:space="preserve">domain user</requesting-user-name>
    </xpif-operation-attributes>
    <job-template-attributes>
        <copies syntax="integer">1</copies>
        <finishings syntax="1setOf">
        <value syntax="enum">3</value>
    </finishings>
    <job-recipient-name syntax="name" xml:lang="en-US" xml:space="preserve">domain user</job-recipient-name>
    <job-save-disposition syntax="collection">
        <save-disposition syntax="keyword">none</save-disposition>
    </job-save-disposition>
    <media-col syntax="collection">
        <media-type syntax="keyword">stationery</media-type>
        <media-hole-count syntax="integer">0</media-hole-count>
        <media-color syntax="keyword">blue</media-color>
        <media-size syntax="collection">
            <x-dimension syntax="integer">21000</x-dimension>
            <y-dimension syntax="integer">29700</y-dimension>
        </media-size>
    </media-col>
    <orientation-requested syntax="enum">3</orientation-requested>
    <sheet-collate syntax="keyword">collated</sheet-collate>
    <sides syntax="keyword">one-sided</sides>
    <x-side1-image-shift syntax="integer">0</x-side1-image-shift>
    <y-side1-image-shift syntax="integer">0</y-side1-image-shift>
</job-template-attributes>
</xpif>

这个指令与需要打印的文件一同发送给打印机。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接