【问题标题】:Cannot specify the correct size for printing无法指定正确的打印尺寸
【发布时间】:2016-11-10 09:29:41
【问题描述】:

我们最近购买了一台brother QL-700 打印机,我们正在通过这台机器进行一些不干胶打印。

我们输入的纸张是62mm-wide sticker roll,没有“长度”限制。

问题是,无论我怎么做(我尝试过BookPrintRequestAttributeSet),我都无法使用 Java 告诉打印机对话框窗口为打印机使用正确的纸张尺寸。例如,我无法按照我们的需要制作出精确的 62mm × 40mm。它总是像这样“捕捉”到最近的纸张:

这里是有问题的代码:

PrinterJob job = PrinterJob.getPrinterJob();
PageFormat pf = job.defaultPage();
Paper p = pf.getPaper();
p.setSize(UnitConv.mm2pt(62), UnitConv.mm2pt(40));
p.setImageableArea(0, 0, UnitConv.mm2pt(62), UnitConv.mm2pt(40));
pf.setPaper(p);
pf.setOrientation(PageFormat.LANDSCAPE);

job.setPrintable(this, pf);

if (job.printDialog()) {
    try {
        job.print();
    } catch (Exception PrintException) {
        PrintException.printStackTrace();
    }
}



我可以确认打印机可以打印任意长度,如下图所示(使用 Brother 的 P-touch 编辑器)。注意虽然是可调的,但是36mm是软件自己预设的:

所以问题:

如何强制纸张的“length”精确到40mm?

相关: custom paper size for labelprinter (Brother QL 570)

编辑

我进行了媒体尺寸查询 (code),这是它可以支持的媒体列表:

17 mm x 54 mm: width = 0.67; height = 2.12
17 mm x 87 mm: width = 0.67; height = 3.42
23 mm x 23 mm: width = 0.9066535; height = 0.9066535
iso-b10: width = 1.2204725; height = 1.7322835
29 mm x 90 mm: width = 1.14; height = 3.5366535
38 mm x 90 mm: width = 1.4966536; height = 3.5366535
39 mm x 48 mm: width = 1.5366535; height = 1.8833464
52 mm x 29 mm: width = 1.1366535; height = 2.0466535
iso-b8: width = 2.440945; height = 3.464567
62 mm x 29 mm: width = 1.1366535; height = 2.44
62 mm x 100 mm: width = 2.44; height = 3.93
12 mm Dia: width = 0.47334644; height = 0.47334644
23 mm x 23 mm: width = 0.9066535; height = 0.9066535
58 mm Dia: width = 2.2933464; height = 2.2933464
12 mm: width = 0.47334644; height = 3.9366536
29 mm: width = 1.14; height = 3.9366536
38 mm: width = 1.4966536; height = 3.9366536
50 mm: width = 1.9666536; height = 3.9366536
54 mm: width = 2.1266534; height = 3.9366536
62 mm x 100 mm: width = 2.44; height = 3.93
12 mm x2: width = 0.82665354; height = 3.9366536
54 mm: width = 2.1266534; height = 3.9366536
38 mm x2: width = 2.8733466; height = 3.9366536
50 mm x2: width = 3.8133464; height = 3.9366536
54 mm x2: width = 3.9366536; height = 4.0933466
62 mm x2: width = 3.9366536; height = 4.76
29 mm: width = 1.14; height = 3.9366536
29 mm x3: width = 3.18; height = 3.9366536
38 mm x3: width = 3.9366536; height = 4.25
50 mm x3: width = 3.9366536; height = 5.66
54 mm x3: width = 3.9366536; height = 6.06
62 mm x3: width = 3.9366536; height = 7.08
38 mm: width = 1.4966536; height = 3.9366536
29 mm x4: width = 3.9366536; height = 4.2
38 mm x4: width = 3.9366536; height = 5.6266537
50 mm x4: width = 3.9366536; height = 7.5066533
54 mm x4: width = 3.9366536; height = 8.026653
62 mm x4: width = 3.9366536; height = 9.4
29 mm x 90 mm: width = 1.14; height = 3.5366535
38 mm x 90 mm: width = 1.4966536; height = 3.5366535
Small Address Label: width = 1.1366535; height = 2.44
17 mm x 54 mm: width = 0.67; height = 2.12
62 mm x 100 mm: width = 2.44; height = 3.93
62 mm x 100 mm: width = 2.44; height = 3.93
17 mm x 87 mm: width = 0.67; height = 3.42
17 mm x 54 mm: width = 0.67; height = 2.12
Binder 3 cm - Spine: width = 1.14; height = 8.226653
Binder 5 cm - Spine: width = 2.44; height = 8.226653
58 mm Dia: width = 2.2933464; height = 2.2933464
12 mm Dia: width = 0.47334644; height = 0.47334644
23 mm x 23 mm: width = 0.9066535; height = 0.9066535
23 mm x 23 mm: width = 0.9066535; height = 0.9066535
62 mm x 184 mm Postage Label: width = 2.44; height = 7.24
Binder 5 cm - Spine: width = 2.44; height = 8.226653

编辑(2017 年 4 月)

只是为了更新这个问题的状态。最后我通过python和一个开源实用程序brother_ql解决了它,它直接将作业发送到usb端口,甚至没有使用兄弟提供的固件。它工作得很好,解决了我的问题。

【问题讨论】:

    标签: java printing java-print


    【解决方案1】:

    没有比here 更好的回答方式了

    那么也不要混淆height和length和width,java中的paper类取的是width和height而不是length

     public void setSize(double width, double height) {
        mWidth = width;
        mHeight = height;
    

    你可能也想考虑这个

       /**
     * Sets the imageable area of this <code>Paper</code>.  The
     * imageable area is the area on the page in which printing
     * occurs.
     * @param x the X coordinate to which to set the
     * upper-left corner of the imageable area of this <code>Paper</code>
     * @param y the Y coordinate to which to set the
     * upper-left corner of the imageable area of this <code>Paper</code>
     * @param width the value to which to set the width of the
     * imageable area of this <code>Paper</code>
     * @param height the value to which to set the height of the
     * imageable area of this <code>Paper</code>
     */
    public void setImageableArea(double x, double y,
                                 double width, double height) {
        mImageableArea = new Rectangle2D.Double(x, y, width,height);
    }
    

    这些只是纸质类中的一些方法,当涉及到实现时,您可能想看看更多参数.. 希望对你有帮助:)

    【讨论】:

    • 谢谢。打印机的问题是,无论您设置什么尺寸,打印机服务似乎总是“捕捉”到他们喜欢的最接近的尺寸,这对打印机来说是不行的,因为打印机能够打印 62mm x *mm 尺寸的纸张.他们提供的软件证明可以做到,但不能用Java。不知何故,要么我没有得到正确的组合,要么 Java 服务不支持它。
    • 您好,我也遇到了同样的问题。您是否在不与打印机通信或使用 python 的情况下找到任何解决方案?谢谢
    【解决方案2】:

    我已经多次看到Paper setSize 传递的参数包含像素大小。您可以尝试像这样将mm2pt 更改为mm2px 吗?

    PrinterJob job = PrinterJob.getPrinterJob();
    PageFormat pf = job.defaultPage();
    Paper p = pf.getPaper();
    int resolution = 72; // dpi
    p.setSize(UnitConv.mm2px(62, resolution), UnitConv.mm2px(40, resolution));
    p.setImageableArea(0, 0, UnitConv.mm2px(62, resolution), UnitConv.mm2px(40, resolution));
    pf.setPaper(p);
    pf.setOrientation(PageFormat.LANDSCAPE);
    
    job.setPrintable(this, pf);
    
    if (job.printDialog()) {
        try {
            job.print();
        } catch (Exception PrintException) {
            PrintException.printStackTrace();
        }
    }
    

    【讨论】:

    • 不走运。它仍在选择最接近的变体“58 mm Dia”。
    【解决方案3】:

    您可能需要在提交printjob request 时使用PrintRequestAttribute。如果自定义打印介质尺寸不起作用,您可能希望使用通过query code 发现的介质尺寸并在请求属性集中选择最合适的一个。

    @Test
    public void testMyPrinteService() {
        // select default or specific one here
        PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
    
        PrinterJob job = PrinterJob.getPrinterJob();
    
        PageFormat pf = job.defaultPage();
        Paper p = pf.getPaper();
        p.setSize(UnitConv.mm2pt(62), UnitConv.mm2pt(40));
        p.setImageableArea(0, 0, UnitConv.mm2pt(62), UnitConv.mm2pt(40));
        pf.setPaper(p);
        pf.setOrientation(PageFormat.LANDSCAPE);
    
        Printable myPrintable = null ;//some printable new MyPrintable(1); 
        PrintRequestAttributeSet printReqAttrs = new HashPrintRequestAttributeSet();
        PrintRequestAttribute jobPrinArea = new MediaPrintableArea(0, 0, 64, 40, MediaPrintableArea.MM);
        printReqAttrs.add(jobPrinArea);
    
        if (job.printDialog(printReqAttrs)) {
            try {
                job.setPrintable(myPrintable, pf);
                job.setPrintService(printService);
                //pass specific attributes to printer
                job.print(printReqAttrs);
            } catch (Exception PrintException) {
                PrintException.printStackTrace();
            }
        }
    }
    

    希望这会有所帮助。

    【讨论】:

    • 如果我这样做,将显示 Java 的默认提示,但打印机拒绝接受该作业并即时取消它。我无法使用这种方法打印 :( imgur.com/Hj77T7H
    【解决方案4】:

    使用自定义 java.awt.print.Paper 不适用于 Brother QL 标签打印机。

    我已经为QL-720NW 找到了一个解决方案,它的型号几乎相同,只是带有 WiFi 和以太网。 请注意,它应该适用于所有 Brother 标签打印机。

    首先,您需要使用驱动程序添加自定义连续磁带格式。在 Windows 中,它位于:

    打印机首选项 > 高级选项卡 > 连续磁带格式 > 设置

    Printer Settings

    List of Custom Paper Sizes

    Add Custom Paper

    之后,您应该按照您选择的名称(例如“自定义纸张”)找到介质并通过 javax.print API 打印:

    // Lookup printer by name 
    PrintService[] foundPrinters = PrintServiceLookup.lookupPrintServices(null, new HashAttributeSet(new PrinterName("QL-720NW", null)));
    PrintService printer = foundPrinters[0];
    
    // Lookup custom paper by name
    MediaSizeName paper = null;
    for (Media m : (Media[])printer.getSupportedAttributeValues(Media.class, null, null))
    {
        if (m instanceof MediaSizeName)
        {
            MediaSizeName media = ((MediaSizeName)m);
            if ("Custom paper".equals(media.toString())) paper = media;
        }
    }
    
    // Create a new printable object
    Printable p = ...; // Create a printable object
    Doc doc = new SimpleDoc(p, DocFlavor.SERVICE_FORMATTED.PRINTABLE, null);
    
    // Set custom paper as request attribute
    PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();
    attrs.add(paper);
    
    // Create a new print job and print it
    DocPrintJob job = printer.createPrintJob();
    try
    {
        job.print(doc, attrs);
    }
    catch (PrintException ex)
    {
        ex.printStackTrace();
    }
    

    【讨论】:

      【解决方案5】:

      我找到了适合我的解决方案。调用 printDialog() 后,您不能在 PrintJob 上设置打印 (),但使用包装在 Book 对象中的 Printable 的 setPageable() 可以工作。第一个验证传递的 PageFormat 并选择另一个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-29
        • 1970-01-01
        • 1970-01-01
        • 2018-05-06
        • 1970-01-01
        • 1970-01-01
        • 2014-10-31
        • 2018-08-23
        相关资源
        最近更新 更多