我想直接从网页打印文件。为此,我正在使用以下参考,并尝试使用ZUL和Composer实施相同的参考。

http://tonny-bruckers.blogspot.in/2012/11/printing-files-directly-from-web-page.html

ZUL文件:-

<zk>
<applet code = "PrintApplet.class" codebase = "applet/" id="printApplet" width="400px" style="border: 1px" />
<button id="btnClickMe" label="Click Me" sclass="light-btn"/>
</zk>


PrintApplet.class位于“ WebContent / applet”中。

public class AppletComposer extends GenericForwardComposer<Window> {
    private Applet printApplet;
    public void doOverrideAfterComposer(Window comp) throws Exception {

    }
    public void onClick$btnClickMe(Event event) throws Exception {
        String Originalstr = "ByteArrayInputStream Example!";
        byte[] Originalbytes = Originalstr.getBytes();
        ByteArrayInputStream bis=new ByteArrayInputStream(Originalbytes);
        printApplet.invoke("print", bis);
    }
}


PrintApplet类别:-

public class PrintApplet extends Applet {
    public void init()
    {

    }
    public void print(ByteArrayInputStream bis) throws PrintException
    {
        PrintService service = PrintServiceLookup.lookupDefaultPrintService();
        if (service != null) {
            DocFlavor psFormat = DocFlavor.INPUT_STREAM.PDF;
            PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
            DocPrintJob job = service.createPrintJob();
            Doc pdfDoc = new SimpleDoc(bis,psFormat, null);
            job.print(pdfDoc, attributes);
        }
    }
}


我可以用这种方法调用PrintApplet,但可以将Null作为服务。 PrintApplet在AppletViewer和正常的Java应用程序上都可以正常工作,但是在使用上述方法时无法获得默认的打印机服务。

最佳答案

首先,我要提到APPLET始终在客户端运行,并且APPLET仅与从其下载的服务器通信。
  
  这就是为什么我们必须指定代码库目录的原因,以便我们可以在客户端浏览器上下载小程序,然后由浏览器的JAVA Platform Environment插件进行控制,而该插件又可以在客户端JRE环境上运行。
  
  因此,我们必须非常小心地正确安装了JDK环境。
  要跟踪小程序日志,我们可以使用Java小程序控制台工具“ jconsole”。




APPLET在客户端浏览器上正确运行的步骤:


在浏览器(firefox,chrome,opera)上检查是否存在JAVA Platform插件,因为要从浏览器运行applet,我们需要安装并启用该插件。

如果您在linux机器上工作:有点复杂,
您可以从此处找到如何为LINUX-BROWSER启用插件:

http://www.oracle.com/technetwork/java/javase/manual-plugin-install-linux-136395.html
为applet启用控制台日志,当它在客户端JRE上执行时,我们可以对其进行调查以进行跟踪。

路径:JDK_DIR / bin / jcontrol

[JControl窗口] [1]

仅出于开发目的:您可以降低安全性
每次我们构建新的applet时,我们都必须清除applet的缓存,以反映最新的变化,我们需要首先清除cache,否则它将加载已缓存的applet类。

要清除,我们可以使用'javaws -viewer'

路径:JAVA_HOME / bin / javaws -viewer

[清除小程序缓存] [2]





  根据您的代码,您的服务器端代码(zul和composer)是完美的,但是问题出在applet代码上。
  
  您正在print()方法中寻找默认打印机,这是一次性配置代码。它必须在init()中。
  
  PrintApplet.java


public class PrintApplet extends Applet {

 private static final long serialVersionUID = 1L;
 private PrintService service;

 public void init()
 {
    JOptionPane.showMessageDialog(null, "Inside INIT()");
    if(null==service){
        service = PrintServiceLookup.lookupDefaultPrintService();
        System.out.println(service.getName());
    } else {
        System.out.println(service.getName());
    }
 }
 public void print(String str) throws PrintException
 {
    JOptionPane.showMessageDialog(null, "Inside print()");
    JOptionPane.showMessageDialog(null, "String is:::"+str);
    cPrint cP = new cPrint(str, service);
    System.out.println((Integer) AccessController.doPrivileged(cP));
 }
}



  并且您需要AccessController的另一种实现,以授予对默认打印机的定位和打印权限。
  
  cPrint.java


class cPrint implements PrivilegedAction<Object> {
 String str;
 PrintService service;

 public cPrint(String str, PrintService argPrintService) {

    this.str = str;
    this.service = argPrintService;

 };
 public Object run() {
    // privileged code goes here
    InputStream is = null;
    try
    {
        JOptionPane.showMessageDialog(null, "String is:::"+str);
        byte[] Originalbytes = str.getBytes();
        JOptionPane.showMessageDialog(null, "Original bytes:::"+Originalbytes);
        is=new ByteArrayInputStream(Originalbytes);
        FileWriter fstream = new FileWriter("/home/test/out.pdf");
        BufferedWriter out = new BufferedWriter(fstream);
        for (Byte b: Originalbytes) {
            out.write(b);
        }
        out.close();
        DocPrintJob printJob = service.createPrintJob();
        Doc doc;
        DocAttributeSet docAttrSet = new HashDocAttributeSet();
        PrintRequestAttributeSet printReqAttr = new HashPrintRequestAttributeSet();
        doc = new SimpleDoc(is, DocFlavor.INPUT_STREAM.AUTOSENSE, docAttrSet);
        PrintJobWatcher pjDone = new PrintJobWatcher(printJob);
        printJob.print(doc, printReqAttr);
        pjDone.waitForDone();
        // It is now safe to close the input stream
        is.close();
     }
     catch (Exception e) {
        e.printStackTrace();
        System.out.println(e);
        return 1;
     }
    return 0;
  }
  static class PrintJobWatcher {
    // true iff it is safe to close the print job's input stream
    boolean done = false;

    PrintJobWatcher(DocPrintJob job) {
        // Add a listener to the print job
        job.addPrintJobListener(new PrintJobAdapter() {
            public void printJobCanceled(PrintJobEvent pje) {
                allDone();
            }
            public void printJobCompleted(PrintJobEvent pje) {
                allDone();
            }
            public void printJobFailed(PrintJobEvent pje) {
                allDone();
            }
            public void printJobNoMoreEvents(PrintJobEvent pje) {
                allDone();
            }
            void allDone() {
                synchronized (PrintJobWatcher.this) {
                    done = true;
                    PrintJobWatcher.this.notify();
                }
            }
        });
    }
    public synchronized void waitForDone() {
        try {
            while (!done) {
                wait();
            }
        } catch (InterruptedException e) {
        }
    }
 }
}



  
    cPrint(str,PrintService)
    
    如果要打印文件,则str可以是文件名,也可以是字节数组字符串。
    
    在我的示例中,我希望使用字节数组,因此我将从作曲家的applet提供的字节数组中创建pdf文件,然后将其发送到给定PrintService的默认打印机。
    
    因此,zk中applet可以访问默认打印机并进行打印的实际流程由此[graph] [3]决定。

关于java - 使用小程序时无法获取默认打印机名称-ZK Framework,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34394577/

10-13 09:09