在.net中,你可以很容易的用sql语句过滤报表数据,但在CR4E中没这样的功能设定,但可以通过编写代码完成。
这里是我做的简单用sql语句过滤数据的例子。
项目还是用(二)里面的tomcat项目。
建一个实现这个功能的类
JRC_ResultSet_DataSource.java
package
com.JRC.util;
import
java.sql.
*
;
import
javax.servlet.http.
*
;
import
com.crystaldecisions.reports.sdk.
*
;
import
com.crystaldecisions.sdk.occa.report.lib.
*
;
public
class
JRC_ResultSet_DataSource
{ private String REPORT_NAME=""; public JRC_ResultSet_DataSource(String report_name){ this.REPORT_NAME=report_name; } /** *//** * @return rEPORT_NAME */ public String getREPORT_NAME() { return REPORT_NAME; } /** *//** * @param report_name 要设置的 rEPORT_NAME */ public void setREPORT_NAME(String report_name) { REPORT_NAME = report_name; } /** *//** * 连接数据库,通过sql查询语句进行查询,返回结果集 */ private static ResultSet getResultSetFromQuery(String query, int scrollType) throws SQLException, ClassNotFoundException{ Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); final String DBUSERNAME = "username"; final String DBPASSWORD = "password"; final String CONNECTION_URL = "jdbc:microsoft:sqlserver://localhost:1433;database=dname"; java.sql.Connection connection = DriverManager.getConnection(CONNECTION_URL, DBUSERNAME, DBPASSWORD); Statement statement = connection.createStatement(scrollType, ResultSet.CONCUR_READ_ONLY); return statement.executeQuery(query); } /** *//** * 通过sql语句过滤报表数据,在.net就不用怎么惨了 */ public boolean isReportSourceInSession(String session_name,HttpSession session) throws ReportSDKException, SQLException, ClassNotFoundException{ boolean flag=false; try { //打开水晶报表 ReportClientDocument reportClientDoc = new ReportClientDocument(); reportClientDoc.open(REPORT_NAME, 0); //sql查询语句,返回的字段数必须跟报表里面的一样,不能多也不能少,并且字段的类型要跟报表的一样,其他不管是什么数据都可以 //from 表这里要填完整,如数据库名.dbo.数据库表,最好做个别名 String query = "select tt.test_1,tt.test_2,tt.test_3,tt.test_4 from dname.dbo.test tt"; ResultSet resultSet = this.getResultSetFromQuery(query,ResultSet.TYPE_SCROLL_INSENSITIVE); String tableAlias = reportClientDoc.getDatabaseController().getDatabase().getTables().getTable(0).getAlias(); //把结果集放进报表里,将会自动产生一个datasource reportClientDoc.getDatabaseController().setDataSource(resultSet,tableAlias, "resultsetTable"); session.setAttribute(session_name, reportClientDoc.getReportSource()); flag=true; return flag; } catch (Exception e){ // TODO: handle exception e.printStackTrace(); return flag; } } }
这里要注意数据库查询结果集的字段数目要跟报表里面的字段数目一样,类型也要一样,不然就会出错。
sql语句中的表的名字要完整,如数据库名.dbo.数据库表,最好做个别名
显示页面
Result_viewer.jsp
<%
@page
import
=
"
com.JRC.util.JRC_ResultSet_DataSource
"
%>
<%--
webreporting.jar
--%>
<%
@page
import
=
"
com.crystaldecisions.report.web.viewer.*
"
%>
<%--
jrcerom.jar
--%>
<%
@ page
import
=
"
com.crystaldecisions.reports.sdk.*
"
%>
<%
JRC_ResultSet_DataSource jrcd
=
new
JRC_ResultSet_DataSource(
"
resultSet.rpt
"
);
if
(
!
jrcd.isReportSourceInSession(
"
reportSource
"
,session) response.sendRedirect(
"
error.html
"
); CrystalReportViewer crViewer
=
new
CrystalReportViewer(); crViewer.setOwnPage(
true
); crViewer.setOwnForm(
true
); crViewer.setPrintMode(CrPrintMode.ACTIVEX); Object reportSource
=
session.getAttribute(
"
reportSource
"
); crViewer.setReportSource(reportSource); crViewer.processHttpRequest(request,response,
this
.getServletConfig().getServletContext(),
null
);
%>
注意上面几点应该就没问题了
注意: 大家在完成数据查询后,记得关闭resultset,statement 和 connection,在不使用报表后要把session里面的报表数据清除。
PS:Snippets视图最下面有Crystal reports的一些实用代码段
CR查看器标记、打开并查询报表、打开报表、查看报表、查看报表并设置数据库登录、将报表导出为pdf、将报表导出为rtf 等的代码段,简单易用