无法指定正确的打印尺寸

13

我们最近获得了一个Brother QL-700打印机,我们正在通过这台机器进行一些贴纸印刷。

我们使用的纸张是62毫米宽的无长度限制的贴纸卷

问题在于,无论我如何尝试(我已经尝试了BookPrintRequestAttributeSet等),我都不能使用Java告诉打印对话框窗口使用正确的纸张大小。我无法使其精确到我们需要的62毫米×40毫米。它总是像这样“捕捉”到最接近的纸张:

下面是相关的代码:

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:

所以问题是:

如何强制纸张"长度"精确到40毫米?

相关: Brother QL 570 标签打印机的自定义纸张大小

编辑

我进行了媒体大小查询(代码),这是它可以支持的媒体列表:

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端口,甚至不使用Brother提供的固件。它完美地解决了我的问题。

6个回答

1

使用自定义的java.awt.print.Paper无法与Brother QL标签打印机配合使用。

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

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

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

打印机设置

自定义纸张大小列表

添加自定义纸张

之后,您应该按您选择的名称(例如“自定义纸张”)找到媒体并通过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();
}

这个解决方案也适用于DYMO LabelWriter 320。它已经定义了一个“连续,宽”的纸张大小,我能够将其找到作为MediaSizeName - Johan Boberg

1

没有比这里更好的回答方式 在这里

同时不要混淆高度和长度以及宽度,在Java中,paper类使用宽度和高度而不是长度

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

这些只是 paper 类中一些方法,当涉及到实现更多参数时,您可能想查看它们。希望能有所帮助 :)


2
谢谢。打印机的问题在于,无论您设置什么尺寸,打印机服务似乎总是“捕捉”到他们喜欢的最近尺寸,这对打印机来说不好,因为打印机能够打印62mm x *mm大小的纸张。他们提供的软件证明可以做到,但不能用Java。不知何故,我要么没有得到正确的组合,要么Java服务不支持它。 - Lionel Chan
嗨,我遇到了同样的问题。你找到了任何解决方案,而无需与打印机通信或使用Python吗?谢谢。 - Thai Doan

0

我找到了一个适合我的解决方案。在调用printDialog()之后,你不能在PrintJob上设置setPrintable(),而是应该使用包含Printable的Book对象来调用setPageable()。第一个方法会验证传递的PageFormat并选择另一个。


0

我尝试按照@MarkoD描述的方法,为Brother QL-800标签打印机定义一个自定义无限纸张大小。

但是当我读取MediaSize时,我的定义的自定义纸张没有显示出来。如果我将尺寸更改为其他值,则会突然出现在列表中。

可能是因为如果自定义纸张大小接近默认纸张大小,Brother会使用默认纸张大小吗?


1
目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何撰写好答案的更多信息。 - Community

0

我曾多次看到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毫米直径”。 - Lionel Chan

0

在提交打印作业请求时,您可能需要使用PrintRequestAttribute。如果自定义打印介质大小无法正常工作,则可以使用查询代码查找已发现的介质大小,并在请求属性集中选择最合适的一个。

@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会显示默认提示,但打印机拒绝接受作业并在运行时取消它。我无法使用此方法进行打印 :( http://imgur.com/Hj77T7H - Lionel Chan

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