锐浪报表WEB开发
Posted 连先森
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了锐浪报表WEB开发相关的知识,希望对你有一定的参考价值。
下载地址:http://www.rubylong.cn/download/Grid++Report6.zip
using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Web; using System.Configuration; using System.IO; using System.IO.Compression; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.htmlControls; using System.Data.OleDb; namespace QianxunApplication.Common { ///////////////////////////////////////////////////////////////////////////////////////////////////////// //以下枚举指定报表数据的格式类型 public enum ResponseDataType { PlainText, //报表数据为XML或JSON文本,在调试时可以查看报表数据。数据未经压缩,大数据量报表采用此种方式不合适 ZipBinary, //报表数据为XML或JSON文本经过压缩得到的二进制数据。此种方式数据量最小(约为原始数据的1/10),但用Ajax方式加载报表数据时不能为此种方式 ZipBase64, //报表数据为将 ZipBinary 方式得到的数据再进行 BASE64 编码的数据。此种方式适合用Ajax方式加载报表数据 }; ///////////////////////////////////////////////////////////////////////////////////////////////////////// // ReportQueryItem public class ReportQueryItem { public string QuerySQL; public string RecordsetName; public ReportQueryItem(string AQuerySQL, string ARecordsetName) { QuerySQL = AQuerySQL; RecordsetName = ARecordsetName; } }; ///////////////////////////////////////////////////////////////////////////////////////////////////////// // ReportDataBase public class ReportDataBase { //指定报表的默认数据类型,便于统一定义整个报表系统的数据类型 //在报表开发调试阶段,通常指定为 ResponseDataType.PlainText, 以便在浏览器中查看响应的源文件时能看到可读的文本数据 //在项目部署时,通常指定为 ResponseDataType.ZipBinary 或 ResponseDataType.ZipBase64,这样可以极大减少数据量,提供报表响应速度 public const ResponseDataType DefaultDataType = ResponseDataType.PlainText; //PlainText ZipBinary ZipBase64 //将报表XML数据文本输出到HTTP请求 public static void ResponseData(System.Web.UI.Page DataPage, ref string DataText, ResponseDataType DataType) { //报表XML数据的前后不能附加任何其它数据,否则XML数据将不能成功解析,所以调用ClearContent方法清理网页中前面多余的数据 DataPage.Response.ClearContent(); if (ResponseDataType.PlainText == DataType) { // 把xml对象发送给客户端 //DataPage.Response.ContentType = "text/xml"; DataPage.Response.Write(DataText); } else { //将string数据转换为byte[],以便进行压缩 System.Text.UTF8Encoding converter = new System.Text.UTF8Encoding(); byte[] XmlBytes = converter.GetBytes(DataText); //在 HTTP 头信息中写入报表数据压缩信息 DataPage.Response.AppendHeader("gr_zip_type", "deflate"); //指定压缩方法 DataPage.Response.AppendHeader("gr_zip_size", XmlBytes.Length.ToString()); //指定数据的原始长度 DataPage.Response.AppendHeader("gr_zip_encode", converter.HeaderName); //指定数据的编码方式 utf-8 utf-16 ... // 把压缩后的xml数据发送给客户端 if (ResponseDataType.ZipBinary == DataType) { DeflateStream compressedzipStream = new DeflateStream(DataPage.Response.OutputStream, CompressionMode.Compress, true); compressedzipStream.Write(XmlBytes, 0, XmlBytes.Length); compressedzipStream.Close(); } else //ResponseDataType.ZipBase64 { MemoryStream memStream = new MemoryStream(); DeflateStream compressedzipStream = new DeflateStream(memStream, CompressionMode.Compress, true); compressedzipStream.Write(XmlBytes, 0, XmlBytes.Length); compressedzipStream.Close(); //这句很重要,这样数据才能全部写入 MemoryStream // Read bytes from the stream. memStream.Seek(0, SeekOrigin.Begin); // Set the position to the beginning of the stream. int count = (int)memStream.Length; byte[] byteArray = new byte[count]; count = memStream.Read(byteArray, 0, count); string Base64Text = Convert.ToBase64String(byteArray); DataPage.Response.Write(Base64Text); } } //报表XML数据的前后不能附加任何其它数据,否则XML数据将不能成功解析,所以调用End方法放弃网页中后面不必要的数据 DataPage.Response.End(); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////// //class XMLReportData 产生报表需要的xml数据 public class XMLReportData { //根据 DataSet 产生提供给报表需要的XML数据,参数DataType指定压缩编码数据的形式 public static void GenDataSet(System.Web.UI.Page DataPage, DataSet ReportDataSet, ResponseDataType DataType) { string XMLText = ReportDataSet.GetXml(); ReportDataBase.ResponseData(DataPage, ref XMLText, DataType); } //根据 DataTable 产生提供给报表需要的XML数据,参数DataType指定压缩编码数据的形式 public static void GenDataTable(System.Web.UI.Page DataPage, DataTable mydt, ResponseDataType DataType) { DataSet ds = new DataSet(); ds.Tables.Add(mydt); GenDataSet(DataPage, ds, DataType); } //根据IDataReader, 产生提供给报表需要的XML数据,其中的空值字段也会产生XML节点,参数DataType指定压缩编码数据的形式 public static void GenNodeXmlDataFromReader(System.Web.UI.Page DataPage, IDataReader dr, ResponseDataType DataType) { string XMLText = "<xml>\\n"; while (dr.Read()) { XMLText += "<row>"; for (int i = 0; i < dr.FieldCount; ++i) { string FldName = dr.GetName(i); if (FldName == "") FldName = "Fld" + i; XMLText += String.Format("<{0}>{1}</{0}>", FldName, HttpUtility.HtmlEncode(dr.GetValue(i).ToString())); } XMLText += "</row>\\n"; } XMLText += "</xml>\\n"; ReportDataBase.ResponseData(DataPage, ref XMLText, DataType); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////// //class JSONReportData 产生报表需要的 JSON 格式数据 public class JSONReportData { //根据 DataSet 产生提供给报表需要的JSON数据,参数DataType指定压缩编码数据的形式 public static void GenDataSet(System.Web.UI.Page DataPage, DataSet ReportDataSet, ResponseDataType DataType) { string Out = GenDetailText(ReportDataSet); ReportDataBase.ResponseData(DataPage, ref Out, DataType); } //根据 DataTable 产生提供给报表需要的JSON数据,参数DataType指定压缩编码数据的形式 public static void GenDataTable(System.Web.UI.Page DataPage, DataTable dt, ResponseDataType DataType) { DataSet ds = new DataSet(); ds.Tables.Add(dt); GenDataSet(DataPage, ds, DataType); } //根据 DataSet 产生提供给报表需要的JSON文本数据 public static string GenDetailText(DataSet ds) { //如果这里编译不过,请将项目属性的“生成->目标 Framework”设置为“.Net FrameWork4”或更高版本 System.ServiceModel.Dispatcher.JsonQueryStringConverter jqsc = new System.ServiceModel.Dispatcher.JsonQueryStringConverter(); StringBuilder sbJSONText = new StringBuilder("{\\n"); foreach (DataTable dt in ds.Tables) { //"recordset":[ sbJSONText.Append(\'"\'); sbJSONText.Append(dt.TableName); sbJSONText.Append("\\":[\\n"); foreach (DataRow dr in dt.Rows) { sbJSONText.Append(\'{\'); for (int i = 0; i < dt.Columns.Count; ++i) { if (!dr.IsNull(i)) { //用 ConvertValueToString 转换,这样数字类型才不会加引号 //如果日期类型也用ConvertValueToString转换,则为 "\\/Date(-152438400000+0800)\\/" 这样的形式 string Value; if (dt.Columns[i].DataType.IsArray) { Value = "\\"" + Convert.ToBase64String((byte[])dr[i]) + "\\""; } else if (dt.Columns[i].DataType == typeof(System.DateTime)) { Value = "\\"" + dr[i].ToString() + "\\""; } else { Value = jqsc.ConvertValueToString(dr[i], dt.Columns[i].DataType); } sbJSONText.AppendFormat("\\"{0}\\":{1},", dt.Columns[i].ColumnName, Value); } } sbJSONText.Remove(sbJSONText.Length - 1, 1); //去掉每笔记录最后一个字段后面的"," sbJSONText.Append("},\\n"); } if (dt.Rows.Count > 0) //如果无明细记录,则不要回退 sbJSONText.Remove(sbJSONText.Length - 2, 1); //去掉最后一条记录后面的"," sbJSONText.Append("],\\n"); } sbJSONText.Remove(sbJSONText.Length - 2, 1); //去掉最后一记录集后面的"," sbJSONText.Append("}"); return sbJSONText.ToString(); } ////如果数据中包含有JSON规范中的特殊字符(" \\ \\r \\n \\t),多特殊字符加 \\ 编码 //public static void PrepareValueText(ref string ValueText) //{ // bool HasSpecialChar = false; // foreach(char ch in ValueText) // { // if (ch == \'"\' || ch == \'\\\\\' || ch == \'\\r\' || ch == \'\\n\' || ch == \'\\t\') // { // HasSpecialChar = true; // break; // } // } // if (HasSpecialChar) // { // StringBuilder NewValueText = new StringBuilder(); // foreach (char ch in ValueText) // { // if (ch == \'"\' || ch == \'\\\\\' || ch == \'\\r\' || ch == \'\\n\' || ch == \'\\t\') // { // NewValueText.Append( \'\\\\\'); // if (ch == \'"\' || ch == \'\\\\\') // NewValueText.Append( ch ); // else if (ch == \'\\r\') // NewValueText.Append( \'r\' ); // else if (ch == \'\\n\') // NewValueText.Append( \'n\' ); // else if (ch == \'\\t\') // NewValueText.Append( \'t\' ); // } // else // { // NewValueText.Append( ch ); // } // } // ValueText = NewValueText.ToString(); // } //} } public class SqlReportData { //★特别提示★: //连接SQL Server数据库的连接串,应该修改为与实际一致。如果是运行Grid++Report本身的例子,应该首先附加例子数据库到 //SQL Server2000/2005数据库上。 //public const string SqlConnStr = "Data Source=(local);Initial Catalog=gridreport;Persist Security Info=True;User ID=sa;Password=;"; //public const string SqlConnStr = "Data Source=localhost;Initial Catalog=JiangZaiHua;User Id=Sa;Password=6665508a;"; public const string SqlConnStr = "Data Source=118.190.22.134,15427;Initial Catalog=JiangZaiHua;User Id=Sa;Password=Ukk`]wqzZNeN5hko;"; //定义在SQL中表示日期值的包围符号,Access用“#”, 而MS SQl Server用“\'”,为了生成两者都可用的查询SQL语句,将其参数化定义出来。这样处理只是为了演示例子方便 public const char DateSqlBracketChar = \'\\\'\'; //根据查询SQL,产生提供给报表生成需要的 XML 数据,字段值为空也产生数据 public static void FullGenNodeXmlData(System.Web.UI.Page DataPage, string QuerySQL, bool ToCompress) { SqlConnection ReportConn = new SqlConnection(SqlConnStr); SqlCommand ReportDataCommand = new SqlCommand(QuerySQL, ReportConn); ReportConn.Open(); SqlDataReader ReportDataReader = ReportDataCommand.ExecuteReader(); XMLReportData.GenNodeXmlDataFromReader(DataPage, ReportDataReader, ToCompress ? ResponseDataType.ZipBinary : ResponseDataType.PlainText); ReportDataReader.Close(); ReportConn.Close(); } //获取 Count(*) SQL 查询到的数据行数。参数 QuerySQL 指定获取报表数据的查询SQL public static int BatchGetDataCount(string QuerySQL) { int Total = 0; SqlConnection ReportConn = new SqlConnection(SqlConnStr); SqlCommand ReportDataCommand = new SqlCommand(QuerySQL, ReportConn); ReportConn.Open(); SqlDataReader ReportDataReader = ReportDataCommand.ExecuteReader(); if (ReportDataReader.Read()) Total = ReportDataReader.GetInt32(0); ReportDataReader.Close(); ReportConn.Close(); return Total; } //<<protected function //根据查询SQL,产生提供给报表生成需要的 XML 或 JSON 数据 protected static void DoGenDetailData(System.Web.UI.Page DataPage, string QuerySQL, ResponseDataType DataType, bool IsJSON) { SqlConnection ReportConn = new SqlConnection(SqlConnStr); SqlDataAdapter ReportDataAdapter = new SqlDataAdapter(QuerySQL, ReportConn); DataSet ReportDataSet = new DataSet(); ReportConn.Open(); ReportDataAdapter.Fill(ReportDataSet); ReportConn.Close(); if (IsJSON) JSONReportData.GenDataSet(DataPage, ReportDataSet, DataType); else XMLReportData.GenDataSet(DataPage, ReportDataSet, DataType); } //>>protected function //特别提示:以下函数为兼容以前版本而保留,请勿再用之,无须兼容考虑可删除之 //<<保留前面版本的函数,兼容以前版本所写程序 //根据查询SQL,产生提供给报表生成需要的 XML 数据,采用 Sql 数据引擎 public static void GenNodeXmlData(System.Web.UI.Page DataPage, string QuerySQL, bool ToCompress) { DoGenDetailData(DataPage, QuerySQL, ToCompress ? ResponseDataType.ZipBinary : ResponseDataType.PlainText, false); } //根据查询SQL,产生提供给报表生成需要的 XML 数据,采用 Sql 数据引擎, 这里只产生报表参数数据 //当报表没有明细时,调用本方法生成数据,查询SQL应该只能查询出一条记录 public static void GenParameterReportData(System.Web.UI.Page DataPage, string ParameterQuerySQL) { DoGenDetailData(DataPage, ParameterQuerySQL, ResponseDataType.PlainText, false); } //根据查询SQL,产生提供给报表生成需要的 XML 数据,采用 Sql 数据引擎, 根据RecordsetQuerySQL获取报表明细数据,根据ParameterQuerySQL获取报表参数数据 public static void GenEntireReportData(System.Web.UI.Page DataPage, string RecordsetQuerySQL, string ParameterQuerySQL, bool ToCompress) { SqlConnection ReportConn = new SqlConnection(SqlConnStr); DataSet ReportDataSet = new DataSet(); ReportConn.Open(); SqlDataAdapter DataAdapter1 = new SqlDataAdapter(RecordsetQuerySQL, ReportConn); DataAdapter1.Fill(ReportDataSet, "Detail"); SqlDataAdapter DataAdapter2 = new SqlDataAdapter(ParameterQuerySQL, ReportConn); DataAdapter2.Fill(ReportDataSet, "Master"); ReportConn.Close(); XMLReportData.GenDataSet(DataPage, ReportDataSet, ReportDataBase.DefaultDataType); } //>>保留前面版本的函数,兼容以前版本所写程序 } ///////////////////////////////////////////////////////////////////////////////////////////////////////// //class SqlXMLReportData 根据SQL产生报表需要的 XML 数据,采用 Sql 数据引擎 public class SqlXMLReportData : SqlReportData { public static void GenOneRecordset(System.Web.UI.Page DataPage, string QuerySQL) { SqlReportData.DoGenDetailData(DataPage, QuerySQL, ReportDataBase.DefaultDataType, false); } public static void GenMultiRecordset(System.Web.UI.Page DataPage, ArrayList QueryList) { SqlConnection ReportConn = new SqlConnection(SqlConnStr); DataSet ReportDataSet = new DataSet(); ReportConn.Open(); foreach (ReportQueryItem item in QueryList) { SqlDataAdapter DataAdapter = new SqlDataAdapter(item.QuerySQL, ReportConn); DataAdapter.Fill(ReportDataSet, item.RecordsetName); } ReportConn.Close(); XMLReportData.GenDataSet(DataPage, ReportDataSet, ReportDataBase.DefaultDataType); } //特别提示:以下函数为兼容以前版本而保留,请勿再用之,无须兼容考虑可删除之 //<<保留前面版本的函数,兼容以前版本所写程序 //产生报表明细记录数据,数据将被加载到明细网格的记录集中 public static void GenDetailData(System.Web.UI.Page DataPage, string QuerySQL) { GenOneRecordset(DataPage, QuerySQL); } //这里只产生报表参数数据,数据加载到报表参数、非明细网格中的部件框中 //当报表没有明细时,调用本方法生成数据,查询SQL应该只能查询出一条记录 public static void GenParameterData(System.Web.UI.Page DataPage, string ParameterQuerySQL) { GenOneRecordset(DataPage, ParameterQuerySQL); } //根据RecordsetQuerySQL获取报表明细数据,对应数据加载到报表的明细网格的记录集中 //根据ParameterQuerySQL获取报表参数数据,对应数据加载到报表参数、非明细网格中的部件框中 public static void GenEntireData(System.Web.UI.Page DataPage, string RecordsetQuerySQL, string ParameterQuerySQL, ResponseDataType DataType) { ArrayList QueryList = new ArrayList(); QueryList.Add(new ReportQueryItem(RecordsetQuerySQL, "Detail")); QueryList.Add(new ReportQueryItem(ParameterQuerySQL, "Master")); GenMultiRecordset(DataPage, QueryList); } public static void GenEntireData(System.Web.UI.Page DataPage, string RecordsetQuerySQL, string ParameterQuerySQL) { GenEntireData(DataPage, RecordsetQuerySQL, ParameterQuerySQL, ReportDataBase.DefaultDataType); } //>>保留前面版本的函数,兼容以前版本所写程序 } ///////////////////////////////////////////////////////////////////////////////////////////////////////// //class SqlJsonReportData 根据SQL产生报表需要的 JSON 数据,采用 Sql 数据引擎 public class SqlJsonReportData : SqlReportData { public static void GenOneRecordset(System.Web.UI.Page DataPage, string QuerySQL) { SqlReportData.DoGenDetailData(DataPage, QuerySQL, ReportDataBase.DefaultDataType, true); } public static void GenMultiRecordset(System.Web.UI.Page DataPage, ArrayList QueryList) { SqlConnection ReportConn = new SqlConnection(SqlConnStr); DataSet ReportDataSet = new DataSet(); ReportConn.Open(); foreach (ReportQueryItem item in QueryList) { SqlDataAdapter DataAdapter = new SqlDataAdapter(item.QuerySQL, ReportConn); DataAdapter.Fill(ReportDataSet, item.RecordsetName); } ReportConn.Close(); JSONReportData.GenDataSet(DataPage, ReportDataSet, ReportDataBase.DefaultDataType); } //特别提示:以下函数为兼容以前版本而保留,请勿再用之,无须兼容考虑可删除之 //<<保留前面版本的函数,兼容以前版本所写程序 //产生报表明细记录数据,数据将被加载到明细网格的记录集中 public static void GenDetailData(System.Web.UI.Page DataPage, string QuerySQL) { GenOneRecordset(DataPage, QuerySQL); } //这里只产生报表参数数据,数据将加载到报表参数、非明细网格中的部件框中 //当报表没有明细时,调用本方法生成数据,查询SQL应该只能查询出一条记录 public static void GenParameterData(System.Web.UI.Page DataPage, string ParameterQuerySQL) { GenOneRecordset(DataPage, ParameterQuerySQL); } //根据RecordsetQuerySQL获取报表明细数据,对应数据加载到报表的明细网格的记录集中 //根据ParameterQuerySQL获取报表参数数据,对应数据加载到报表参数、非明细网格中的部件框中 public static void GenEntireData(System.Web.UI.Page DataPage, string RecordsetQuerySQL, string ParameterQuerySQL, ResponseDataType DataType) { ArrayList QueryList = new ArrayList(); QueryList.Add(new ReportQueryItem(RecordsetQuerySQL, "Detail")); QueryList.Add(new ReportQueryItem(ParameterQuerySQL, "Master")); GenMultiRecordset(DataPage, QueryList); } public static void GenEntireData(System.Web.UI.Page DataPage, string RecordsetQuerySQL, string ParameterQuerySQL) { GenEntireData(DataPage, RecordsetQuerySQL, ParameterQuerySQL, ReportDataBase.DefaultDataType); } //>>保留前面版本的函数,兼容以前版本所写程序 } ///////////////////////////////////////////////////////////////////////////////////////////////////////// //class OledbReportData 产生提供给报表生成需要的 XML 或 JSON 数据,采用 OleDb 数据引擎 public class OledbReportData { //★特别提示★: //连接Grid++Report Access例子数据库的连接串,应该修改为与实际一致,如果安装目录不在C:\\Grid++Report 5.0,应进行修改。 public const string OleDbConnStr = @"Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=C:\\Grid++Report 6\\Samples\\Data\\Northwind.mdb"; //定义在SQL中表示日期值的包围符号,Access用“#”, 而MS SQl Server用“\'”,为了生成两者都可用的查询SQL语句,将其参数化定义出来。这样处理只是为了演示例子方便 public const char DateSqlBracketChar = \'#\'; //根据查询SQL,产生提供给报表生成需要的 XML 数据,字段值为空也产生数据 public static void FullGenNodeXmlData(System.Web.UI.Page DataPage, string QuerySQL, bool ToCompress) { OleDbConnection ReportConn = new OleDbConnection(OleDbConnStr); OleDbCommand ReportDataCommand = new OleDbCommand(QuerySQL, ReportConn); ReportConn.Open(); OleDbDataReader ReportDataReader = ReportDataCommand.ExecuteReader(); XMLReportData.GenNodeXmlDataFromReader(DataPage, ReportDataReader, ToCompress ? ResponseDataType.ZipBinary : ResponseDataType.PlainText); ReportDataReader.Close(); ReportConn.Close(); } //获取 Count(*) SQL 查询到的数据行数。参数 QuerySQL 指定获取报表数据的查询SQL public static int BatchGetDataCount(string QuerySQL) { int Total = 0; OleDbConnection ReportConn = new OleDbConnection(OleDbConnStr); OleDbCommand ReportDataCommand = new OleDbCommand(QuerySQL, ReportConn); ReportConn.Open(); OleDbDataReader ReportDataReader = ReportDataCommand.ExecuteReader(); if (ReportDataReader.Read()) Total = ReportDataReader.GetInt32(0); ReportDataReader.Close(); ReportConn.Close(); return Total; } //<<protected function //根据查询SQL,产生提供给报表生成需要的 XML 或 JSON 数据 protected static void DoGenDetailData(System.Web.UI.Page DataPage, string QuerySQL, ResponseDataType DataType, bool IsJSON) { OleDbConnection ReportConn = new OleDbConnection(OleDbConnStr); OleDbDataAdapter ReportDataAdapter = new OleDbDataAdapter(QuerySQL, ReportConn); DataSet ReportDataSet = new DataSet(); ReportConn.Open(); ReportDataAdapter.Fill(ReportDataSet); ReportConn.Close(); if (IsJSON) JSONReportData.GenDataSet(DataPage, ReportDataSet, DataType); else XMLReportData.GenDataSet(DataPage, ReportDataSet, DataType); } //>>protected function 以上是关于锐浪报表WEB开发的主要内容,如果未能解决你的问题,请参考以下文章