【问题标题】:Printing PDF from JasperReports从 JasperReports 打印 PDF
【发布时间】:2011-11-03 18:05:40
【问题描述】:

我是 JasperReports 的新手,发现自己迷失了方向。我在 JSF 中有一个 webapp,我想用它来打印 PDF。我已经构建了报告,并且能够成功编译并使用我的所有参数填充它。但是,我迷失了实际的输出部分。我希望它以 PDF 格式发送到打印机。我不在乎在屏幕上看到它,直接到打印机是理想的(从服务器是理想的,但客户端也可以,因为我们可以根据需要设置客户端进行打印(它是一个内部应用程序)) .

【问题讨论】:

标签: java jsf jakarta-ee jasper-reports


【解决方案1】:

我希望它以 PDF 格式发送到打印机。我不在乎在屏幕上看到它,直接到打印机将是理想的

你不能用普通的 HTML/CSS/JS 做到这一点。由于 JSF 基本上只是一个 HTML/CSS/JS 代码生成器,它不能为您做任何魔术。您可以获得的最接近的是 JavaScript 的 window.print(),但它仍会向用户显示打印机设置等(基本上,它与 Ctrl+P 的作用相同)。

最好的办法是创建一个使用the javax.print APIApplet,然后通过HTML <applet><object> 标记将该Applet 嵌入到您的JSF 页面中。

如果您可以接受直接在屏幕上看到它并将打印作业委托给最终用户本身,那么您可以通过 JSF 将 PDF 文件发送到屏幕,如下所示:

public void sendPdf() throws IOException {
    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();
    externalContext.setResponseContentType("application/pdf");
    externalContext.setResponseHeader("Content-Disposition", "inline; filename=\"filename.pdf\"");
    yourJasperReportsClass.writePdfTo(externalContext.getResponseOutputStream());
    facesContext.responseComplete();
}

我从未使用过 JasperReports,所以 yourJasperReportsClass.writePdfTo() 只是一个随机猜测,但提示应该足够清楚。您基本上需要指示它将 PDF 写入响应正文。


更新:根据 cmets,该打印机实际上连接到服务器,而不是连接到客户端,您实际上希望让服务器将其打印到其打印机。在这种情况下,只需使用the javax.print API。在该文档的底部,您可以找到一些代码示例。以下是相关性摘录:

使用 API

使用 Java Print Service API 的典型应用程序执行以下步骤来处理打印请求:

  • 选择 DocFlavor。
  • 创建一组属性。
  • 找到可以处理由 DocFlavor 和属性集指定的打印请求的打印服务。
  • 创建一个封装 DocFlavor 和实际打印数据的 Doc 对象,该对象可以采用多种形式,包括:Postscript 文件、JPEG 图像、URL 或纯文本。
  • 从打印服务获取打印作业,由 DocPrintJob 表示。
  • 调用打印作业的打印方法。

以下代码示例演示了 Java 打印服务 API 的典型用法:找到可以在 A4 纸上打印五份 Postscript 文档双面副本的打印机,从返回的打印服务之一创建打印作业,以及调用打印。

FileInputStream psStream; 

try { 
  psStream = new FileInputStream("file.ps");
} catch (FileNotFoundException ffne) {
} 

if (psStream == null) { 
  return;
}

DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT; 
Doc myDoc = new SimpleDoc(psStream, psInFormat, null); 
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); 
aset.add(new Copies(5)); 
aset.add(MediaSize.A4); 
aset.add(Sides.DUPLEX); 

PrintService[] services = PrintServiceLookup.lookupPrintServices(psInFormat, aset); > 
if (services.length > 0) { 
  DocPrintJob job = services[0].createPrintJob(); 

  try {
    job.print(myDoc, aset); 
  } catch (PrintException pe) {
  }
} 

如果上面的代码由 JSF 托管 bean 调用,则无关紧要。毕竟只是Java。您可能只想修改DocFlavor 和其他设置。

【讨论】:

  • 客户端做不到,但后端服务器进程也不能打印,我一点都不奇怪?
  • 仅当打印机连接到网络服务器时。
  • 哦,好吧,那和普通的Java没有什么不同。使用javax.print API。如果该 Java 代码位于 JSF 托管 bean 或带有 main() 的普通 Java 应用程序中,则无关紧要。您可以在我的答案中链接的 API 包摘要底部找到代码示例。
  • 看起来我应该使用“JasperExportManager.exportReportToPdfStream(jasperPrintObject, externalContext.getResponseOutputStream());”生成一个 PDF,但是 Glassfish 正在抛出“getOutputStream() 已经为此响应调用”。这是一个无效动作,所以它不应该有一个动作也试图生成会干扰的输出?即使我最终直接使用打印机,将 PDF 显示在屏幕上似乎也是一个很好的测试步骤,所以我先从上面尝试您的示例!
  • @BrianKnoblauch 此外,您可以阅读这篇描述如何为报告设置预定义打印机选项的文章:blog.marcnuri.com/blog/rss/2007/03/22/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多