1. 程式人生 > >解決Jasperreport的web列印另一種方法

解決Jasperreport的web列印另一種方法

    昨天下了jasperreport的最新版本3.7.3看了下。弄了半天還是沒能習慣他的報表製作方式。看了下他的列印是利用applet的來列印的。而且還需要客戶端安裝 十幾MB的 jre 關於這個好壞,每個人都有自己的看法。今天我這裡要說的是利用jatoolsprinter控制元件來列印jasperreport的報表。控制元件大小隻有100k左右         關於jasperreport的報表製作這裡不做說明,我是在環境中跑了下jasperreport的demo執行介面如下
 

執行JSP Example 如下圖
 
下面我們對demo中的html.jsp進行修改 用jatoolsprinter來列印Jasperreport 的報表
藍色部分為控制元件需要的內容
<%@ page contentType="text/html; charset=gb2312" language="java" %>


<%@ page errorPage="error.jsp" %>
<%@ page import="datasource.*" %>
<%@ page import="net.sf.jasperreports.engine.*" %>
<%@ page import="net.sf.jasperreports.engine.util.*" %>
<%@ page import="net.sf.jasperreports.engine.export.*" %>
<%@ page import="net.sf.jasperreports.j2ee.servlets.*" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>
<html>
<head>

<!-- 插入列印控制元件 -->
<OBJECT ID="jatoolsPrinter" CLASSID="CLSID:B43D3361-D975-4BE2-87FE-057188254255" 
codebase="jatoolsPrinter.cab#version=5,3,0,0"></OBJECT>
</head>
<script type="text/javascript">
function doPrint(how)
{
    
//列印文件物件
    var myDoc ={ 
        documents: document,    // 列印頁面(div)們在本文件中
        copyrights :    '傑創軟體擁有版權 
[url=]www.jatools.com'[/url]              // 
       };
         
    // 呼叫列印方法
    if(how == '列印預覽...')
    jatoolsPrinter.printPreview(myDoc,true );   // 列印預覽
                 
   else if(how == '列印...')
      jatoolsPrinter.print(myDoc ,true);   // 列印前彈出列印設定對話方塊
                
   else
      jatoolsPrinter.print(myDoc ,false);       // 不彈出對話方塊列印
}
</script>
<body>

<br>
<input type="button" value="列印預覽...">
<input type="button" value="列印...">
<input type="button" value="列印">
<br>


<%
File reportFile = new File(application.getRealPath("/reports/WebappReport.jasper"));
    if (!reportFile.exists())
   throw new JRRuntimeException("File WebappReport.jasper not found. The report design must be compiled first.");
JasperReport jasperReport = (JasperReport)JRLoader.loadObject(reportFile.getPath());
Map parameters = new HashMap();
parameters.put("ReportTitle", "Address Report");
parameters.put("BaseDir", reportFile.getParentFile());
    
JasperPrint jasperPrint = 
   JasperFillManager.fillReport(
    jasperReport, 
    parameters, 
    new WebappDataSource()
    );
    
JRHtmlExporter exporter = new JRHtmlExporter();
session.setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);

exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);
exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "../servlets/image?image=");

exporter.exportReport();
%>
</body>
</html>


因為jatoolsprinter的列印是根據<div id='page'+數字>來區分列印的頁的。而Jasperreport生成的html頁面中又沒有包含這些資訊,所以我們就需要修改下Jasperreport的原始碼
由生成的報表頁面的原始碼中我們可以看到Jasperreport是利用<a name="JR_PAGE_ANCHOR_?_?"></a>來區分頁數的我們可以找到package net.sf.jasperreports.engine.export 下的JRHtmlExporter.java 找到程式碼中的exportReportToWriter方法裡的如下片段
writer.write("<a name=/"" + JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + (pageIndex + 1) + "/"></a>/n");
在這段程式碼之後加上
writer.write("<div id='page"+ (pageIndex + 1)+"'>/n");
然後找到原始碼中的
exportPage(page);
在他之後加上div的結束標誌
writer.write("</div>/n");
以上程式碼藍色部分為後新增的內容


修改之後的程式碼如下
writer.write("<a name=/"" + JR_PAGE_ANCHOR_PREFIX + reportIndex + "_" + (pageIndex + 1) + "/"></a>/n");
     
     writer.write("<div id='page"+ (pageIndex + 1)+"'>/n");
     

      /*   */
      exportPage(page);
     
     
writer.write("</div>/n");
修改完這些之後我們就把jatoolsPrinter.cab放在專案中html.jsp 
<OBJECT ID="jatoolsPrinter" CLASSID="CLSID:B43D3361-D975-4BE2-87FE-057188254255" 
codebase="jatoolsPrinter.cab#version=5,3,0,0"></OBJECT>


codebase指定的位置這裡指定的是和html.jsp同一路徑
 
現在開啟IE 執行 demo
第一次執行會提示安裝jatoolsprinter控制元件 選擇安裝ActiveX控制元件

 
點選安裝

 
點選列印預覽效果如下
 


到此就可以在web頁面中直接列印Jasperreport 報表了。