代码之家  ›  专栏  ›  技术社区  ›  Jason Day

在Java中打印到特定打印机(IPP URI)

  •  13
  • Jason Day  · 技术社区  · 16 年前

    Java中是否有任何方法可以打印到特定的IPP打印机?我发现的所有示例代码和教程都侧重于如何使用以下内容打印特定类型的文档:

    DocFlavor flavor = DocFlavor.INPUT_STREAM.POSTSCRIPT;
    PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
    aset.add(MediaSizeName.ISO_A4);
    PrintService[] pservices =
                 PrintServiceLookup.lookupPrintServices(flavor, aset);
    if (pservices.length > 0) {
        DocPrintJob pj = pservices[0].createPrintJob();
        try {
            FileInputStream fis = new FileInputStream("test.ps");
            Doc doc = new SimpleDoc(fis, flavor, null);
            pj.print(doc, aset);
        } catch (FileNotFoundException fe) {
        } catch (PrintException e) { 
        }
    }
    

    此代码段仅打印到找到的第一台能够打印文档的打印机。在我的例子中,我想通过URI查找打印机,但是 PrintServiceLookup 似乎不支持这一点。我试着用一个 PrintServiceAttributeSet 而不是 PrintRequestAttributeSet ,并加入 PrinterURI 属性,但不会返回任何打印机。我怀疑查找服务正在查找可以更改其目标URI的打印机,而不是查找具有该URI的打印机。

    作为最后的手段,我想列举一下所有的 PrintService lookupPrintServices ,但URI不在任何属性中。打印机名在那里,但我需要URI。

    为了澄清一点,我不需要渲染数据,我只需要将一个blob复制到给定的打印机。我搞不懂的部分是如何通过IPP URI识别打印机。

    2 回复  |  直到 14 年前
        1
  •  17
  •   Community Mohan Dere    9 年前

    我终于找到了一种方法,通过使用 jipsi :

    URI printerURI = new URI("ipp://SERVER:631/printers/PRINTER_NAME");
    IppPrintService svc = new IppPrintService(printerURI);
    InputStream stream = new BufferedInputStream(new FileInputStream("image.epl"));
    DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
    Doc myDoc = new SimpleDoc(stream, flavor, null);
    DocPrintJob job = svc.createPrintJob();
    job.print(myDoc, null);
    

    我必须承认,我对不得不使用第三方库来做一些看似简单的事情感到失望,比如打印到特定的打印机上。

    更新

    博士在报告中指出 comments 日本国际防扩散安全倡议有一个新的目标 home

    Cups4J 是一个不错的选择,但顾名思义,如果目标不是CUPS服务器,它可能无法正常工作。我使用Cups4J直接在Zebra热敏打印机上打印,效果很好。

        2
  •  1
  •   Thorbjørn Ravn Andersen    16 年前

    我不认为您可以按照自己的方式获得打印机(我认为Java打印机制早于IPP)。

    但是,如果我没记错的话,您可以在本地呈现打印作业,然后“手动”将输出流的字节发送到目标CUPS服务器。这对你来说“足够好”吗?

        3
  •  1
  •   IPP Nerd    5 年前

    要仅通过IPP向打印机(或CUPS)提交PDF等可打印文档格式,此代码提供了一个没有依赖项的最低限度实现。 ipp-printjob-java 具有解码ipp响应的基本支持。

    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.URI;
    import java.nio.charset.Charset;
    import java.nio.charset.StandardCharsets;
    
    public class IppPrintJob {
    
      public static void main(String args[]) throws Exception {
        URI printerURI = URI.create("http://colorjet:631/ipp/printer");
        File file = new File("A4-blank.pdf");
        short status = new IppPrintJob()
          .printDocument(printerURI, new FileInputStream(file));
        System.out.println(String.format("ipp status: %04X", status));
      }
    
      short printDocument(
        URI uri, InputStream documentInputStream
      ) throws IOException {
        HttpURLConnection httpURLConnection =
          (HttpURLConnection) uri.toURL().openConnection();
        httpURLConnection.setDoOutput(true);
        httpURLConnection.setRequestProperty("Content-Type", "application/ipp");
        OutputStream outputStream = httpURLConnection.getOutputStream();
        DataOutputStream dataOutputStream =
          new DataOutputStream(httpURLConnection.getOutputStream());
        dataOutputStream.writeShort(0x0101); // ipp version
        dataOutputStream.writeShort(0x0002); // print job operation
        dataOutputStream.writeInt(0x002A); // request id
        dataOutputStream.writeByte(0x01); // operation group tag
        writeAttribute(dataOutputStream, 0x47, "attributes-charset", "utf-8");
        writeAttribute(dataOutputStream, 0x48, "attributes-natural-language", "en");
        writeAttribute(dataOutputStream, 0x45, "printer-uri", uri.toString());
        dataOutputStream.writeByte(0x03); // end tag
        documentInputStream.transferTo(outputStream);
        dataOutputStream.close();
        outputStream.close();
        if (httpURLConnection.getResponseCode() == 200) {
          DataInputStream dataInputStream =
            new DataInputStream(httpURLConnection.getInputStream());
          System.out.println(String.format("ipp version %d.%s",
            dataInputStream.readByte(), dataInputStream.readByte()
          ));
          return dataInputStream.readShort();
        } else {
          throw new IOException(String.format("post to %s failed with http status %d",
            uri, httpURLConnection.getResponseCode()
          ));
        }
      }
    
      void writeAttribute(
        DataOutputStream dataOutputStream, int tag, String name, String value
      ) throws IOException
      {
        Charset charset = StandardCharsets.UTF_8;
        dataOutputStream.writeByte(tag);
        dataOutputStream.writeShort(name.length());
        dataOutputStream.write(name.getBytes(charset));
        dataOutputStream.writeShort(value.length());
        dataOutputStream.write(value.getBytes(charset));
      }
    
    }
    
    推荐文章