私はしばらくの間、標準のJava Printライブラリを使用して、特定の属性を持つファイル(具体的には、PDFドキュメント)を特定のトレイまたはデュプレックスを使用して印刷する方法を決定しようとしてきました。
これをどのように行うべきかについてのドキュメントはたくさんあります。実際、私はこれらの方法を調査して試しました。典型的な方法は次のようなものです。
public static void main (String [] args) {
try {
PrintService[] pservices = PrintServiceLookup.lookupPrintServices(null, null);
//Acquire Printer
PrintService printer = null;
for (PrintService serv: pservices) {
System.out.println(serv.toString());
if (serv.getName().equals("PRINTER_NAME_BLAH")) {
printer = serv;
}
}
if (printer != null) {
System.out.println("Found!");
//Open File
FileInputStream fis = new FileInputStream("FILENAME_BLAH_BLAH.pdf");
//Create Doc out of file, autosense filetype
Doc pdfDoc = new SimpleDoc(fis, DocFlavor.INPUT_STREAM.AUTOSENSE, null);
//Create job for printer
DocPrintJob printJob = printer.createPrintJob();
//Create AttributeSet
PrintRequestAttributeSet pset = new HashPrintRequestAttributeSet();
//Add MediaTray to AttributeSet
pset.add(MediaTray.TOP);
//Add Duplex Option to AttributeSet
pset.add(Sides.DUPLEX);
//Print using Doc and Attributes
printJob.print(pdfDoc, pset);
//Close File
fis.close();
}
}
catch (Throwable t) {
t.printStackTrace();
}
}
要するに、あなたは次のことをします
- プリンタを探す
- PrinterJobを作成する
- AttributeSetを作成する
- トレイやデュプレックスなどの属性をAttributeSetに追加します
- AttributeSetを使用してプリンタージョブでprintを呼び出します
ここでの問題は、これを行うための文書化された方法であり、いくつかのチュートリアルから私が見つけたものであるにもかかわらず、この方法は...機能しないことです。覚えておいてください、それはあまり説明的ではないように聞こえますが、私に聞いてください。 軽くは言わない...
PrinterJobの公式ドキュメントには、デフォルトの実装ではAttributeSetが無視されると実際に記載されています。 ここに表示されているソースコードは、これが真であることを示しています。属性は渡され、完全に無視されます。
どうやら、特定のプリンタとその機能に基づいている可能性のある、ある種の拡張バージョンのクラスが必要ですか?私はそのような機能を教えてくれるいくつかのテストコードを書こうとしました-オフィスには多種多様なプリンターが設置されており、大小、シンプルまたはベルとホイッスルでいっぱいです-疑似のためだけに私のコンピューター上のいくつかのドライバーは言うまでもありません-ドキュメントを作成し、ハードウェアを使用せずにプリンターをシミュレートするプリンタードライバー。テストコードは次のとおりです。
public static void main (String [] args) {
PrintService[] pservices = PrintServiceLookup.lookupPrintServices(null, null);
for (PrintService serv: pservices) {
System.out.println(serv.toString());
printFunctionality(serv, "Trays", MediaTray.class);
printFunctionality(serv, "Copies", Copies.class);
printFunctionality(serv, "Print Quality", PrintQuality.class);
printFunctionality(serv, "Color", ColorSupported.class);
printFunctionality(serv, "Media Size", MediaSize.class);
printFunctionality(serv, "Accepting Jobs", PrinterIsAcceptingJobs.class);
}
}
private static void printFunctionality(PrintService serv, String attrName, Class<? extends Attribute> attr) {
boolean isSupported = serv.isAttributeCategorySupported(attr);
System.out.println(" " + attrName + ": " + (isSupported ? "Y" : "N"));
}
私が見つけた結果は、例外なく、すべてのプリンターが「コピー」がサポートされていることを返し、他のすべての属性はサポートされていないことでした。さらに、それがどれほど信じられないように見えるかにかかわらず、すべてのプリンターの機能は同一でした。
避けられない質問は多層的です:どのように属性が登録されている方法で属性を送信するのですか?さらに、プリンタの機能を適切に検出するにはどうすればよいですか?実際、PrinterJobクラスは実際に使用可能な方法で拡張されているのでしょうか、それとも属性は常に無視されているのでしょうか。
私がインターネット全体で見つけた例は、後者の質問に対する答えが「いいえ、それらは常に無視されます」であると私に示唆しているようです。 このコードは、Sunが設定しただけで、完全な状態になることはありませんか?もしそうなら、代替手段はありますか?