25 changed files with 5269 additions and 0 deletions
@ -0,0 +1,25 @@ |
|||
|
|||
Microsoft Visual Studio Solution File, Format Version 12.00 |
|||
# Visual Studio Version 16 |
|||
VisualStudioVersion = 16.0.31515.178 |
|||
MinimumVisualStudioVersion = 10.0.40219.1 |
|||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebApplicationGridJJReport", "WebApplicationGridJJReport\WebApplicationGridJJReport.csproj", "{BF0F3ED4-41A8-4AD4-9C8E-EE7112151620}" |
|||
EndProject |
|||
Global |
|||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
|||
Debug|Any CPU = Debug|Any CPU |
|||
Release|Any CPU = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
|||
{BF0F3ED4-41A8-4AD4-9C8E-EE7112151620}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
|||
{BF0F3ED4-41A8-4AD4-9C8E-EE7112151620}.Debug|Any CPU.Build.0 = Debug|Any CPU |
|||
{BF0F3ED4-41A8-4AD4-9C8E-EE7112151620}.Release|Any CPU.ActiveCfg = Release|Any CPU |
|||
{BF0F3ED4-41A8-4AD4-9C8E-EE7112151620}.Release|Any CPU.Build.0 = Release|Any CPU |
|||
EndGlobalSection |
|||
GlobalSection(SolutionProperties) = preSolution |
|||
HideSolutionNode = FALSE |
|||
EndGlobalSection |
|||
GlobalSection(ExtensibilityGlobals) = postSolution |
|||
SolutionGuid = {94C38E90-2D92-4F48-A923-4ECF913D03BF} |
|||
EndGlobalSection |
|||
EndGlobal |
@ -0,0 +1,397 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Data; |
|||
using System.Diagnostics; |
|||
using System.IO; |
|||
using System.IO.Compression; |
|||
using System.Linq; |
|||
using System.ServiceModel.Dispatcher; |
|||
using System.Text; |
|||
using System.Web; |
|||
//using CK.SCP.Controller;
|
|||
//using CK.SCP.Models.ScpEntity;
|
|||
//using CK.SCP.Utils;
|
|||
|
|||
namespace SCP.Common |
|||
{ |
|||
|
|||
public enum PrintType |
|||
{ |
|||
BARCODE_CUSTOM=110, |
|||
BARCODE = 101, |
|||
ASN = 102, |
|||
ARRIVE = 103, |
|||
CUSTOM_PAGE = 104, |
|||
ASN_PALLET =107, |
|||
PALLET=105, |
|||
SmallBARCODE = 106, |
|||
} |
|||
public class TextProvider |
|||
{ |
|||
public static string BuildByRequest(HttpRequest p_request) |
|||
{ |
|||
string text = string.Empty; |
|||
if (p_request.Form["dataname"]!=null && !string.IsNullOrEmpty(p_request.Form["dataname"])) |
|||
{ |
|||
text = p_request.Form["dataname"]; |
|||
} |
|||
else |
|||
{ |
|||
//string name = p_request.QueryString["data"];
|
|||
//text = JSONReportData.FromDataSet(GetData(name, p_request));
|
|||
} |
|||
return text; |
|||
} |
|||
|
|||
// private static DataSet GetData(string p_name, HttpRequest p_request)
|
|||
// {
|
|||
// DataSet ds = new DataSet();
|
|||
// switch (int.Parse(p_name))
|
|||
// {
|
|||
// case (int)PrintType.ASN:
|
|||
// ds = GET_ASN(p_request);
|
|||
// break;
|
|||
// case (int)PrintType.BARCODE:
|
|||
// ds = GET_TS_BAR(p_request);
|
|||
// break;
|
|||
// case (int)PrintType.BARCODE_CUSTOM:
|
|||
// ds = GET_TS_BAR_CUSTOM(p_request);
|
|||
// break;
|
|||
// case (int)PrintType.ARRIVE:
|
|||
// ds = GET_ARRIVE(p_request);
|
|||
// break;
|
|||
// case (int)PrintType.CUSTOM_PAGE:
|
|||
// ds =GET_CUSTOM_PAGE(p_request);
|
|||
// break;
|
|||
// case (int)PrintType.ASN_PALLET:
|
|||
// ds = GET_ASN_PALLET(p_request);
|
|||
// break;
|
|||
// case (int)PrintType.PALLET:
|
|||
// ds = GET_TB_PALLETS(p_request);
|
|||
// break;
|
|||
// case (int)PrintType.SmallBARCODE:
|
|||
// ds = GET_TS_BAR_Small(p_request);
|
|||
// break;
|
|||
// }
|
|||
// return ds;
|
|||
// }
|
|||
///// <summary>
|
|||
// /// 获取发货单(带托盘明细的发货单)
|
|||
// /// </summary>
|
|||
// /// <param name="p_request"></param>
|
|||
// /// <returns></returns>
|
|||
// private static DataSet GET_ASN_PALLET(HttpRequest p_request)
|
|||
// {
|
|||
// DataSet ds = new DataSet();
|
|||
// if (!string.IsNullOrEmpty(p_request["AsnBillNum"]))
|
|||
// {
|
|||
// var AskBillNum = p_request["AsnBillNum"].ToString();
|
|||
// ds = SCP_ASN_CONTROLLER.ASN_PALLET_REPORT(AskBillNum);
|
|||
// }
|
|||
// return ds;
|
|||
// }
|
|||
// private static DataSet GET_ASN(HttpRequest p_request)
|
|||
// {
|
|||
// DataSet ds = new DataSet();
|
|||
// if (!string.IsNullOrEmpty(p_request["AsnBillNum"]))
|
|||
// {
|
|||
// var AskBillNum = p_request["AsnBillNum"].ToString();
|
|||
// ds=SCP_ASN_CONTROLLER.ASN_REPORT(AskBillNum);
|
|||
// }
|
|||
// return ds;
|
|||
// }
|
|||
///// <summary>
|
|||
// /// 获取托盘
|
|||
// /// </summary>
|
|||
// /// <param name="p_request"></param>
|
|||
// /// <returns></returns>
|
|||
// private static DataSet GET_TB_PALLETS(HttpRequest p_request)
|
|||
// {
|
|||
// DataSet ds = new DataSet();
|
|||
// TB_PALLETS _pallet = new TB_PALLETS();
|
|||
// if (!string.IsNullOrEmpty(p_request["AsnBillNum"]))
|
|||
// {
|
|||
// _pallet.AsnBillNum = p_request["AsnBillNum"].ToString();
|
|||
// }
|
|||
// if (!string.IsNullOrEmpty(_pallet.AsnBillNum))
|
|||
// {
|
|||
// SCP_PALLET_CONTROLLER.Get_TB_PALLETS_List(_pallet, (ret) =>
|
|||
// {
|
|||
// if (ret.State == ReturnStatus.Succeed)
|
|||
// {
|
|||
// var _ls = ret.Result.DistinctBy(t=>t.PalletNum);
|
|||
// var dt = ConvertHelper.ToDataTable(_ls.ToList());
|
|||
// ds.Tables.Add(dt);
|
|||
// }
|
|||
// });
|
|||
// }
|
|||
// return ds;
|
|||
// }
|
|||
// private static DataSet GET_TS_BAR(HttpRequest p_request)
|
|||
// {
|
|||
// DataSet ds = new DataSet();
|
|||
// TS_BARCODE _bar = new TS_BARCODE();
|
|||
// if (!string.IsNullOrEmpty(p_request["AsnBillNum"]))
|
|||
// {
|
|||
// _bar.BillNum = p_request["AsnBillNum"].ToString();
|
|||
// }
|
|||
// if (!string.IsNullOrEmpty(p_request["Barcode"]))
|
|||
// {
|
|||
// var _ls = p_request["Barcode"].ToString().Split('_').ToList();
|
|||
// _bar.UIDList = new List<long>();
|
|||
// _ls.ForEach(p =>
|
|||
// {
|
|||
// if (!string.IsNullOrEmpty(p))
|
|||
// {
|
|||
// _bar.UIDList.Add(long.Parse(p));
|
|||
// }
|
|||
// });
|
|||
// }
|
|||
// if (!string.IsNullOrEmpty(_bar.BillNum) || _bar.UIDList != null)
|
|||
// {
|
|||
// SCP_TS_BARCODE_CONTROLLER.Get_TS_BARCODE_List(_bar, (ret) =>
|
|||
// {
|
|||
// if (ret.State == ReturnStatus.Succeed)
|
|||
// {
|
|||
// var _ls = ret.Result.ToList();
|
|||
// var _list=_ls.OrderBy(p => p.PartCode).ThenBy(p => p.BarCode).ToList();
|
|||
// var dt = ConvertHelper.ToDataTable(_list);
|
|||
// ds.Tables.Add(dt);
|
|||
// }
|
|||
// });
|
|||
// }
|
|||
|
|||
// return ds;
|
|||
// }
|
|||
|
|||
// private static DataSet GET_TS_BAR_Small(HttpRequest p_request)
|
|||
// {
|
|||
// DataSet ds = new DataSet();
|
|||
// TS_BARCODE_SMALL _bar = new TS_BARCODE_SMALL();
|
|||
// if (!string.IsNullOrEmpty(p_request["AsnBillNum"]))
|
|||
// {
|
|||
// _bar.BillNum = p_request["AsnBillNum"].ToString();
|
|||
// }
|
|||
// if (!string.IsNullOrEmpty(p_request["Barcode"]))
|
|||
// {
|
|||
// var _ls = p_request["Barcode"].ToString().Split('_').ToList();
|
|||
// _bar.UIDList = new List<long>();
|
|||
// _ls.ForEach(p =>
|
|||
// {
|
|||
// if (!string.IsNullOrEmpty(p))
|
|||
// {
|
|||
// _bar.UIDList.Add(long.Parse(p));
|
|||
// }
|
|||
// });
|
|||
// }
|
|||
// if (!string.IsNullOrEmpty(_bar.BillNum) || _bar.UIDList != null)
|
|||
// {
|
|||
// SCP_TS_BARCODE_CONTROLLER.Get_TS_BARCODE_Small_List(_bar, (ret) =>
|
|||
// {
|
|||
// if (ret.State == ReturnStatus.Succeed)
|
|||
// {
|
|||
// var _ls = ret.Result.ToList();
|
|||
// var _list = _ls.OrderBy(p => p.PartCode).ThenBy(p => p.BarCode).ToList();
|
|||
// var dt = ConvertHelper.ToDataTable(_list);
|
|||
// ds.Tables.Add(dt);
|
|||
// }
|
|||
// });
|
|||
// }
|
|||
|
|||
// return ds;
|
|||
// }
|
|||
|
|||
// private static DataSet GET_TS_BAR_CUSTOM(HttpRequest p_request)
|
|||
// {
|
|||
// DataSet ds = new DataSet();
|
|||
// TS_BARCODE_CUSTOM _bar = new TS_BARCODE_CUSTOM();
|
|||
// if (!string.IsNullOrEmpty(p_request["AsnBillNum"]))
|
|||
// {
|
|||
// _bar.BillNum = p_request["AsnBillNum"].ToString();
|
|||
// }
|
|||
// if (!string.IsNullOrEmpty(p_request["Barcode"]))
|
|||
// {
|
|||
// var _ls = p_request["Barcode"].ToString().Split('_').ToList();
|
|||
// _bar.UIDList = new List<long>();
|
|||
// _ls.ForEach(p =>
|
|||
// {
|
|||
// if (!string.IsNullOrEmpty(p))
|
|||
// {
|
|||
// _bar.UIDList.Add(long.Parse(p));
|
|||
// }
|
|||
// });
|
|||
// }
|
|||
// if (!string.IsNullOrEmpty(_bar.BillNum) || _bar.UIDList != null)
|
|||
// {
|
|||
// SCP_TS_BARCODE_CONTROLLER.Get_TS_BARCODE_CUSTOM_List(_bar, (ret) =>
|
|||
// {
|
|||
// if (ret.State == ReturnStatus.Succeed)
|
|||
// {
|
|||
// var _ls = ret.Result.ToList();
|
|||
// var _list = _ls.OrderBy(p => p.PartCode).ThenBy(p => p.BarCode).ToList();
|
|||
// var dt = ConvertHelper.ToDataTable(_list);
|
|||
// ds.Tables.Add(dt);
|
|||
// }
|
|||
// });
|
|||
// }
|
|||
|
|||
// return ds;
|
|||
// }
|
|||
// private static DataSet GET_ARRIVE(HttpRequest p_request)
|
|||
// {
|
|||
// DataSet ds = new DataSet();
|
|||
// if (!string.IsNullOrEmpty(p_request["AsnBillNum"]))
|
|||
// {
|
|||
// var AskBillNum = p_request["AsnBillNum"].ToString();
|
|||
// ds = SCP_ASN_CONTROLLER.ARRIVE_REPORT(AskBillNum);
|
|||
// }
|
|||
// return ds;
|
|||
// }
|
|||
// private static DataSet GET_CUSTOM_PAGE(HttpRequest p_request)
|
|||
// {
|
|||
// DataSet ds = new DataSet();
|
|||
// V_TB_ASN _asn = new V_TB_ASN();
|
|||
// _asn.AsnBillNum= p_request.Params["AsnBillNum"];
|
|||
// var dt=SCP_ASN_CONTROLLER.Get_CUSTOM_PAGE_List(_asn);
|
|||
// ds.Tables.Add(dt);
|
|||
|
|||
// // string _str= ConvertHelper.SerializeObject(_asn);
|
|||
|
|||
|
|||
// return ds;
|
|||
|
|||
// }
|
|||
//class JSONReportData 产生报表需要的 JSON 格式数据
|
|||
public class JSONReportData |
|||
{ |
|||
//根据 DataSet 产生提供给报表需要的JSON文本数据
|
|||
public static string FromDataSet(DataSet ds) |
|||
{ |
|||
JsonQueryStringConverter jqsc = new 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(); |
|||
} |
|||
|
|||
//根据 DataTable 产生提供给报表需要的JSON文本数据
|
|||
public static string FromDataTable(DataTable dt) |
|||
{ |
|||
DataSet ds = new DataSet(); |
|||
ds.Tables.Add(dt); |
|||
return FromDataSet(ds); |
|||
} |
|||
} |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
//以下枚举指定报表数据的格式类型
|
|||
public enum ResponseDataType |
|||
{ |
|||
PlainText, //报表数据为XML或JSON文本,在调试时可以查看报表数据。数据未经压缩,大数据量报表采用此种方式不合适
|
|||
ZipBinary, //报表数据为XML或JSON文本经过压缩得到的二进制数据。此种方式数据量最小(约为原始数据的1/10),但用Ajax方式加载报表数据时不能为此种方式
|
|||
ZipBase64, //报表数据为将 ZipBinary 方式得到的数据再进行 BASE64 编码的数据。此种方式适合用Ajax方式加载报表数据
|
|||
}; |
|||
|
|||
public class GridReportDataResponse |
|||
{ |
|||
//指定报表的默认数据类型,便于统一定义整个报表系统的数据类型
|
|||
//在报表开发调试阶段,通常指定为 ResponseDataType.PlainText, 以便在浏览器中查看响应的源文件时能看到可读的文本数据
|
|||
//在项目部署时,通常指定为 ResponseDataType.ZipBinary 或 ResponseDataType.ZipBase64,这样可以极大减少数据量,提供报表响应速度
|
|||
public const ResponseDataType DefaultDataType = ResponseDataType.PlainText; //PlainText ZipBinary ZipBase64
|
|||
|
|||
//将报表XML数据文本输出到HTTP请求
|
|||
public static void Response(HttpResponse Response, string DataText, ResponseDataType DataType) |
|||
{ |
|||
//报表XML数据的前后不能附加任何其它数据,否则XML数据将不能成功解析,所以调用ClearContent方法清理网页中前面多余的数据
|
|||
Response.ClearContent(); |
|||
|
|||
if (ResponseDataType.PlainText == DataType) |
|||
{ |
|||
// 把 xml 或 json 文本响应给客户端
|
|||
//Response.ContentType = "text/xml";
|
|||
Response.ContentType = "text/plain"; |
|||
Response.Write(DataText); |
|||
} |
|||
else |
|||
{ |
|||
//将string数据转换为byte[],以便进行压缩
|
|||
System.Text.UTF8Encoding converter = new System.Text.UTF8Encoding(); |
|||
byte[] XmlBytes = converter.GetBytes(DataText); |
|||
|
|||
//在 HTTP 头信息中写入报表数据压缩信息
|
|||
Response.AppendHeader("gr_zip_type", "deflate"); //指定压缩方法
|
|||
Response.AppendHeader("gr_zip_size", XmlBytes.Length.ToString()); //指定数据的原始长度
|
|||
Response.AppendHeader("gr_zip_encode", converter.HeaderName); //指定数据的编码方式 utf-8 utf-16 ...
|
|||
|
|||
// 把压缩后的xml数据发送给客户端
|
|||
if (ResponseDataType.ZipBinary == DataType) |
|||
{ |
|||
DeflateStream compressedzipStream = new DeflateStream(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); |
|||
Response.ContentType = "text/plain"; |
|||
Response.Write(Base64Text); |
|||
} |
|||
} |
|||
|
|||
//报表XML数据的前后不能附加任何其它数据,否则XML数据将不能成功解析,所以调用End方法放弃网页中后面不必要的数据
|
|||
Response.End(); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1 @@ |
|||
<%@ WebHandler Language="C#" CodeBehind="Handler1.ashx.cs" Class="WebApplicationGridJJReport.Handlers.Handler1" %> |
@ -0,0 +1,94 @@ |
|||
using GridReport; |
|||
using SCP.Common; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Web; |
|||
using WebApplicationGridJJReport.appcode; |
|||
|
|||
namespace WebApplicationGridJJReport.Handlers |
|||
{ |
|||
/// <summary>
|
|||
/// Handler1 的摘要说明
|
|||
/// </summary>
|
|||
public class Handler1 : IHttpHandler |
|||
{ |
|||
|
|||
public void ProcessRequest(HttpContext context) |
|||
{ |
|||
//取Post参数
|
|||
string text = TextProvider.BuildByRequest(context.Request); |
|||
if (text.Length > 1 && text[0] == '[' && text[text.Length - 1] == ']') |
|||
{ |
|||
text = text.Substring(1); |
|||
text = text.Substring(0, text.Length - 1); |
|||
} |
|||
|
|||
|
|||
string reportType = context.Request.QueryString["report"].ToLower(); |
|||
if (reportType == "menban") |
|||
{ |
|||
if (string.IsNullOrEmpty(text)) |
|||
{ |
|||
text = PostParam.MenBanVal.Replace("'", "\""); |
|||
} |
|||
} |
|||
else if (reportType == "zhuhuban") |
|||
{ |
|||
if (string.IsNullOrEmpty(text)) |
|||
{ |
|||
text = PostParam.ZhuHuBanVal.Replace("'", "\""); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
if (string.IsNullOrEmpty(text)) |
|||
{ |
|||
text = PostParam.ZhuHuBanVal.Replace("'", "\""); |
|||
} |
|||
|
|||
} |
|||
|
|||
ReportGenerator reportGenerator = new ReportGenerator(context); |
|||
|
|||
//#region 加载子报表
|
|||
//if (reportType == "zhuhuban")
|
|||
//{
|
|||
// string[] childReportLst = new string[6] { "1", "2", "3", "4", "5", "6" };
|
|||
// foreach (string childReportName in childReportLst)
|
|||
// {
|
|||
// reportGenerator.LoadChildReport(childReportName);
|
|||
// //reportGenerator.LoadReportData(text);
|
|||
// }
|
|||
//}
|
|||
//#endregion
|
|||
|
|||
|
|||
reportGenerator.LoadReport(); |
|||
reportGenerator.LoadReportData(text); |
|||
|
|||
string returnFile = context.Request.QueryString["returnfile"]; |
|||
if (returnFile == "1") //返回PDF文件流
|
|||
{ |
|||
reportGenerator.Generate(); |
|||
|
|||
} |
|||
else //返回base64字符串
|
|||
{ |
|||
string base64Str = reportGenerator.Generate2(); |
|||
|
|||
context.Response.Write(base64Str); |
|||
context.Response.End(); |
|||
|
|||
} |
|||
} |
|||
|
|||
public bool IsReusable |
|||
{ |
|||
get |
|||
{ |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,35 @@ |
|||
using System.Reflection; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
// 有关程序集的常规信息通过下列特性集
|
|||
// 控制。更改这些特性值可修改
|
|||
// 与程序集关联的信息。
|
|||
[assembly: AssemblyTitle("WebApplicationGridJJReport")] |
|||
[assembly: AssemblyDescription("")] |
|||
[assembly: AssemblyConfiguration("")] |
|||
[assembly: AssemblyCompany("")] |
|||
[assembly: AssemblyProduct("WebApplicationGridJJReport")] |
|||
[assembly: AssemblyCopyright("Copyright © 2021")] |
|||
[assembly: AssemblyTrademark("")] |
|||
[assembly: AssemblyCulture("")] |
|||
|
|||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
|||
// 对 COM 组件不可见。如果需要
|
|||
// 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。
|
|||
[assembly: ComVisible(false)] |
|||
|
|||
// 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID
|
|||
[assembly: Guid("bf0f3ed4-41a8-4ad4-9c8e-ee7112151620")] |
|||
|
|||
// 程序集的版本信息由下列四个值组成:
|
|||
//
|
|||
// 主版本
|
|||
// 次版本
|
|||
// 内部版本号
|
|||
// 修订版本
|
|||
//
|
|||
// 可以指定所有值,也可以使用“修订号”和“内部版本号”的默认值,
|
|||
// 方法是按如下所示使用 "*":
|
|||
[assembly: AssemblyVersion("1.0.0.0")] |
|||
[assembly: AssemblyFileVersion("1.0.0.0")] |
@ -0,0 +1,31 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
|
|||
<!-- 有关使用 web.config 转换的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkId=125889 --> |
|||
|
|||
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> |
|||
<!-- |
|||
在下例中,“SetAttributes”转换将更改 |
|||
“connectionString”的值,以仅在“Match”定位器 |
|||
找到值为“MyDB”的特性“name”时使用“ReleaseSQLServer”。 |
|||
|
|||
<connectionStrings> |
|||
<add name="MyDB" |
|||
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" |
|||
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/> |
|||
</connectionStrings> |
|||
--> |
|||
<system.web> |
|||
<!-- |
|||
|
|||
在下例中,“Replace”转换将替换 |
|||
web.config 文件的整个 <customErrors> 节。 |
|||
请注意,由于 |
|||
在 <system.web> 节点下仅有一个 customErrors 节,因此不需要使用“xdt:Locator”特性。 |
|||
|
|||
<customErrors defaultRedirect="GenericError.htm" |
|||
mode="RemoteOnly" xdt:Transform="Replace"> |
|||
<error statusCode="500" redirect="InternalError.htm"/> |
|||
</customErrors> |
|||
--> |
|||
</system.web> |
|||
</configuration> |
@ -0,0 +1,32 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
|
|||
<!-- 有关使用 web.config 转换的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkId=125889 --> |
|||
|
|||
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> |
|||
<!-- |
|||
在下例中,“SetAttributes”转换将更改 |
|||
“connectionString”的值,以仅在“Match”定位器 |
|||
找到值为“MyDB”的特性“name”时使用“ReleaseSQLServer”。 |
|||
|
|||
<connectionStrings> |
|||
<add name="MyDB" |
|||
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" |
|||
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/> |
|||
</connectionStrings> |
|||
--> |
|||
<system.web> |
|||
<compilation xdt:Transform="RemoveAttributes(debug)" /> |
|||
<!-- |
|||
|
|||
在下例中,“Replace”转换将替换 |
|||
web.config 文件的整个 <customErrors> 节。 |
|||
请注意,由于 |
|||
在 <system.web> 节点下仅有一个 customErrors 节,因此不需要使用“xdt:Locator”特性。 |
|||
|
|||
<customErrors defaultRedirect="GenericError.htm" |
|||
mode="RemoteOnly" xdt:Transform="Replace"> |
|||
<error statusCode="500" redirect="InternalError.htm"/> |
|||
</customErrors> |
|||
--> |
|||
</system.web> |
|||
</configuration> |
@ -0,0 +1,17 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<!-- |
|||
有关如何配置 ASP.NET 应用程序的详细信息,请访问 |
|||
https://go.microsoft.com/fwlink/?LinkId=169433 |
|||
--> |
|||
<configuration> |
|||
<system.web> |
|||
<compilation debug="true" targetFramework="4.5.2" /> |
|||
<httpRuntime targetFramework="4.5.2" /> |
|||
</system.web> |
|||
<system.codedom> |
|||
<compilers> |
|||
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" /> |
|||
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" /> |
|||
</compilers> |
|||
</system.codedom> |
|||
</configuration> |
@ -0,0 +1,140 @@ |
|||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" /> |
|||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
|||
<PropertyGroup> |
|||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
|||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
|||
<ProductVersion> |
|||
</ProductVersion> |
|||
<SchemaVersion>2.0</SchemaVersion> |
|||
<ProjectGuid>{BF0F3ED4-41A8-4AD4-9C8E-EE7112151620}</ProjectGuid> |
|||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids> |
|||
<OutputType>Library</OutputType> |
|||
<AppDesignerFolder>Properties</AppDesignerFolder> |
|||
<RootNamespace>WebApplicationGridJJReport</RootNamespace> |
|||
<AssemblyName>WebApplicationGridJJReport</AssemblyName> |
|||
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion> |
|||
<UseIISExpress>true</UseIISExpress> |
|||
<Use64BitIISExpress /> |
|||
<IISExpressSSLPort>44356</IISExpressSSLPort> |
|||
<IISExpressAnonymousAuthentication /> |
|||
<IISExpressWindowsAuthentication /> |
|||
<IISExpressUseClassicPipelineMode /> |
|||
<UseGlobalApplicationHostFile /> |
|||
<NuGetPackageImportStamp> |
|||
</NuGetPackageImportStamp> |
|||
</PropertyGroup> |
|||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
|||
<DebugSymbols>true</DebugSymbols> |
|||
<DebugType>full</DebugType> |
|||
<Optimize>false</Optimize> |
|||
<OutputPath>bin\</OutputPath> |
|||
<DefineConstants>DEBUG;TRACE</DefineConstants> |
|||
<ErrorReport>prompt</ErrorReport> |
|||
<WarningLevel>4</WarningLevel> |
|||
</PropertyGroup> |
|||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
|||
<DebugSymbols>true</DebugSymbols> |
|||
<DebugType>pdbonly</DebugType> |
|||
<Optimize>true</Optimize> |
|||
<OutputPath>bin\</OutputPath> |
|||
<DefineConstants>TRACE</DefineConstants> |
|||
<ErrorReport>prompt</ErrorReport> |
|||
<WarningLevel>4</WarningLevel> |
|||
</PropertyGroup> |
|||
<ItemGroup> |
|||
<Reference Include="Interop.grsvr6Lib"> |
|||
<HintPath>D:\~LYF\软件安装\闻荫软件安装\SCP(GridJJ_report_project)\SCP\SCP\obj\Debug\Interop.grsvr6Lib.dll</HintPath> |
|||
<EmbedInteropTypes>True</EmbedInteropTypes> |
|||
</Reference> |
|||
<Reference Include="Microsoft.CSharp" /> |
|||
<Reference Include="System.ServiceModel.Web" /> |
|||
<Reference Include="System.Web.DynamicData" /> |
|||
<Reference Include="System.Web.Entity" /> |
|||
<Reference Include="System.Web.ApplicationServices" /> |
|||
<Reference Include="System.ComponentModel.DataAnnotations" /> |
|||
<Reference Include="System" /> |
|||
<Reference Include="System.Data" /> |
|||
<Reference Include="System.Core" /> |
|||
<Reference Include="System.Data.DataSetExtensions" /> |
|||
<Reference Include="System.Web.Extensions" /> |
|||
<Reference Include="System.Xml.Linq" /> |
|||
<Reference Include="System.Drawing" /> |
|||
<Reference Include="System.Web" /> |
|||
<Reference Include="System.Xml" /> |
|||
<Reference Include="System.Configuration" /> |
|||
<Reference Include="System.Web.Services" /> |
|||
<Reference Include="System.EnterpriseServices" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform"> |
|||
<HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath> |
|||
</Reference> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Content Include="Web.config" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Compile Include="appcode\PostParam.cs" /> |
|||
<Compile Include="appcode\ReportGenerator.cs" /> |
|||
<Compile Include="appcode\ServerUtility.cs" /> |
|||
<Compile Include="Common\ReportHelper.cs" /> |
|||
<Compile Include="common_code\DataTextProvider.cs" /> |
|||
<Compile Include="common_code\DbReportData.cs" /> |
|||
<Compile Include="common_code\ReportData.cs" /> |
|||
<Compile Include="Handlers\Handler1.ashx.cs"> |
|||
<DependentUpon>Handler1.ashx</DependentUpon> |
|||
</Compile> |
|||
<Compile Include="Properties\AssemblyInfo.cs" /> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Content Include="Handlers\Handler1.ashx" /> |
|||
<None Include="packages.config" /> |
|||
<None Include="Web.Debug.config"> |
|||
<DependentUpon>Web.config</DependentUpon> |
|||
</None> |
|||
<None Include="Web.Release.config"> |
|||
<DependentUpon>Web.config</DependentUpon> |
|||
</None> |
|||
</ItemGroup> |
|||
<ItemGroup> |
|||
<Folder Include="grf\" /> |
|||
</ItemGroup> |
|||
<PropertyGroup> |
|||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion> |
|||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> |
|||
</PropertyGroup> |
|||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> |
|||
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> |
|||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" /> |
|||
<ProjectExtensions> |
|||
<VisualStudio> |
|||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}"> |
|||
<WebProjectProperties> |
|||
<UseIIS>True</UseIIS> |
|||
<AutoAssignPort>True</AutoAssignPort> |
|||
<DevelopmentServerPort>56348</DevelopmentServerPort> |
|||
<DevelopmentServerVPath>/</DevelopmentServerVPath> |
|||
<IISUrl>https://localhost:44356/</IISUrl> |
|||
<NTLMAuthentication>False</NTLMAuthentication> |
|||
<UseCustomServer>False</UseCustomServer> |
|||
<CustomServerUrl>http://192.168.0.140/WebApplicationGridJJReport</CustomServerUrl> |
|||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile> |
|||
</WebProjectProperties> |
|||
</FlavorProperties> |
|||
</VisualStudio> |
|||
</ProjectExtensions> |
|||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> |
|||
<PropertyGroup> |
|||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText> |
|||
</PropertyGroup> |
|||
<Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" /> |
|||
</Target> |
|||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
|||
Other similar extension points exist, see Microsoft.Common.targets. |
|||
<Target Name="BeforeBuild"> |
|||
</Target> |
|||
<Target Name="AfterBuild"> |
|||
</Target> |
|||
--> |
|||
</Project> |
@ -0,0 +1,38 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<PropertyGroup> |
|||
<UseIISExpress>true</UseIISExpress> |
|||
<Use64BitIISExpress /> |
|||
<IISExpressSSLPort>44356</IISExpressSSLPort> |
|||
<IISExpressAnonymousAuthentication /> |
|||
<IISExpressWindowsAuthentication /> |
|||
<IISExpressUseClassicPipelineMode /> |
|||
<UseGlobalApplicationHostFile /> |
|||
<LastActiveSolutionConfig>Debug|Any CPU</LastActiveSolutionConfig> |
|||
<ProjectView>ProjectFiles</ProjectView> |
|||
</PropertyGroup> |
|||
<ProjectExtensions> |
|||
<VisualStudio> |
|||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}"> |
|||
<WebProjectProperties> |
|||
<StartPageUrl>/Handlers/Handler1.ashx?report=zhuhuban&returnfile=1</StartPageUrl> |
|||
<StartAction>SpecificPage</StartAction> |
|||
<AspNetDebugging>True</AspNetDebugging> |
|||
<SilverlightDebugging>False</SilverlightDebugging> |
|||
<NativeDebugging>False</NativeDebugging> |
|||
<SQLDebugging>False</SQLDebugging> |
|||
<ExternalProgram> |
|||
</ExternalProgram> |
|||
<StartExternalURL> |
|||
</StartExternalURL> |
|||
<StartCmdLineArguments> |
|||
</StartCmdLineArguments> |
|||
<StartWorkingDirectory> |
|||
</StartWorkingDirectory> |
|||
<EnableENC>True</EnableENC> |
|||
<AlwaysStartWebServerOnDebug>False</AlwaysStartWebServerOnDebug> |
|||
</WebProjectProperties> |
|||
</FlavorProperties> |
|||
</VisualStudio> |
|||
</ProjectExtensions> |
|||
</Project> |
File diff suppressed because one or more lines are too long
@ -0,0 +1,202 @@ |
|||
using System; |
|||
using System.Web; |
|||
using grsvr6Lib; |
|||
|
|||
namespace GridReport |
|||
{ |
|||
public class ReportGenerator |
|||
{ |
|||
protected HttpContext context = null; |
|||
|
|||
public GridppReportServer report = new GridppReportServer(); |
|||
|
|||
|
|||
|
|||
public ReportGenerator(HttpContext context) |
|||
{ |
|||
this.context = context; |
|||
} |
|||
|
|||
//根据HTTP请求中的 report 参数加载报表模板
|
|||
public void LoadReport() |
|||
{ |
|||
string reportID = context.Request.QueryString["report"]; |
|||
|
|||
if (reportID == null || reportID.Length == 0) |
|||
throw new Exception("没有在URL参数中指定\"report\"参数!"); |
|||
|
|||
//载入报表模板。模板路径获取应该按实际情况进行调整
|
|||
string reportPathFile = context.Server.MapPath("../grf/") + reportID + ".grf"; //根据当前页进行相对寻址
|
|||
//string reportPathFile = context.Server.MapPath("/grf/") + reportID + ".grf"; //根据WEB服务器根目录寻址
|
|||
LoadReportEx(reportPathFile); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 导入子报表【适用于柱护板报表】
|
|||
/// </summary>
|
|||
/// <param name="fileShortName">不含文件扩展名的文件名称</param>
|
|||
/// <returns></returns>
|
|||
public GridppReportServer LoadChildReport(string fileShortName) |
|||
{ |
|||
string reportPathFile = context.Server.MapPath("../grf/") + fileShortName + ".grf"; //根据当前页进行相对寻址
|
|||
bool success = report.LoadFromFile(reportPathFile); |
|||
if (!success) |
|||
throw new Exception(string.Format("载入 子 报表模板 '{0}' 失败!", reportPathFile)); |
|||
return report; |
|||
} |
|||
|
|||
//根据路径文件名加载报表模板,参数为当前网页的相对文件路径名
|
|||
public void LoadReport(string relativePathFile) |
|||
{ |
|||
string reportPathFile = context.Server.MapPath(relativePathFile); |
|||
LoadReportEx(reportPathFile); |
|||
} |
|||
|
|||
//根据完整的路径文件名加载报表模板
|
|||
public void LoadReportEx(string fullPathFile) |
|||
{ |
|||
bool success = report.LoadFromFile(fullPathFile); |
|||
if (!success) |
|||
throw new Exception(string.Format("载入报表模板 '{0}' 失败!", fullPathFile)); |
|||
|
|||
//如果要禁止用拉模式获取报表数据,需要将报表模板中的数据连接串置空
|
|||
//如果确实要用拉模式获取报表数据,请将以下代码注释掉
|
|||
//report.ConnectionString = "";
|
|||
//if (report.DetailGrid != null)
|
|||
// report.DetailGrid.Recordset.ConnectionString = "";
|
|||
} |
|||
|
|||
//从 XML 或 JSON 文本数据包加载报表数据。数据形式必须满足Grid++report的约定要求。
|
|||
public void LoadReportData(string DataText) |
|||
{ |
|||
bool success = report.LoadDataFromXML(DataText); |
|||
if (!success) |
|||
throw new Exception(string.Format("载入报表数据:\r\n '{0}' \r\n失败!", DataText)); |
|||
} |
|||
|
|||
//生成报表结果到二进制数据包对象中,并将数据响应给请求的客户端
|
|||
//HTTP请求中包含的参数:
|
|||
//report: 指定哪个报表
|
|||
//type: 指定生成的数据类型,可选[pdf|xls|csv|txt|rtf|img|grd|grp]。如果不指定,默认为pdf
|
|||
//img: 指定生成的图像数据格式,仅当生成图像数据时需要,可选[png|bmp|jpg|tif]。如果不指定,默认为png
|
|||
//open: 指定生成的数据打开模式,可选[inline|attachment],"inline"表示在网页中内联显示,"attachment"表示以附件文件形式下载。如果不指定,由浏览器自动确定打开方式
|
|||
//filename: 指定下载(或保存)文件时的默认文件名称
|
|||
public void Generate() |
|||
{ |
|||
string TypeText = context.Request.QueryString["type"]; |
|||
string ImageTypeText = context.Request.QueryString["img"]; |
|||
string FileName = context.Request.QueryString["filename"]; |
|||
string OpenMode = context.Request.QueryString["open"]; |
|||
|
|||
Generate(TypeText, FileName, OpenMode, ImageTypeText); |
|||
} |
|||
|
|||
public void Generate(string TypeText, string FileName) |
|||
{ |
|||
Generate(TypeText, FileName, "", ""); |
|||
} |
|||
|
|||
public void Generate(string TypeText, string FileName, string OpenMode, string ImageTypeText) |
|||
{ |
|||
//确定导出数据类型及数据的ContentType
|
|||
ReportGenerateInfo GenerateInfo = new ReportGenerateInfo(); |
|||
GenerateInfo.Build(TypeText, ImageTypeText); |
|||
|
|||
IGRBinaryObject ResultDataObject; |
|||
if (GenerateInfo.IsGRD) |
|||
{ |
|||
ResultDataObject = report.GenerateDocumentData(); |
|||
} |
|||
else |
|||
{ |
|||
IGRExportOption ExportOption = report.PrepareExport(GenerateInfo.ExportType); |
|||
|
|||
if (GenerateInfo.ExportType == GRExportType.gretIMG) |
|||
{ |
|||
IGRE2IMGOption E2IMGOption = ExportOption.AsE2IMGOption; |
|||
E2IMGOption.ImageType = GenerateInfo.ImageType; |
|||
E2IMGOption.AllInOne = true; //所有页产生在一个图像文件中
|
|||
//E2IMGOption.VertGap = 20; //页之间设置20个像素的间距
|
|||
} |
|||
|
|||
ResultDataObject = report.ExportToBinaryObject(); |
|||
report.UnprepareExport(); |
|||
} |
|||
|
|||
#region 响应生成的报表结果数据
|
|||
//如果参数中没指定文件名,则更报表模板中的“标题”属性设置一个默认文件名
|
|||
if (FileName == null || FileName.Length == 0) |
|||
{ |
|||
if (report.Title == null || report.Title.Length == 0) |
|||
FileName = "gridreport"; |
|||
else |
|||
FileName = report.Title; |
|||
FileName += "." + GenerateInfo.ExtFileBame; |
|||
} |
|||
|
|||
ServerUtility.ResponseBinary(context, ResultDataObject, FileName, GenerateInfo.ContentType, OpenMode); |
|||
#endregion
|
|||
} |
|||
|
|||
#region 导出Base64
|
|||
public string Generate2() |
|||
{ |
|||
string TypeText = context.Request.QueryString["type"]; |
|||
string ImageTypeText = context.Request.QueryString["img"]; |
|||
string FileName = context.Request.QueryString["filename"]; |
|||
string OpenMode = context.Request.QueryString["open"]; |
|||
|
|||
return Generate2(TypeText, FileName, OpenMode, ImageTypeText); |
|||
} |
|||
|
|||
|
|||
public string Generate2(string TypeText, string FileName, string OpenMode, string ImageTypeText) |
|||
{ |
|||
//确定导出数据类型及数据的ContentType
|
|||
ReportGenerateInfo GenerateInfo = new ReportGenerateInfo(); |
|||
GenerateInfo.Build(TypeText, ImageTypeText); |
|||
|
|||
IGRBinaryObject ResultDataObject; |
|||
if (GenerateInfo.IsGRD) |
|||
{ |
|||
ResultDataObject = report.GenerateDocumentData(); |
|||
} |
|||
else |
|||
{ |
|||
IGRExportOption ExportOption = report.PrepareExport(GenerateInfo.ExportType); |
|||
|
|||
if (GenerateInfo.ExportType == GRExportType.gretIMG) |
|||
{ |
|||
IGRE2IMGOption E2IMGOption = ExportOption.AsE2IMGOption; |
|||
E2IMGOption.ImageType = GenerateInfo.ImageType; |
|||
E2IMGOption.AllInOne = true; //所有页产生在一个图像文件中
|
|||
//E2IMGOption.VertGap = 20; //页之间设置20个像素的间距
|
|||
} |
|||
|
|||
ResultDataObject = report.ExportToBinaryObject(); |
|||
report.UnprepareExport(); |
|||
} |
|||
|
|||
#region 响应生成的报表结果数据
|
|||
//如果参数中没指定文件名,则更报表模板中的“标题”属性设置一个默认文件名
|
|||
if (FileName == null || FileName.Length == 0) |
|||
{ |
|||
if (report.Title == null || report.Title.Length == 0) |
|||
FileName = "gridreport"; |
|||
else |
|||
FileName = report.Title; |
|||
FileName += "." + GenerateInfo.ExtFileBame; |
|||
} |
|||
|
|||
#endregion
|
|||
object Data = ResultDataObject.SaveToVariant(); |
|||
byte[] byArr = (byte[])Data; |
|||
string base64Str = Convert.ToBase64String(byArr); |
|||
return base64Str; |
|||
|
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
} |
|||
} |
@ -0,0 +1,336 @@ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Web; |
|||
using System.Data; |
|||
using grsvr6Lib; |
|||
//using OfficeOpenXml;
|
|||
|
|||
namespace GridReport |
|||
{ |
|||
public class ReportGenerateInfo |
|||
{ |
|||
public string ContentType; //HTTP响应ContentType
|
|||
public string ExtFileBame; //默认扩展文件名
|
|||
public bool IsGRD; //是否生成为 Grid++Report 报表文档格式
|
|||
public GRExportType ExportType; //导出的数据格式类型
|
|||
public GRExportImageType ImageType; //导出的图像格式类型
|
|||
|
|||
///根据报表导出格式类型,生成对应的响应信息,将结果信息保存本类的成员变量中
|
|||
///参数 ExportTypeText: 指定报表导出的导出格式类型
|
|||
///参数 ImageTypeText: 指定生成的图像格式,仅当为导出图像时有效
|
|||
public void Build(string ExportTypeText, string ImageTypeText) |
|||
{ |
|||
ExtFileBame = ExportTypeText; |
|||
ContentType = "application/"; |
|||
IsGRD = (ExportTypeText == "grd" || ExportTypeText == "grp"); |
|||
|
|||
if (IsGRD) |
|||
{ |
|||
//ContentType += ExportTypeText; //application/grd
|
|||
ContentType += "octet-stream"; //application/octet-stream
|
|||
} |
|||
else |
|||
{ |
|||
switch (ExportTypeText) |
|||
{ |
|||
case "xls": |
|||
ExportType = GRExportType.gretXLS; |
|||
ContentType += "x-xls"; //application/vnd.ms-excel application/x-xls
|
|||
break; |
|||
case "csv": |
|||
ExportType = GRExportType.gretCSV; |
|||
ContentType += "vnd.ms-excel"; //application/vnd.ms-excel application/x-xls
|
|||
break; |
|||
case "txt": |
|||
ExportType = GRExportType.gretTXT; |
|||
ContentType = "text/plain"; //text/plain
|
|||
break; |
|||
case "rtf": |
|||
ExportType = GRExportType.gretRTF; |
|||
ContentType += "rtf"; //application/rtf
|
|||
break; |
|||
case "img": |
|||
ExportType = GRExportType.gretIMG; |
|||
//ContentType 要在后面根据图像格式来确定
|
|||
break; |
|||
default: |
|||
ExtFileBame = "pdf"; //"type"参数如没有设置,保证 ExtFileBame 被设置为"pdf"
|
|||
ExportType = GRExportType.gretPDF; |
|||
ContentType += "pdf"; |
|||
break; |
|||
} |
|||
|
|||
//导出图像处理
|
|||
if (ExportType == GRExportType.gretIMG) |
|||
{ |
|||
ExtFileBame = ImageTypeText; |
|||
switch (ImageTypeText) |
|||
{ |
|||
case "bmp": |
|||
ImageType = GRExportImageType.greitBMP; |
|||
ContentType += "x-bmp"; |
|||
break; |
|||
case "jpg": |
|||
ImageType = GRExportImageType.greitJPEG; |
|||
ContentType += "x-jpg"; |
|||
break; |
|||
case "tif": |
|||
ImageType = GRExportImageType.greitTIFF; |
|||
ContentType = "image/tiff"; |
|||
break; |
|||
default: |
|||
ExtFileBame = "png"; |
|||
ImageType = GRExportImageType.greitPNG; |
|||
ContentType += "x-png"; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
public class ServerUtility |
|||
{ |
|||
/// <summary>
|
|||
/// 将报表生成的二进制数据响应给 HTPP 请求客户端
|
|||
/// </summary>
|
|||
/// <param name="context"> HTPP 请求对象</param>
|
|||
/// <param name="ExportResult">报表生成的二进制数据</param>
|
|||
/// <param name="FileName">指定下载(或保存)文件时的默认文件名称</param>
|
|||
/// <param name="ContentType">响应的ContentType</param>
|
|||
/// <param name="OpenMode">指定生成的数据打开模式,可选[inline|attachment],"inline"表示在网页中内联显示,"attachment"表示以附件文件形式下载。如果不指定,由浏览器自动确定打开方式。</param>
|
|||
public static void ResponseBinary(HttpContext context, IGRBinaryObject ExportResult, string FileName, string ContentType, string OpenMode) |
|||
{ |
|||
if (ExportResult.DataSize > 0) |
|||
{ |
|||
string Disposition = ""; |
|||
|
|||
if (OpenMode != null && OpenMode.Length > 0) |
|||
Disposition = OpenMode + "; "; |
|||
|
|||
Disposition += ServerUtility.EncodeAttachmentFileName(context.Request.UserAgent, FileName); |
|||
|
|||
context.Response.ContentType = ContentType; |
|||
context.Response.AppendHeader("Content-Length", ExportResult.DataSize.ToString()); |
|||
context.Response.AppendHeader("Content-Disposition", Disposition); |
|||
|
|||
context.Response.ClearContent(); |
|||
|
|||
//当发布到IIS,用InteropServices.Marshal.Copy方式复制导出的数据出现了异常,而在VS的IDE里是正常的,所以改用SaveToVariant
|
|||
//byte[] buffer = new byte[ExportResult.DataSize];
|
|||
//System.Runtime.InteropServices.Marshal.Copy((IntPtr)ExportResult.DataBuf, buffer, 0, ExportResult.DataSize);
|
|||
//context.Response.BinaryWrite(buffer);
|
|||
object Data = ExportResult.SaveToVariant(); |
|||
context.Response.BinaryWrite((byte[])Data); |
|||
|
|||
context.Response.Flush(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 将异常信息文字响应给请求的客户端
|
|||
/// </summary>
|
|||
/// <param name="context"></param>
|
|||
/// <param name="MessageText"></param>
|
|||
public static void ResponseException(HttpContext context, string MessageText) |
|||
{ |
|||
context.Response.ContentType = "text/plain"; |
|||
context.Response.Write(MessageText); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 为了文件名中的汉字与特殊字符能正确,必须进行分浏览器处理
|
|||
/// </summary>
|
|||
/// <param name="BrowserAgent"></param>
|
|||
/// <param name="RawFileName"></param>
|
|||
/// <returns></returns>
|
|||
public static string EncodeAttachmentFileName(string BrowserAgent, string RawFileName) |
|||
{ |
|||
System.Text.UTF8Encoding UTF8Encoding = new System.Text.UTF8Encoding(); |
|||
string EncodedFileName = HttpUtility.UrlEncode(RawFileName, UTF8Encoding); |
|||
|
|||
// 如果没有BrowserAgent,则默认使用IE的方式进行编码,因为毕竟IE还是占多数的
|
|||
string ret = "filename=\"" + EncodedFileName + "\""; |
|||
if (BrowserAgent != null && BrowserAgent.Length != 0) |
|||
{ |
|||
BrowserAgent = BrowserAgent.ToLower(); |
|||
// msie 与 edge 采用默认的方式
|
|||
if ((BrowserAgent.IndexOf("msie") == -1) && (BrowserAgent.IndexOf("edge") == -1)) |
|||
{ |
|||
// Chrome浏览器,只能采用MimeUtility编码或ISO编码的中文输出
|
|||
if (BrowserAgent.IndexOf("applewebkit") != -1) |
|||
{ |
|||
//EncodedFileName = MimeUtility.encodeText(RawFileName, "UTF8", "B");
|
|||
System.Text.UTF8Encoding UTF8EncodingBOM = new System.Text.UTF8Encoding(true); |
|||
EncodedFileName = UTF8EncodingBOM.GetString(UTF8EncodingBOM.GetBytes(RawFileName)); |
|||
ret = "filename=\"" + EncodedFileName + "\""; |
|||
} |
|||
// Safari浏览器,只能采用ISO编码的中文输出
|
|||
else if (BrowserAgent.IndexOf("safari") != -1) |
|||
{ |
|||
//28591 iso-8859-1 1252 *
|
|||
//ret = "filename=\"" + new String(filename.getBytes("UTF-8"), "ISO8859-1") + "\"";
|
|||
byte[] UTF8Bytes = UTF8Encoding.GetBytes(RawFileName); |
|||
string ISO8859Text = System.Text.Encoding.GetEncoding(28591).GetString(UTF8Bytes); |
|||
ret = "filename=\"" + ISO8859Text + "\""; |
|||
} |
|||
// Opera浏览器只能采用filename*
|
|||
// FireFox浏览器,可以使用MimeUtility或filename*或ISO编码的中文输出
|
|||
else if ((BrowserAgent.IndexOf("opera") != -1) || (BrowserAgent.IndexOf("mozilla") != -1)) |
|||
{ |
|||
ret = "filename*=UTF-8''" + EncodedFileName; |
|||
} |
|||
} |
|||
} |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 根据报表模板中的查询SQL获取报表数据
|
|||
/// </summary>
|
|||
public static string BuildFromSelfSQL(GridppReportServer Report) |
|||
{ |
|||
string DataText = ""; |
|||
|
|||
//从 XML 或 JSON 数据包中载入报表数据
|
|||
string MasterQuerySQL = Report.QuerySQL; |
|||
string DetailQuerySQL = Report.DetailGrid != null ? Report.DetailGrid.Recordset.QuerySQL : null; |
|||
bool MasterAssigned = (MasterQuerySQL != null && MasterQuerySQL.Length > 0); |
|||
bool DetailAssigned = (DetailQuerySQL != null && DetailQuerySQL.Length > 0); |
|||
if (MasterAssigned || DetailAssigned) |
|||
{ |
|||
if (MasterAssigned && DetailAssigned) |
|||
{ |
|||
string MasterTableName = Report.XmlTableName; |
|||
if (MasterTableName == null || MasterTableName.Length == 0) |
|||
MasterTableName = "Master"; |
|||
|
|||
string DetailTableName = Report.DetailGrid.Recordset.XmlTableName; |
|||
if (DetailTableName == null || DetailTableName.Length == 0) |
|||
{ |
|||
DetailTableName = "Detail"; |
|||
} |
|||
ArrayList QueryList = new ArrayList(); |
|||
QueryList.Add(new ReportQueryItem(DetailQuerySQL, DetailTableName)); |
|||
QueryList.Add(new ReportQueryItem(MasterQuerySQL, MasterTableName)); |
|||
DataText = DataTextProvider.Build(QueryList); |
|||
} |
|||
else |
|||
{ |
|||
DataText = DataTextProvider.Build(MasterAssigned ? MasterQuerySQL : DetailQuerySQL); |
|||
} |
|||
} |
|||
|
|||
return DataText; |
|||
} |
|||
|
|||
private struct MatchFieldPairType |
|||
{ |
|||
public IGRField grField; |
|||
public int MatchColumnIndex; |
|||
} |
|||
|
|||
// 将 DataReader 的数据转储到 Grid++Report 的记录集中
|
|||
public static void FillRecordToReport(IGridppReport Report, IDataReader dr) |
|||
{ |
|||
MatchFieldPairType[] MatchFieldPairs = new MatchFieldPairType[Math.Min(Report.DetailGrid.Recordset.Fields.Count, dr.FieldCount)]; |
|||
|
|||
//根据字段名称与列名称进行匹配,建立DataReader字段与Grid++Report记录集的字段之间的对应关系
|
|||
int MatchFieldCount = 0; |
|||
for (int i = 0; i < dr.FieldCount; ++i) |
|||
{ |
|||
foreach (IGRField fld in Report.DetailGrid.Recordset.Fields) |
|||
{ |
|||
if (String.Compare(fld.RunningDBField, dr.GetName(i), true) == 0) |
|||
{ |
|||
MatchFieldPairs[MatchFieldCount].grField = fld; |
|||
MatchFieldPairs[MatchFieldCount].MatchColumnIndex = i; |
|||
++MatchFieldCount; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
// 将 DataReader 中的每一条记录转储到 Grid++Report 的记录集中去
|
|||
while (dr.Read()) |
|||
{ |
|||
Report.DetailGrid.Recordset.Append(); |
|||
|
|||
for (int i = 0; i < MatchFieldCount; ++i) |
|||
{ |
|||
if (!dr.IsDBNull(MatchFieldPairs[i].MatchColumnIndex)) |
|||
MatchFieldPairs[i].grField.Value = dr.GetValue(MatchFieldPairs[i].MatchColumnIndex); |
|||
} |
|||
Report.DetailGrid.Recordset.Post(); |
|||
} |
|||
} |
|||
|
|||
// 将 DataTable 的数据转储到 Grid++Report 的记录集中
|
|||
public static void FillRecordToReport(IGridppReport Report, DataTable dt) |
|||
{ |
|||
MatchFieldPairType[] MatchFieldPairs = new MatchFieldPairType[Math.Min(Report.DetailGrid.Recordset.Fields.Count, dt.Columns.Count)]; |
|||
|
|||
//根据字段名称与列名称进行匹配,建立DataReader字段与Grid++Report记录集的字段之间的对应关系
|
|||
int MatchFieldCount = 0; |
|||
for (int i = 0; i < dt.Columns.Count; ++i) |
|||
{ |
|||
foreach (IGRField fld in Report.DetailGrid.Recordset.Fields) |
|||
{ |
|||
if (String.Compare(fld.Name, dt.Columns[i].ColumnName, true) == 0) |
|||
{ |
|||
MatchFieldPairs[MatchFieldCount].grField = fld; |
|||
MatchFieldPairs[MatchFieldCount].MatchColumnIndex = i; |
|||
++MatchFieldCount; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
// 将 DataTable 中的每一条记录转储到 Grid++Report 的记录集中去
|
|||
foreach (DataRow dr in dt.Rows) |
|||
{ |
|||
Report.DetailGrid.Recordset.Append(); |
|||
|
|||
for (int i = 0; i < MatchFieldCount; ++i) |
|||
{ |
|||
if (!dr.IsNull(MatchFieldPairs[i].MatchColumnIndex)) |
|||
MatchFieldPairs[i].grField.Value = dr[MatchFieldPairs[i].MatchColumnIndex]; |
|||
} |
|||
|
|||
Report.DetailGrid.Recordset.Post(); |
|||
} |
|||
} |
|||
|
|||
public static uint RGBToOleColor(byte r, byte g, byte b) |
|||
{ |
|||
return ((uint)b) * 256 * 256 + ((uint)g) * 256 + r; |
|||
} |
|||
|
|||
public static uint ColorToOleColor(System.Drawing.Color val) |
|||
{ |
|||
return RGBToOleColor(val.R, val.G, val.B); |
|||
} |
|||
|
|||
//判断当前运行进程是不是64位程序
|
|||
public static bool Is64bitProcess() |
|||
{ |
|||
//IsWow64Process
|
|||
//也可以直接用Environment.Is64BitProcess,不过需要DotNet4.0或以上版本。
|
|||
return (IntPtr.Size == 8); |
|||
} |
|||
|
|||
//生成数据源连接串,根据当前运行环境与配置参数进行实际调整
|
|||
public static string BuildOLEDBConnectionString() |
|||
{ |
|||
//Grid++Report的64位程序通过OLE DB连接Access与32位程序使用完全不同的数据驱动程序,
|
|||
//此数据驱动程序(AccessDatabaseEngine_X64.exe)没有跟随Windows系统自动安装,需要从
|
|||
//微软网站下载并安装, 下载地址:https://www.microsoft.com/zh-CN/download/details.aspx?id=13255
|
|||
//如果直接不能安装,要先将Ofiice卸载后再进行安装,驱动程序安装后,在重新安装Office。
|
|||
return (Is64bitProcess() ? "Provider = Microsoft.ACE.OLEDB.12.0;" : "Provider=Microsoft.Jet.OLEDB.4.0;") + |
|||
"User ID=Admin;Data Source=" + @"C:\Grid++Report 6\Samples\Data\NorthWind.mdb"; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,517 @@ |
|||
///下面两个编译条件参数指定产生报表数据的格式。如果都不定义,则产生 XML 形式的报表数据
|
|||
///编译条件参数定义在项目属性的“生成->条件编译符号”里更合适,这样可以为整个项目使用
|
|||
///_XML_REPORT_DATA:指定产生 XML 形式的报表数据
|
|||
///_JSON_REPORT_DATA:指定产生 JSON 形式的报表数据。
|
|||
//#define _XML_REPORT_DATA
|
|||
#define _JSON_REPORT_DATA
|
|||
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Web; |
|||
using System.Text; |
|||
using System.Diagnostics; |
|||
|
|||
namespace GridReport |
|||
{ |
|||
|
|||
#if _JSON_REPORT_DATA
|
|||
using MyDbReportData = DatabaseJsonReportData; |
|||
#else
|
|||
using MyDbReportData = DatabaseXmlReportData; |
|||
#endif
|
|||
|
|||
/// <summary>
|
|||
/// 在这里集中产生整个项目的所有报表需要的 XML 或 JSON 文本数据
|
|||
/// </summary>
|
|||
public class DataTextProvider |
|||
{ |
|||
/// <summary>
|
|||
/// 根据查询SQL语句产生报表数据
|
|||
/// </summary>
|
|||
public static string Build(string QuerySQL) |
|||
{ |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 根据多条查询SQL语句产生报表数据,数据对应多记录集
|
|||
/// </summary>
|
|||
public static string Build(ArrayList QueryList) |
|||
{ |
|||
return MyDbReportData.TextFromMultiSQL(QueryList); |
|||
} |
|||
|
|||
#region 产生特定的报表数据文本
|
|||
public static string Customer() |
|||
{ |
|||
return MyDbReportData.TextFromOneSQL("select * from Customers order by Region,City"); |
|||
} |
|||
|
|||
public static string AppendBlankRow() |
|||
{ |
|||
string QuerySQL = string.Format( |
|||
"select m.OrderId, m.OrderDate, d.Productid,p.ProductName,d.Quantity," + |
|||
"d.UnitPrice*d.Quantity as Amount " + |
|||
"from orders m inner join (OrderDetails d inner join Products p on d.ProductID=p.ProductID) " + |
|||
"on m.orderid=d.orderid " + |
|||
"where (m.OrderDate between {0}1996-1-1{0} And {0}1997-9-30{0}) and d.Productid<10 " + |
|||
"order by d.ProductID", DatabaseReportData.DateSqlBracketChar); |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string Categories() |
|||
{ |
|||
return MyDbReportData.TextFromOneSQL("select * from categories"); |
|||
} |
|||
|
|||
public static string ContractOne() |
|||
{ |
|||
const string QuerySQL = |
|||
"select m.OrderID,m.CustomerId,c.CompanyName,m.OrderDate, " |
|||
+ "p.ProductName,d.UnitPrice,d.Quantity,d.UnitPrice*d.Quantity as Amount " |
|||
+ "from (Orders m inner join " |
|||
+ "(OrderDetails as d inner join Products p on P.ProductID=D.ProductID) on m.OrderId=d.OrderId) " |
|||
+ "left join Customers c on c.CustomerID=m.CustomerID " |
|||
+ "where m.OrderID=10252 and d.ProductID=20 " |
|||
+ "order by m.OrderDate, m.OrderID"; |
|||
|
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string CrossTab() |
|||
{ |
|||
const string QuerySQL = "select c.City,m.CustomerId,c.CompanyName,d.ProductID,p.ProductName," + |
|||
"d.Quantity, d.UnitPrice*d.Quantity as Amount " + |
|||
"from (Orders m inner join " + |
|||
"(OrderDetails as d inner join Products p " + |
|||
"on P.ProductID=D.ProductID) on m.OrderId=d.OrderId) " + |
|||
"left join Customers c on c.CustomerID=m.CustomerID " + |
|||
"where d.ProductID<8 " + |
|||
"order by c.City,m.CustomerId, d.ProductID"; |
|||
|
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string CrossTabByDay() |
|||
{ |
|||
string QuerySQL = string.Format("select c.CompanyName,m.OrderDate,d.UnitPrice*d.Quantity as Amount " + |
|||
"from (Orders m inner join OrderDetails as d on m.OrderId=d.OrderId) " + |
|||
"left join Customers c on c.CustomerID=m.CustomerID " + |
|||
"where m.OrderDate between {0}1997-6-1{0} and {0}1997-7-15{0} " + |
|||
"order by c.CompanyName, m.OrderDate", DatabaseReportData.DateSqlBracketChar); |
|||
|
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string CrossTabByMonth() |
|||
{ |
|||
string QuerySQL = string.Format("select c.CompanyName,m.OrderDate,d.UnitPrice*d.Quantity as Amount " + |
|||
"from (Orders m inner join OrderDetails as d on m.OrderId=d.OrderId) " + |
|||
"left join Customers c on c.CustomerID=m.CustomerID " + |
|||
"where m.OrderDate between {0}1997-1-1{0} and {0}1997-12-31{0} " + |
|||
"order by c.CompanyName, m.OrderDate", DatabaseReportData.DateSqlBracketChar); |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string CrossTabCalendar() |
|||
{ |
|||
string QuerySQL = string.Format( |
|||
"select m.OrderDate,sum(d.Quantity) as Qty,sum(d.UnitPrice*d.Quantity) as Amount " + |
|||
"from (Orders m inner join OrderDetails as d on m.OrderId=d.OrderId) " + |
|||
"where m.OrderDate between {0}1997-1-1{0} and {0}1997-12-31{0} " + |
|||
"group by m.OrderDate " + |
|||
"order by m.OrderDate", DatabaseReportData.DateSqlBracketChar); |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string CrossTabSubtotal() |
|||
{ |
|||
string QuerySQL = string.Format( |
|||
"select t.CategoryName, p.ProductName,c.City,c.CompanyName,d.Quantity " + |
|||
"from (Orders m inner join " + |
|||
"(OrderDetails as d inner join (Products p inner join Categories t on p.CategoryID=t.CategoryID) " + |
|||
"on P.ProductID=D.ProductID) on m.OrderId=d.OrderId) " + |
|||
"left join Customers c on c.CustomerID=m.CustomerID " + |
|||
"where m.OrderDate between {0}1997-1-1{0} and {0}1997-3-31{0} " + |
|||
"order by t.CategoryName,p.ProductName,c.City,c.CompanyName ", DatabaseReportData.DateSqlBracketChar); |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string CrossTabYearMonth() |
|||
{ |
|||
string QuerySQL = "select Year(m.OrderDate) As TheYear,Month(m.OrderDate) As TheMonth, sum(d.UnitPrice*d.Quantity) as Amount " + |
|||
"from Orders m inner join OrderDetails as d on m.OrderId=d.OrderId " + |
|||
"group by Year(m.OrderDate),Month(m.OrderDate) " + |
|||
"order by Year(m.OrderDate),Month(m.OrderDate)"; |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string EmployeeOne() |
|||
{ |
|||
const string QuerySQL = "select * from Employees where EmployeeID=5"; |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string FreeGridwithDetailGrid() |
|||
{ |
|||
//第一个查询SQL串指定报表明细数据的查询SQL
|
|||
//第二个查询SQL串指定报表参数数据的查询SQL
|
|||
const string RecordsetQuerySQL = "select * from Employees where EmployeeID<8"; |
|||
const string ParameterQuerySQL = "select * from Employees where EmployeeID=8"; |
|||
|
|||
ArrayList QueryList = new ArrayList(); |
|||
QueryList.Add(new ReportQueryItem(RecordsetQuerySQL, "Detail")); |
|||
QueryList.Add(new ReportQueryItem(ParameterQuerySQL, "FreeGrid")); |
|||
|
|||
return MyDbReportData.TextFromMultiSQL(QueryList); |
|||
} |
|||
|
|||
public static string InvoiceMany() |
|||
{ |
|||
const string QuerySQL = |
|||
"select m.OrderID,m.CustomerId,c.CompanyName,C.Address,m.OrderDate,c.ContactName+c.Phone as Remark, " + |
|||
"d.ProductID,p.ProductName,d.UnitPrice,d.Quantity,d.UnitPrice*d.Quantity as Amount " + |
|||
"from (Orders m inner join (OrderDetails d inner join Products p on p.ProductID=d.ProductID) " + |
|||
"on d.OrderID=m.OrderID) left join Customers c on c.CustomerID=m.CustomerID " + |
|||
"where m.OrderID>=10255 and m.OrderID<10260 "; |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string InvoiceOne() |
|||
{ |
|||
//第一个查询SQL串指定报表明细数据的查询SQL
|
|||
//第二个查询SQL串指定报表参数数据的查询SQL
|
|||
const string RecordsetQuerySQL = "select d.ProductID,p.ProductName,d.UnitPrice,d.Quantity,d.UnitPrice*d.Quantity as Amount " |
|||
+ "from OrderDetails as d inner join Products p on P.ProductID=D.ProductID " |
|||
+ "where d.OrderID=10255"; |
|||
const string ParameterQuerySQL = "select m.OrderID,m.CustomerId,c.CompanyName,C.Address,m.OrderDate,c.ContactName+c.Phone as Remark " |
|||
+ "from Orders m left join Customers c on c.CustomerID=m.CustomerID " |
|||
+ "where m.OrderID=10255"; |
|||
|
|||
ArrayList QueryList = new ArrayList(); |
|||
QueryList.Add(new ReportQueryItem(RecordsetQuerySQL, "Detail")); |
|||
QueryList.Add(new ReportQueryItem(ParameterQuerySQL, "Master")); |
|||
|
|||
return MyDbReportData.TextFromMultiSQL(QueryList); |
|||
} |
|||
|
|||
public static string Picture() |
|||
{ |
|||
const string QuerySQL = "select EmployeeID,LastName,FirstName,Title,TitleOfCourtesy,BirthDate,HireDate," + |
|||
"Address,City,Region,PostalCode,Country,HomePhone,Extension,Photo,Notes from Employees"; |
|||
|
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string RTFSample() |
|||
{ |
|||
string QuerySQL = string.Format("select m.OrderID,m.CustomerId,c.CompanyName,c.ContactName,c.Address,c.city,c.Region,c.Country,c.Postalcode," + |
|||
"m.OrderDate,M.Freight,d.ProductID,p.ProductName," + |
|||
"d.UnitPrice,d.Quantity,d.Discount," + |
|||
"d.UnitPrice*d.Quantity as Amount," + |
|||
"d.UnitPrice*d.Quantity*d.Discount as DiscountAmt," + |
|||
"d.UnitPrice*d.Quantity-d.UnitPrice*d.Quantity*d.Discount as NetAmount " + |
|||
"from (Orders m inner join " + |
|||
"(OrderDetails as d inner join Products p on P.ProductID=D.ProductID) on m.OrderId=d.OrderId) " + |
|||
"left join Customers c on c.CustomerID=m.CustomerID " + |
|||
"where m.OrderDate between {0}1997-1-1{0} And {0}1997-1-15{0} " + |
|||
"order by m.CustomerID,m.OrderDate, m.OrderID", DatabaseReportData.DateSqlBracketChar); |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string SaleByProduct() |
|||
{ |
|||
string QuerySQL = string.Format( |
|||
"select m.OrderID,m.OrderDate, " + |
|||
"d.ProductID,p.ProductName,d.UnitPrice,d.Quantity,d.UnitPrice*d.Quantity as Amount " + |
|||
"from Orders m inner join " + |
|||
"(OrderDetails as d inner join Products p on P.ProductID=D.ProductID) on m.OrderId=d.OrderId " + |
|||
"where m.OrderDate between {0}1997-6-1{0} and {0}1997-12-31{0} " + |
|||
"order by d.ProductID, m.OrderDate", DatabaseReportData.DateSqlBracketChar); |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string SaleDetail() |
|||
{ |
|||
const string QuerySQL = "select m.OrderID,m.CustomerId,c.CompanyName,m.OrderDate,M.Freight," + |
|||
"d.ProductID,p.ProductName,d.UnitPrice,d.Quantity,d.Discount, " + |
|||
"d.UnitPrice*d.Quantity as Amount, d.UnitPrice*d.Quantity*d.Discount as DiscountAmt, " + |
|||
"d.UnitPrice*d.Quantity-d.UnitPrice*d.Quantity*d.Discount as NetAmount " + |
|||
"from (Orders m inner join " + |
|||
"(OrderDetails as d inner join Products p on P.ProductID=D.ProductID) on m.OrderId=d.OrderId) " + |
|||
"left join Customers c on c.CustomerID=m.CustomerID " + |
|||
"where m.OrderID<=10300 " + |
|||
"order by m.OrderDate, m.OrderID"; |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string SaleSumByProduct() |
|||
{ |
|||
string QuerySQL = string.Format( |
|||
"select d.Productid,p.ProductName,sum(d.Quantity) as Quantity, " + |
|||
"sum(d.UnitPrice*d.Quantity*(1-d.Discount)) as Amount " + |
|||
"from orders m inner join (OrderDetails d inner join Products p " + |
|||
"on d.ProductID=p.ProductID) " + |
|||
"on m.orderid=d.orderid " + |
|||
"where m.OrderDate between {0}1997-1-1{0} and {0}1997-12-31{0} " + |
|||
"group by d.Productid,p.ProductName " + |
|||
"order by d.Productid", DatabaseReportData.DateSqlBracketChar); |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string SubReport_4a() |
|||
{ |
|||
const string Top10CustomerQuerySQL = |
|||
"select top 10 c.CustomerID, c.CompanyName, sum(o.Quantity*o.UnitPrice) As SumAmt " + |
|||
"from OrderDetails o, Orders m, customers c " + |
|||
"where o.OrderID=m.OrderID and m.CustomerID=c.CustomerID " + |
|||
"group by c.CustomerID, c.CompanyName " + |
|||
"order by sum(o.Quantity*o.UnitPrice) desc"; |
|||
const string Top10ProductQuerySQL = |
|||
"select top 10 p.ProductID, p.ProductName, sum(o.Quantity*o.UnitPrice) As SumQty " + |
|||
"from OrderDetails o, Products p " + |
|||
"where o.ProductID=p.ProductID " + |
|||
"group by p.ProductID, p.ProductName " + |
|||
"order by sum(Quantity*o.UnitPrice) desc"; |
|||
|
|||
ArrayList QueryList = new ArrayList(); |
|||
QueryList.Add(new ReportQueryItem("select * from Customers order by CustomerID", "Customer")); |
|||
QueryList.Add(new ReportQueryItem("select * from Products order by ProductName", "Product")); |
|||
QueryList.Add(new ReportQueryItem(Top10CustomerQuerySQL, "Top10Customer")); |
|||
QueryList.Add(new ReportQueryItem(Top10ProductQuerySQL, "Top10Product")); |
|||
return MyDbReportData.TextFromMultiSQL(QueryList); |
|||
} |
|||
|
|||
public static string SubReport_4b() |
|||
{ |
|||
ArrayList QueryList = new ArrayList(); |
|||
QueryList.Add(new ReportQueryItem("select * from Customers order by CustomerID", "Customer")); |
|||
QueryList.Add(new ReportQueryItem("select * from Products order by ProductName", "Product")); |
|||
QueryList.Add(new ReportQueryItem("select * from Customers order by CustomerID", "Customer2")); |
|||
return MyDbReportData.TextFromMultiSQL(QueryList); |
|||
} |
|||
|
|||
public static string SubReport_4c() |
|||
{ |
|||
const string RelateCustomerQuerySQL = |
|||
"select o.OrderID, o.ShipCity, c.* from Customers c, Orders o " + |
|||
"where OrderID<=10260 and c.City=o.ShipCity " + |
|||
"order by o.OrderID"; |
|||
|
|||
ArrayList QueryList = new ArrayList(); |
|||
QueryList.Add(new ReportQueryItem("select * from Orders where OrderID<=10260 order by OrderID", "Master")); |
|||
QueryList.Add(new ReportQueryItem("select * from OrderDetails where OrderID<=10260", "Detail1")); |
|||
QueryList.Add(new ReportQueryItem(RelateCustomerQuerySQL, "Detail2")); |
|||
|
|||
return MyDbReportData.TextFromMultiSQL(QueryList); |
|||
} |
|||
|
|||
public static string SubReport_4d(string city) |
|||
{ |
|||
string CustomerQuerySQL = "select * from Customers where City='" + city + "'"; |
|||
string SupplierQuerySQL = "select * from Suppliers where City='" + city + "'"; |
|||
|
|||
ArrayList QueryList = new ArrayList(); |
|||
QueryList.Add(new ReportQueryItem(CustomerQuerySQL, "Customer")); |
|||
QueryList.Add(new ReportQueryItem(SupplierQuerySQL, "Supplier")); |
|||
|
|||
return MyDbReportData.TextFromMultiSQL(QueryList); |
|||
} |
|||
|
|||
public static string Report_7_3g(int BeginNo, int EndNo) |
|||
{ |
|||
string QuerySQL = string.Format("select * from Products " + |
|||
"where ProductID>={0} and ProductID<={1} " + |
|||
"order by ProductID", BeginNo, EndNo); |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string Chart_8b() |
|||
{ |
|||
ArrayList QueryList = new ArrayList(); |
|||
QueryList.Add(new ReportQueryItem("select * from scatter order by Name, X", "Table1")); |
|||
QueryList.Add(new ReportQueryItem("select * from scatter order by Name, X", "Table2")); |
|||
QueryList.Add(new ReportQueryItem("select * from scatter order by Name, X", "Table3")); |
|||
QueryList.Add(new ReportQueryItem("select * from scatter order by Name, X", "Table4")); |
|||
return MyDbReportData.TextFromMultiSQL(QueryList); |
|||
} |
|||
|
|||
public static string Chart_8d() |
|||
{ |
|||
string SQL = "select c.Region, d.ProductID,p.ProductName, " + |
|||
"sum(d.UnitPrice * d.Quantity) as Amount " + |
|||
"from(Orders m inner join (OrderDetails as d inner join Products p on P.ProductID = D.ProductID) on m.OrderId = d.OrderId) " + |
|||
"left join Customers c on c.CustomerID = m.CustomerID " + |
|||
"where d.ProductID in (1, 10, 11, 21) and m.OrderDate between #1997/1/1# and #1997/12/31# " + |
|||
"group by c.Region, d.ProductID, p.ProductName " + |
|||
"order by d.ProductID, c.Region"; |
|||
string SQL2 = "select c.Region, sum(d.UnitPrice * d.Quantity) as Amount, sum(d.Quantity) as Quantity " + |
|||
"from(Orders m inner join OrderDetails d on m.OrderId = d.OrderId) " + |
|||
"left join Customers c on c.CustomerID = m.CustomerID " + |
|||
"where d.ProductID = 11 and m.OrderDate between #1997/1/1# and #1997/12/31# " + |
|||
"group by c.Region " + |
|||
"order by c.Region"; |
|||
|
|||
ArrayList QueryList = new ArrayList(); |
|||
QueryList.Add(new ReportQueryItem(SQL, "Table1")); |
|||
QueryList.Add(new ReportQueryItem(SQL, "Table2")); |
|||
QueryList.Add(new ReportQueryItem(SQL, "Table3")); |
|||
QueryList.Add(new ReportQueryItem(SQL2, "Table4")); |
|||
return MyDbReportData.TextFromMultiSQL(QueryList); |
|||
} |
|||
|
|||
public static string FilterSaleSummary(string BeginDate, string EndDate) |
|||
{ |
|||
string QuerySQL = string.Format("select d.Productid,p.ProductName,sum(d.Quantity) as Quantity," + |
|||
"sum(d.UnitPrice*d.Quantity) as Amount " + |
|||
"from orders m inner join (OrderDetails d inner join Products p " + |
|||
"on d.ProductID=p.ProductID) on m.orderid=d.orderid " + |
|||
"where m.OrderDate between {2}{0}{2} And {2}{1}{2}" + |
|||
"group by d.Productid,p.ProductName " + |
|||
"order by d.Productid", BeginDate, EndDate, DatabaseReportData.DateSqlBracketChar); |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
|
|||
public static string FilterSaleDetail(string BeginDate, string EndDate, string ProductID) |
|||
{ |
|||
string QuerySQL = string.Format("select m.OrderId, m.OrderDate, d.Productid,p.ProductName,d.Quantity, " + |
|||
"d.UnitPrice*d.Quantity as Amount " + |
|||
"from orders m inner join (OrderDetails d inner join Products p on d.ProductID=p.ProductID) " + |
|||
"on m.orderid=d.orderid " + |
|||
"where (m.OrderDate between {3}{0}{3} And {3}{1}{3}) and d.Productid={2} " + |
|||
"order by m.OrderDate ", |
|||
BeginDate, EndDate, ProductID, DatabaseReportData.DateSqlBracketChar); |
|||
return MyDbReportData.TextFromOneSQL(QuerySQL); |
|||
} |
|||
#endregion
|
|||
|
|||
|
|||
#region 根据 HTTP 请求中的参数生成报表数据,主要是为例子报表自动分配合适的数据生成函数
|
|||
/// <summary>
|
|||
/// 为了避免 switch 语句的使用,建立数据名称与数据函数的映射(map)
|
|||
/// 在 Global.asax 中创建映射,即在WEB服务启动时初始化映射数据
|
|||
/// </summary>
|
|||
|
|||
//简单无参数报表数据的名称与函数映射表
|
|||
private delegate string SimpleDataFun(); |
|||
private static Dictionary<string, SimpleDataFun> SimpleDataFunMap = new Dictionary<string, SimpleDataFun>(); |
|||
|
|||
//有参数报表数据的名称与函数映射表,参数来自 HttpRequest
|
|||
private delegate string SpecialDataFun(HttpRequest Request); |
|||
private static Dictionary<string, SpecialDataFun> SpecialDataFunMap = new Dictionary<string, SpecialDataFun>(); |
|||
|
|||
public static string BuildByHttpRequest(HttpRequest Request) |
|||
{ |
|||
string DataText; |
|||
string DataName = Request.QueryString["data"]; |
|||
|
|||
Trace.Assert(SimpleDataFunMap.Count > 0, "DataFunMap isn't initialized!"); |
|||
|
|||
if (DataName != null) //if (DataName != "")
|
|||
{ |
|||
//根据数据名称查找映射表,如果找到,执行对应的报表数据函数获取数据
|
|||
SimpleDataFun simpleFun; |
|||
SpecialDataFun specialFun; |
|||
if (SimpleDataFunMap.TryGetValue(DataName, out simpleFun)) |
|||
{ |
|||
DataText = simpleFun(); |
|||
} |
|||
else if (SpecialDataFunMap.TryGetValue(DataName, out specialFun)) |
|||
{ |
|||
DataText = specialFun(Request); |
|||
} |
|||
else |
|||
{ |
|||
throw new Exception(string.Format("没有为报表数据 '{0}' 分配处理程序!", DataName)); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
string QuerySQL = Request.QueryString["QuerySQL"]; |
|||
if (QuerySQL != null) |
|||
{ |
|||
//根据传递的 HTTP 请求中的查询SQL获取数据
|
|||
DataText = DataTextProvider.Build(QuerySQL); |
|||
} |
|||
else if (Request.TotalBytes > 0) |
|||
{ |
|||
//从客户端发送的数据包中获取报表查询参数,URL有长度限制,当要传递的参数数据量比较大时,应该采用这样的方式
|
|||
//这里演示了用这样的方式传递一个超长查询SQL语句。
|
|||
byte[] FormData = Request.BinaryRead(Request.TotalBytes); |
|||
UTF8Encoding Unicode = new UTF8Encoding(); |
|||
int charCount = Unicode.GetCharCount(FormData, 0, Request.TotalBytes); |
|||
char[] chars = new Char[charCount]; |
|||
int charsDecodedCount = Unicode.GetChars(FormData, 0, Request.TotalBytes, chars, 0); |
|||
|
|||
QuerySQL = new String(chars); |
|||
|
|||
DataText = DataTextProvider.Build(QuerySQL); |
|||
} |
|||
else |
|||
{ |
|||
DataText = ""; |
|||
} |
|||
} |
|||
|
|||
return DataText; |
|||
} |
|||
|
|||
//初始化映射表(map),在 Global.asax 中被调用
|
|||
public static void InitDataFunMap() |
|||
{ |
|||
Trace.Assert(SimpleDataFunMap.Count <= 0, "DataFunMap already initialized!"); |
|||
|
|||
SimpleDataFunMap.Add("AppendBlankRow", DataTextProvider.AppendBlankRow); |
|||
SimpleDataFunMap.Add("Categories", DataTextProvider.Categories); |
|||
SimpleDataFunMap.Add("Chart_8b", DataTextProvider.Chart_8b); |
|||
SimpleDataFunMap.Add("Chart_8d", DataTextProvider.Chart_8d); |
|||
SimpleDataFunMap.Add("ContractOne", DataTextProvider.ContractOne); |
|||
SimpleDataFunMap.Add("CrossTab", DataTextProvider.CrossTab); |
|||
SimpleDataFunMap.Add("CrossTabByDay", DataTextProvider.CrossTabByDay); |
|||
SimpleDataFunMap.Add("CrossTabByMonth", DataTextProvider.CrossTabByMonth); |
|||
SimpleDataFunMap.Add("CrossTabCalendar", DataTextProvider.CrossTabCalendar); |
|||
SimpleDataFunMap.Add("CrossTabSubtotal", DataTextProvider.CrossTabSubtotal); |
|||
SimpleDataFunMap.Add("CrossTabYearMonth", DataTextProvider.CrossTabYearMonth); |
|||
SimpleDataFunMap.Add("Customer", DataTextProvider.Customer); |
|||
SimpleDataFunMap.Add("EmployeeOne", DataTextProvider.EmployeeOne); |
|||
SimpleDataFunMap.Add("FreeGridwithDetailGrid", DataTextProvider.FreeGridwithDetailGrid); |
|||
SimpleDataFunMap.Add("InvoiceMany", DataTextProvider.InvoiceMany); |
|||
SimpleDataFunMap.Add("InvoiceOne", DataTextProvider.InvoiceOne); |
|||
SimpleDataFunMap.Add("Picture", DataTextProvider.Picture); |
|||
SimpleDataFunMap.Add("RTFSample", DataTextProvider.RTFSample); |
|||
SimpleDataFunMap.Add("SaleByProduct", DataTextProvider.SaleByProduct); |
|||
SimpleDataFunMap.Add("SaleDetail", DataTextProvider.SaleDetail); |
|||
SimpleDataFunMap.Add("SaleSumByProduct", DataTextProvider.SaleSumByProduct); |
|||
SimpleDataFunMap.Add("SubReport_4a", DataTextProvider.SubReport_4a); |
|||
SimpleDataFunMap.Add("SubReport_4b", DataTextProvider.SubReport_4b); |
|||
SimpleDataFunMap.Add("SubReport_4c", DataTextProvider.SubReport_4c); |
|||
|
|||
SpecialDataFunMap.Add("Report_7_3g", DataTextProvider.Report_7_3g); |
|||
SpecialDataFunMap.Add("SubReport_4d", DataTextProvider.SubReport_4d); |
|||
SpecialDataFunMap.Add("FilterSaleSummary", DataTextProvider.FilterSaleSummary); |
|||
SpecialDataFunMap.Add("FilterSaleDetail", DataTextProvider.FilterSaleDetail); |
|||
} |
|||
|
|||
public static string SubReport_4d(HttpRequest Request) |
|||
{ |
|||
return DataTextProvider.SubReport_4d(Request.QueryString["city"]); |
|||
} |
|||
|
|||
public static string Report_7_3g(HttpRequest Request) |
|||
{ |
|||
return DataTextProvider.Report_7_3g(Convert.ToInt32(Request.QueryString["BeginNo"]), Convert.ToInt32(Request.QueryString["EndNo"])); |
|||
} |
|||
|
|||
public static string FilterSaleSummary(HttpRequest Request) |
|||
{ |
|||
return DataTextProvider.FilterSaleSummary(Request.QueryString["BeginDate"], Request.QueryString["EndDate"]); |
|||
} |
|||
|
|||
public static string FilterSaleDetail(HttpRequest Request) |
|||
{ |
|||
return DataTextProvider.FilterSaleDetail(Request.QueryString["BeginDate"], Request.QueryString["EndDate"], Request.QueryString["ProductID"]); |
|||
} |
|||
#endregion
|
|||
} |
|||
} |
@ -0,0 +1,194 @@ |
|||
///下面三个编译条件参数指定产生报表数据需要连接的数据库。如果都不定义,则用 OLEDB 数据驱动连接数据库
|
|||
///编译条件参数定义在项目属性的“生成->条件编译符号”里更合适,这样可以为整个项目使用
|
|||
///_OLEDB_REPORT_DS:指定用 OLEDB 数据驱动连接数据库
|
|||
///_MSSQL_REPORT_DS:指定用 Microsoft SQL Server 数据驱动连接数据库
|
|||
///_ORACLE_REPORT_DS:指定用 Oracle 数据驱动连接数据库
|
|||
#define _OLEDB_REPORT_DS
|
|||
//#define _MSSQL_REPORT_DS
|
|||
//#define _ORACLE_REPORT_DS
|
|||
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Data; |
|||
using System.Web; |
|||
|
|||
namespace GridReport |
|||
{ |
|||
|
|||
#if _ORACLE_REPORT_DS
|
|||
//using System.Data.OracleClient;
|
|||
using MyDbConnection = System.Data.OracleClient.OracleConnection; |
|||
using MyDbCommand = System.Data.OracleClient.OracleCommand; |
|||
using MyDbDataReader = System.Data.OracleClient.OracleDataReader; |
|||
using MyDbDataAdapter = System.Data.OracleClient.OracleDataAdapter; |
|||
#elif _MSSQL_REPORT_DS
|
|||
//using System.Data.SqlClient;
|
|||
using MyDbConnection = System.Data.SqlClient.SqlConnection; |
|||
using MyDbCommand = System.Data.SqlClient.SqlCommand; |
|||
using MyDbDataReader = System.Data.SqlClient.SqlDataReader; |
|||
using MyDbDataAdapter = System.Data.SqlClient.SqlDataAdapter; |
|||
#else
|
|||
//using System.Data.OleDb;
|
|||
using MyDbConnection = System.Data.OleDb.OleDbConnection; |
|||
using MyDbCommand = System.Data.OleDb.OleDbCommand; |
|||
using MyDbDataReader = System.Data.OleDb.OleDbDataReader; |
|||
using MyDbDataAdapter = System.Data.OleDb.OleDbDataAdapter; |
|||
#endif //#ifdef OLE_DB
|
|||
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
//class DatabaseReportData 产生提供给报表生成需要的 XML 或 JSON 数据
|
|||
public class DatabaseReportData |
|||
{ |
|||
//★特别提示★:数据库连接串,一定要改为实际的参数值
|
|||
#if _ORACLE_REPORT_DS
|
|||
public const string DbConnStr = "Data Source=dbmachine;Persist Security Info=True;User ID=hr;Password=hr;Unicode=True;"; |
|||
|
|||
public const char DateSqlBracketChar = '\''; |
|||
#elif _MSSQL_REPORT_DS
|
|||
//连接SQL Server数据库的连接串,应该修改为与实际一致。如果是运行Grid++Report本身的例子,应该首先附加例子数据库到
|
|||
//SQL Server2000/2005数据库上。
|
|||
public const string DbConnStr = "Data Source=(local);Initial Catalog=gridreport;Persist Security Info=True;User ID=sa;Password=;"; |
|||
|
|||
//定义在SQL中表示日期值的包围符号,Access用“#”, 而MS SQl Server用“'”,为了生成两者都可用的查询SQL语句,将其参数化定义出来。这样处理只是为了演示例子方便
|
|||
public const char DateSqlBracketChar = '\''; |
|||
#else
|
|||
//连接Grid++Report Access例子数据库的连接串,应该修改为与实际一致,如果安装目录不在C:\Grid++Report 6,应进行修改。
|
|||
//如果是运行为64位程序,连接串应该改为64位的,Provider为“Microsoft.ACE.OLEDB.12.0”
|
|||
//另64位的驱动不是Windows系统自带的,需要从微软官网下载安装,具体见帮助文档“开发指南->报表数据源->设计时报表数据源->连接 Access”中的说明
|
|||
//如果WEB服务器是64位的,则 Grid++Report 的报表服务器程序也是64位的,其连接串也要相应的改为用64位的
|
|||
public const string DbConnStr = @"Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=C:\Grid++Report 6\Samples\Data\Northwind.mdb"; //32位报表服务器程序连接串
|
|||
//public const string DbConnStr = @"Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=C:\Grid++Report 6\Samples\Data\Northwind.mdb"; //64位报表服务器程序连接串
|
|||
|
|||
//定义在SQL中表示日期值的包围符号,Access用“#”, 而MS SQl Server用“'”,为了生成两者都可用的查询SQL语句,将其参数化定义出来。这样处理只是为了演示例子方便
|
|||
public const char DateSqlBracketChar = '#'; |
|||
#endif //#ifdef OLE_DB
|
|||
|
|||
//根据查询SQL,产生提供给报表生成需要的 XML 数据,字段值为空也产生数据
|
|||
public static void FullGenNodeXmlData(HttpResponse Response, string QuerySQL, bool ToCompress) |
|||
{ |
|||
MyDbCommand ReportDataCommand = new MyDbCommand(QuerySQL, ReportConn); |
|||
MyDbDataReader ReportDataReader = ReportDataCommand.ExecuteReader(); |
|||
string Text = XMLReportData.FromDataReader(ReportDataReader); |
|||
GridReportDataResponse.Response(Response, Text, ToCompress ? ResponseDataType.ZipBinary : ResponseDataType.PlainText); |
|||
} |
|||
|
|||
//获取 Count(*) SQL 查询到的数据行数。参数 QuerySQL 指定获取报表数据的查询SQL
|
|||
public static int BatchGetDataCount(string QuerySQL) |
|||
{ |
|||
int Total = 0; |
|||
|
|||
MyDbCommand ReportDataCommand = new MyDbCommand(QuerySQL, ReportConn); |
|||
MyDbDataReader ReportDataReader = ReportDataCommand.ExecuteReader(); |
|||
if (ReportDataReader.Read()) |
|||
Total = ReportDataReader.GetInt32(0); |
|||
|
|||
return Total; |
|||
} |
|||
|
|||
#region protected function
|
|||
private static object dbcLock = new Object(); |
|||
|
|||
private static MyDbConnection _ReportConn = null; |
|||
|
|||
protected static MyDbConnection ReportConn |
|||
{ |
|||
get |
|||
{ |
|||
lock (dbcLock) |
|||
{ |
|||
if (_ReportConn == null) |
|||
{ |
|||
_ReportConn = new MyDbConnection(DbConnStr); |
|||
_ReportConn.Open(); |
|||
} |
|||
} |
|||
return _ReportConn; |
|||
} |
|||
} |
|||
#endregion protected function
|
|||
} |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
//class DatabaseXmlReportData 根据SQL产生报表需要的 XML 数据
|
|||
public class DatabaseXmlReportData : DatabaseReportData |
|||
{ |
|||
public static string TextFromOneSQL(string QuerySQL) |
|||
{ |
|||
DataSet ReportDataSet = new DataSet(); |
|||
|
|||
MyDbDataAdapter ReportDataAdapter = new MyDbDataAdapter(QuerySQL, ReportConn); |
|||
|
|||
ReportDataAdapter.Fill(ReportDataSet); |
|||
|
|||
return XMLReportData.FromDataSet(ReportDataSet); |
|||
} |
|||
|
|||
public static string TextFromMultiSQL(ArrayList QueryList) |
|||
{ |
|||
DataSet ReportDataSet = new DataSet(); |
|||
|
|||
foreach (ReportQueryItem item in QueryList) |
|||
{ |
|||
MyDbDataAdapter DataAdapter = new MyDbDataAdapter(item.QuerySQL, ReportConn); |
|||
|
|||
DataAdapter.Fill(ReportDataSet, item.RecordsetName); |
|||
} |
|||
|
|||
return XMLReportData.FromDataSet(ReportDataSet); |
|||
} |
|||
|
|||
public static void GenOneRecordset(HttpResponse Response, string QuerySQL) |
|||
{ |
|||
string Text = TextFromOneSQL(QuerySQL); |
|||
GridReportDataResponse.Response(Response, Text, GridReportDataResponse.DefaultDataType); |
|||
} |
|||
|
|||
public static void GenMultiRecordset(HttpResponse Response, ArrayList QueryList) |
|||
{ |
|||
string Text = TextFromMultiSQL(QueryList); |
|||
GridReportDataResponse.Response(Response, Text, GridReportDataResponse.DefaultDataType); |
|||
} |
|||
} |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
//class DatabaseJsonReportData 根据SQL产生报表需要的 JSON 数据
|
|||
public class DatabaseJsonReportData : DatabaseReportData |
|||
{ |
|||
public static string TextFromOneSQL(string QuerySQL) |
|||
{ |
|||
DataSet ReportDataSet = new DataSet(); |
|||
|
|||
MyDbDataAdapter ReportDataAdapter = new MyDbDataAdapter(QuerySQL, ReportConn); |
|||
|
|||
ReportDataAdapter.Fill(ReportDataSet); |
|||
|
|||
return JSONReportData.FromDataSet(ReportDataSet); |
|||
} |
|||
|
|||
public static string TextFromMultiSQL(ArrayList QueryList) |
|||
{ |
|||
DataSet ReportDataSet = new DataSet(); |
|||
|
|||
foreach (ReportQueryItem item in QueryList) |
|||
{ |
|||
MyDbDataAdapter DataAdapter = new MyDbDataAdapter(item.QuerySQL, ReportConn); |
|||
|
|||
DataAdapter.Fill(ReportDataSet, item.RecordsetName); |
|||
} |
|||
|
|||
return JSONReportData.FromDataSet(ReportDataSet); |
|||
} |
|||
|
|||
public static void GenOneRecordset(HttpResponse Response, string QuerySQL) |
|||
{ |
|||
string Text = TextFromOneSQL(QuerySQL); |
|||
GridReportDataResponse.Response(Response, Text, GridReportDataResponse.DefaultDataType); |
|||
} |
|||
|
|||
public static void GenMultiRecordset(HttpResponse Response, ArrayList QueryList) |
|||
{ |
|||
string Text = TextFromMultiSQL(QueryList); |
|||
GridReportDataResponse.Response(Response, Text, GridReportDataResponse.DefaultDataType); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,239 @@ |
|||
using System; |
|||
using System.Text; |
|||
using System.Data; |
|||
using System.IO; |
|||
using System.IO.Compression; |
|||
using System.Web; |
|||
|
|||
namespace GridReport |
|||
{ |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
//以下枚举指定报表数据的格式类型
|
|||
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; |
|||
} |
|||
}; |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
// GridReportDataResponse
|
|||
public class GridReportDataResponse |
|||
{ |
|||
//指定报表的默认数据类型,便于统一定义整个报表系统的数据类型
|
|||
//在报表开发调试阶段,通常指定为 ResponseDataType.PlainText, 以便在浏览器中查看响应的源文件时能看到可读的文本数据
|
|||
//在项目部署时,通常指定为 ResponseDataType.ZipBinary 或 ResponseDataType.ZipBase64,这样可以极大减少数据量,提供报表响应速度
|
|||
public const ResponseDataType DefaultDataType = ResponseDataType.PlainText; //PlainText ZipBinary ZipBase64
|
|||
|
|||
//将报表XML数据文本输出到HTTP请求
|
|||
public static void Response(HttpResponse Response, string DataText, ResponseDataType DataType) |
|||
{ |
|||
//报表XML数据的前后不能附加任何其它数据,否则XML数据将不能成功解析,所以调用ClearContent方法清理网页中前面多余的数据
|
|||
Response.ClearContent(); |
|||
|
|||
if (ResponseDataType.PlainText == DataType) |
|||
{ |
|||
// 把 xml 或 json 文本响应给客户端
|
|||
//Response.ContentType = "text/xml";
|
|||
Response.ContentType = "text/plain"; |
|||
Response.Write(DataText); |
|||
} |
|||
else |
|||
{ |
|||
//将string数据转换为byte[],以便进行压缩
|
|||
System.Text.UTF8Encoding converter = new System.Text.UTF8Encoding(); |
|||
byte[] XmlBytes = converter.GetBytes(DataText); |
|||
|
|||
//在 HTTP 头信息中写入报表数据压缩信息
|
|||
Response.AppendHeader("gr_zip_type", "deflate"); //指定压缩方法
|
|||
Response.AppendHeader("gr_zip_size", XmlBytes.Length.ToString()); //指定数据的原始长度
|
|||
Response.AppendHeader("gr_zip_encode", converter.HeaderName); //指定数据的编码方式 utf-8 utf-16 ...
|
|||
|
|||
// 把压缩后的xml数据发送给客户端
|
|||
if (ResponseDataType.ZipBinary == DataType) |
|||
{ |
|||
DeflateStream compressedzipStream = new DeflateStream(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); |
|||
Response.ContentType = "text/plain"; |
|||
Response.Write(Base64Text); |
|||
} |
|||
} |
|||
|
|||
//报表XML数据的前后不能附加任何其它数据,否则XML数据将不能成功解析,所以调用End方法放弃网页中后面不必要的数据
|
|||
Response.End(); |
|||
} |
|||
} |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
//class XMLReportData 产生报表需要的xml数据
|
|||
public class XMLReportData |
|||
{ |
|||
//根据 DataSet 产生提供给报表需要的XML文本数据
|
|||
public static string FromDataSet(DataSet ReportDataSet) |
|||
{ |
|||
return ReportDataSet.GetXml(); |
|||
} |
|||
|
|||
//根据 DataTable 产生提供给报表需要的XML文本数据
|
|||
public static string FromDataTable(DataTable mydt) |
|||
{ |
|||
DataSet ds = new DataSet(); |
|||
ds.Tables.Add(mydt); |
|||
return FromDataSet(ds); |
|||
} |
|||
|
|||
//根据IDataReader, 产生提供给报表需要的XML文本数据
|
|||
public static string FromDataReader(IDataReader dr) |
|||
{ |
|||
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"; |
|||
|
|||
return XMLText; |
|||
} |
|||
} |
|||
|
|||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|||
//class JSONReportData 产生报表需要的 JSON 格式数据
|
|||
public class JSONReportData |
|||
{ |
|||
//根据 DataSet 产生提供给报表需要的JSON文本数据
|
|||
public static string FromDataSet(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(); |
|||
} |
|||
|
|||
//根据 DataTable 产生提供给报表需要的JSON文本数据
|
|||
public static string FromDataTable(DataTable dt) |
|||
{ |
|||
DataSet ds = new DataSet(); |
|||
ds.Tables.Add(dt); |
|||
return FromDataSet(ds); |
|||
} |
|||
|
|||
////如果数据中包含有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();
|
|||
// }
|
|||
//}
|
|||
} |
|||
} |
@ -0,0 +1 @@ |
|||
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 |
@ -0,0 +1 @@ |
|||
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 |
@ -0,0 +1 @@ |
|||
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 |
@ -0,0 +1 @@ |
|||
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 |
@ -0,0 +1 @@ |
|||
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 |
@ -0,0 +1 @@ |
|||
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 |
@ -0,0 +1 @@ |
|||
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 |
@ -0,0 +1 @@ |
|||
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 |
@ -0,0 +1,4 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<packages> |
|||
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net452" /> |
|||
</packages> |
Loading…
Reference in new issue