首页 > 解决方案 > 当实际页面较大时如何在虚拟页面周围打印边框

问题描述

我的程序打印 A6 大小的页面,但是我经常使用较大的纸张。在这种情况下,我想在 A6 虚拟页面周围打印一个边框来帮助我修剪纸张。但如果我使用实际的 A6 纸,我想要一个可行的解决方案。

我在 macOS 上运行。

我将 pageDialog() 配置为所需的页面大小(3.75 x 6.75 英寸)和全尺寸的可成像区域。经过验证的返回 PageFormat 与该大小和可成像区域匹配。

但是,当我的 Printable 被调用时,PageFormat 不同:纸张尺寸为 3.875 x 7.5 英寸,可成像区域为 3.375 x 6.55 英寸,左边距为 0.25 英寸,上边距为 0.2 英寸。我可以理解上边距,因为 8.5 x 11 英寸纸上的实际打印在纸的顶部。左边距不明显,因为实际打印是水平居中的。(打印机显然知道纸张宽度,但也许软件不知道打印机会做什么?)

我画了边框:

double paperWidth = 3.75 * 72;
double paperHeight = 6.75 * 72;
g.draw(new Rectangle2D.Double(2, 2, paperWidth - 2, paperHeight - 2));

(2 是一个软糖因素。)

我得到的只是底部的一条细线,但侧面没有。(我不在乎顶部。)如果可成像区域导致剪裁,这是有道理的。

我尝试改变可成像区域和剪辑区域,但没有任何改变。

pageFormat.getPaper().setImageableArea(0, 0, paperWidth, paperHeight);
g = (Graphics2D) g.create();
g.setClip(0, 0, (int) paperWidth, (int) paperHeight);
g.draw(new Rectangle2D.Double(2, 2, paperWidth - 2, paperHeight - 2));
g.dispose();

标签: javaprinting

解决方案


至于为什么您的代码不起作用,我不能说,因为没有足够的信息可以确定。似乎很明显的一件事是,您在绘画时忽略了页边距,这将是一个问题。此外,您无法PageFormat在打印过程中更改 ,因为此信息已用于生成物理打印作业(到打印机)。

下面的例子基本上假设输出页面的期望目标是A6,如果页面大小不合适,它将在代表A6页面的区域周围打印一个边框。

该示例还远未完成,因为我没有考虑如果页面更小会发生什么,只是更大,你需要弄清楚。

该示例将页面默认为 A4,边距非常小(0.1 厘米),但默认页面的概念应该保持不变

例子

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Test {

    public static PaperSize A6_PAPER = new PaperSize(toPPI(4.1), toPPI(5.8));
    public static PaperSize A4_PAPER = new PaperSize(toPPI(8.27), toPPI(11.69));

    public static void main(String[] args) throws IOException {
        BufferedImage background = ImageIO.read(new File("/Users/shanew/Downloads/1512455_10152727077279377_24129534228312133_n.jpg"));
        PrinterJob pj = PrinterJob.getPrinterJob();
        if (pj.printDialog()) {
            PageFormat pf = pj.defaultPage();
            Paper paper = pf.getPaper();

            double width = A4_PAPER.getWidth();            
            double height = A4_PAPER.getHeight();
            paper.setSize(width, height);
            paper.setImageableArea(
                    fromCMToPPI(0.1),
                    fromCMToPPI(0.1),
                    width - fromCMToPPI(0.1),
                    height - fromCMToPPI(0.1));
            pf.setOrientation(PageFormat.PORTRAIT);
            pf.setPaper(paper);
            PageFormat validatePage = pj.validatePage(pf);
            pj.setPrintable(new FancyOutput(background), validatePage);
            try {
                pj.print();
            } catch (PrinterException ex) {
                ex.printStackTrace();
            }
        }
    }

    public static class FancyOutput implements Printable {

        protected static final Rectangle2D BORDER = new Rectangle2D.Double(0, 0, A6_PAPER.getWidth() - 1, A6_PAPER.getHeight() - 1);

        private BufferedImage background;

        public FancyOutput(BufferedImage background) {
            this.background = background;
        }

        @Override
        public int print(Graphics g, PageFormat pf, int page) throws PrinterException {
            Graphics2D g2d = (Graphics2D) g.create();
            if (page != 0) {
                return NO_SUCH_PAGE;
            }
            double width = pf.getImageableWidth();
            double height = pf.getImageableHeight();

            double x = pf.getImageableX();
            double y = pf.getImageableY();

            if (width != A6_PAPER.getWidth() || height != A6_PAPER.getHeight()) {
                x = x + ((width - A6_PAPER.getWidth()) / 2);
                y = y + ((height - A6_PAPER.getHeight()) / 2);

                System.out.println(x + "x" + y);
            }

            g2d.translate((int) x,
                    (int) y);
            Shape oldClip = g2d.getClip();
            g2d.setClip(BORDER);
            g2d.drawImage(background, 0, 0, null);

            g2d.setClip(oldClip);
            if (width != A6_PAPER.getWidth() || height != A6_PAPER.getHeight()) {
                g2d.setColor(Color.RED);
                g2d.draw(BORDER);
            }

            g2d.dispose();

            return PAGE_EXISTS;
        }

    }

    public static class PaperSize {

        private double width;
        private double height;

        public PaperSize(double width, double height) {
            this.width = width;
            this.height = height;
        }

        public double getWidth() {
            return width;
        }

        public double getHeight() {
            return height;
        }
    }

    protected static double fromCMToPPI(double cm) {
        return toPPI(cm * 0.393700787);
    }

    protected static double toPPI(double inch) {
        return inch * 72d;
    }
}

推荐阅读