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が必要です。

背景として、私のWebアプリは、現在のユーザーに基づいて、特定のプリンターにバーコードを印刷する必要があります。各ユーザーは、CUPSサーバー上のプリンターを指すプリンターURIに関連付けられています。私が持っている情報はプリンターURIだけであり、プリンター名をURIまたはURIのサブストリングと一致するように制限することはできません。

編集:少し明確にするために、データをレンダリングする必要はありません。blobを特定のプリンターにコピーするだけです。私が理解できない部分は、IPPURIによってプリンターを識別する方法です。

4

3 に答える 3

17

私はついにこれを行う方法を見つけました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);

特定のプリンタに印刷するような単純なことをするためにサードパーティのライブラリを使用しなければならないことに失望していることを認めなければなりません。

アップデート

DRはコメントの中で、jipsiには新しいと新しい名前があることを指摘しています。

Cups4Jは優れた代替手段ですが、名前が示すように、宛先がCUPSサーバーでない場合は正しく機能しない可能性があります。Cups4Jを使用してZebraサーマルプリンターに直接印刷することで、良い結果が得られました。

于 2009-11-02T18:24:41.863 に答える
1

私はあなたが望むようにプリンターを手に入れることができるとは思いません(私はJava PrintメカニズムがIPPよりも前からあると思います)。

ただし、正しく思い出せば、印刷ジョブをローカルでレンダリングしてから、出力ストリームのバイトをターゲットCUPSサーバーに「手動で」送信できる可能性があります。これはあなたにとって「十分」でしょうか?

于 2009-10-31T19:24:57.277 に答える
1

PDFなどの印刷可能なドキュメント形式をIPP経由でプリンター(またはCUPS)にのみ送信するために、このコードは依存関係のない最小限の実装を提供します。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));
  }

}
于 2020-03-19T14:20:16.930 に答える