我想直接从网页打印文件。为此,我正在使用以下参考,并尝试使用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/