且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

java printerjob景观白色空间

更新时间:2023-12-03 17:15:16

不要使用 PageFormat#getWidth PageFormat#getHeight ,请使用 PageFormat #getImageableWidth PageFormat#getImageableHeight 而不是

Don't use PageFormat#getWidth or PageFormat#getHeight, use PageFormat#getImageableWidth and PageFormat#getImageableHeight instead

来自 JavaDocs


返回页面可成像区域的高度/宽度,以1/72英寸为单位。此方法考虑了页面的方向。

Return the height/width, in 1/72nds of an inch, of the imageable area of the page. This method takes into account the orientation of the page.

您还应该翻译打印机 Graphics ImageableX / Y ...

You should also translate the printer Graphics by the ImageableX/Y...

g2.translate((int)pageFormat.getImageableX(), (int)pageFormat.getImageableY());

可运行的示例

这是一个简单的可运行示例。这段代码能够拍摄原版(左图)并以纵向和横向打印,而不会出现问题......

This is a simple runnable example. This code was able to take the original (left) and print it both in portrait and landscape without issue...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
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;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class PrintTest100 {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                try {
                    PrinterJob pj = PrinterJob.getPrinterJob();
                    pj.setJobName(" Print Component ");

                    PageFormat pf = pj.defaultPage();
//                  pf.setOrientation(PageFormat.LANDSCAPE);
//                  pf = pj.validatePage(pf);

                    pj.setPrintable(new ImagePrintable(ImageIO.read(new File("..."))), pf);

                    if (!pj.printDialog()) {
                        return;
                    }
                    try {
                        pj.print();
                    } catch (PrinterException ex) {
                        ex.printStackTrace();
                    }
                } catch (IOException exp) {
                    exp.printStackTrace();
                }
            }
        });
    }

    public static class ImagePrintable implements Printable {

        private int currentPage = -1;
        private Image cachedScaledImage = null;

        private BufferedImage master;

        public ImagePrintable(BufferedImage master) {
            this.master = master;
        }

        public double getScaleFactor(int iMasterSize, int iTargetSize) {
            double dScale = 1;
            if (iMasterSize > iTargetSize) {
                dScale = (double) iTargetSize / (double) iMasterSize;
            } else {
                dScale = (double) iTargetSize / (double) iMasterSize;
            }
            return dScale;
        }

        public double getScaleFactorToFit(BufferedImage img, Dimension size) {
            double dScale = 1;
            if (img != null) {
                int imageWidth = img.getWidth();
                int imageHeight = img.getHeight();
                dScale = getScaleFactorToFit(new Dimension(imageWidth, imageHeight), size);
            }
            return dScale;
        }

        public double getScaleFactorToFit(Dimension original, Dimension toFit) {
            double dScale = 1d;
            if (original != null && toFit != null) {
                double dScaleWidth = getScaleFactor(original.width, toFit.width);
                double dScaleHeight = getScaleFactor(original.height, toFit.height);

                dScale = Math.min(dScaleHeight, dScaleWidth);
            }
            return dScale;
        }

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

            int result = Printable.NO_SUCH_PAGE;

            if (pageIndex == 0) {

                result = Printable.PAGE_EXISTS;

                Graphics2D graphics2D = (Graphics2D) graphics;
                graphics2D.translate(pageFormat.getImageableX(), pageFormat.getImageableY());

                int width = (int) Math.round(pageFormat.getImageableWidth());
                int height = (int) Math.round(pageFormat.getImageableHeight());

                if (currentPage != pageIndex || cachedScaledImage == null) {
                    currentPage = pageIndex;

                    double scaleFactor = getScaleFactorToFit(new Dimension(master.getWidth(), master.getHeight()), new Dimension(width, height));

                    int imageWidth = (int) Math.round(master.getWidth() * scaleFactor);
                    int imageHeight = (int) Math.round(master.getHeight() * scaleFactor);

                    cachedScaledImage = master.getScaledInstance(imageWidth, imageHeight, Image.SCALE_SMOOTH);

                }

                double x = ((pageFormat.getImageableWidth() - cachedScaledImage.getWidth(null)) / 2);
                double y = ((pageFormat.getImageableHeight() - cachedScaledImage.getHeight(null)) / 2);

                graphics2D.drawImage(cachedScaledImage, (int) x, (int) y, null);
                graphics2D.setColor(Color.RED);
                graphics2D.drawRect(0, 0, width - 1, height - 1);
            }

            return result;
        }
    }

}

nb:我和Yosemite有一个问题,试图弄清楚如何从对话框中改变打印方向,最后,我放弃并通过更改 PageFormat 来强制它 PrintJob的。我在无数应用程序中使用了相同类型的代码而没有问题...

nb: I had an issue with Yosemite, trying to figure out how to change the print orientation from the dialog, in the end, I gave up and forced it by changing the PageFormat from the PrintJob. I've used this same type of code in countless applications without issues before...

已更新

原始图片:1920x1200

Original Image: 1920x1200