纽威
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
12 KiB

1 year ago
  1. using grsvr6Lib;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Data;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Web;
  10. namespace NFine.Code
  11. {
  12. public class ServerUtility
  13. {
  14. /// <summary>
  15. /// 将报表生成的二进制数据响应给 HTPP 请求客户端
  16. /// </summary>
  17. /// <param name="context"> HTPP 请求对象</param>
  18. /// <param name="ExportResult">报表生成的二进制数据</param>
  19. /// <param name="FileName">指定下载(或保存)文件时的默认文件名称</param>
  20. /// <param name="ContentType">响应的ContentType</param>
  21. /// <param name="OpenMode">指定生成的数据打开模式,可选[inline|attachment],"inline"表示在网页中内联显示,"attachment"表示以附件文件形式下载。如果不指定,由浏览器自动确定打开方式。</param>
  22. public static void ResponseBinary(HttpContext context, IGRBinaryObject ExportResult, string FileName, string ContentType, string OpenMode)
  23. {
  24. if (ExportResult.DataSize > 0)
  25. {
  26. string Disposition = "";
  27. if (OpenMode != null && OpenMode.Length > 0)
  28. Disposition = OpenMode + "; ";
  29. Disposition += ServerUtility.EncodeAttachmentFileName(context.Request.UserAgent, FileName);
  30. context.Response.ContentType = ContentType;
  31. context.Response.AppendHeader("Content-Length", ExportResult.DataSize.ToString());
  32. context.Response.AppendHeader("Content-Disposition", Disposition);
  33. context.Response.ClearContent();
  34. byte[] buffer = new byte[ExportResult.DataSize];
  35. System.Runtime.InteropServices.Marshal.Copy((IntPtr)ExportResult.DataBuf, buffer, 0, ExportResult.DataSize);
  36. context.Response.BinaryWrite(buffer);
  37. context.Response.Flush();
  38. }
  39. }
  40. /// <summary>
  41. /// 将异常信息文字响应给请求的客户端
  42. /// </summary>
  43. /// <param name="context"></param>
  44. /// <param name="MessageText"></param>
  45. public static void ResponseException(HttpContext context, string MessageText)
  46. {
  47. context.Response.ContentType = "text/plain";
  48. context.Response.Write(MessageText);
  49. }
  50. /// <summary>
  51. /// 为了文件名中的汉字与特殊字符能正确,必须进行分浏览器处理
  52. /// </summary>
  53. /// <param name="BrowserAgent"></param>
  54. /// <param name="RawFileName"></param>
  55. /// <returns></returns>
  56. public static string EncodeAttachmentFileName(string BrowserAgent, string RawFileName)
  57. {
  58. System.Text.UTF8Encoding UTF8Encoding = new System.Text.UTF8Encoding();
  59. string EncodedFileName = HttpUtility.UrlEncode(RawFileName, UTF8Encoding);
  60. // 如果没有BrowserAgent,则默认使用IE的方式进行编码,因为毕竟IE还是占多数的
  61. string ret = "filename=\"" + EncodedFileName + "\"";
  62. if (BrowserAgent != null && BrowserAgent.Length != 0)
  63. {
  64. BrowserAgent = BrowserAgent.ToLower();
  65. // msie 与 edge 采用默认的方式
  66. if ((BrowserAgent.IndexOf("msie") == -1) && (BrowserAgent.IndexOf("edge") == -1))
  67. {
  68. // Chrome浏览器,只能采用MimeUtility编码或ISO编码的中文输出
  69. if (BrowserAgent.IndexOf("applewebkit") != -1)
  70. {
  71. //EncodedFileName = MimeUtility.encodeText(RawFileName, "UTF8", "B");
  72. System.Text.UTF8Encoding UTF8EncodingBOM = new System.Text.UTF8Encoding(true);
  73. EncodedFileName = UTF8EncodingBOM.GetString(UTF8EncodingBOM.GetBytes(RawFileName));
  74. ret = "filename=\"" + EncodedFileName + "\"";
  75. }
  76. // Safari浏览器,只能采用ISO编码的中文输出
  77. else if (BrowserAgent.IndexOf("safari") != -1)
  78. {
  79. //28591 iso-8859-1 1252 *
  80. //ret = "filename=\"" + new String(filename.getBytes("UTF-8"), "ISO8859-1") + "\"";
  81. byte[] UTF8Bytes = UTF8Encoding.GetBytes(RawFileName);
  82. string ISO8859Text = System.Text.Encoding.GetEncoding(28591).GetString(UTF8Bytes);
  83. ret = "filename=\"" + ISO8859Text + "\"";
  84. }
  85. // Opera浏览器只能采用filename*
  86. // FireFox浏览器,可以使用MimeUtility或filename*或ISO编码的中文输出
  87. else if ((BrowserAgent.IndexOf("opera") != -1) || (BrowserAgent.IndexOf("mozilla") != -1))
  88. {
  89. ret = "filename*=UTF-8''" + EncodedFileName;
  90. }
  91. }
  92. }
  93. return ret;
  94. }
  95. /// <summary>
  96. /// 根据报表模板中的查询SQL获取报表数据
  97. /// </summary>
  98. //public static string BuildFromSelfSQL(GridppReportServer Report)
  99. //{
  100. // string DataText = "";
  101. // //从 XML 或 JSON 数据包中载入报表数据
  102. // string MasterQuerySQL = Report.QuerySQL;
  103. // string DetailQuerySQL = Report.DetailGrid != null ? Report.DetailGrid.Recordset.QuerySQL : null;
  104. // bool MasterAssigned = (MasterQuerySQL != null && MasterQuerySQL.Length > 0);
  105. // bool DetailAssigned = (DetailQuerySQL != null && DetailQuerySQL.Length > 0);
  106. // if (MasterAssigned || DetailAssigned)
  107. // {
  108. // if (MasterAssigned && DetailAssigned)
  109. // {
  110. // string MasterTableName = Report.XmlTableName;
  111. // if (MasterTableName == null || MasterTableName.Length == 0)
  112. // MasterTableName = "Master";
  113. // string DetailTableName = Report.DetailGrid.Recordset.XmlTableName;
  114. // if (DetailTableName == null || DetailTableName.Length == 0)
  115. // DetailTableName = "Detail";
  116. // ArrayList QueryList = new ArrayList();
  117. // QueryList.Add(new ReportQueryItem(DetailQuerySQL, DetailTableName));
  118. // QueryList.Add(new ReportQueryItem(MasterQuerySQL, MasterTableName));
  119. // DataText = DataTextProvider.Build(QueryList);
  120. // }
  121. // else
  122. // {
  123. // DataText = DataTextProvider.Build(MasterAssigned ? MasterQuerySQL : DetailQuerySQL);
  124. // }
  125. // }
  126. // return DataText;
  127. //}
  128. private struct MatchFieldPairType
  129. {
  130. public IGRField grField;
  131. public int MatchColumnIndex;
  132. }
  133. // 将 DataReader 的数据转储到 Grid++Report 的记录集中
  134. public static void FillRecordToReport(IGridppReport Report, IDataReader dr)
  135. {
  136. MatchFieldPairType[] MatchFieldPairs = new MatchFieldPairType[Math.Min(Report.DetailGrid.Recordset.Fields.Count, dr.FieldCount)];
  137. //根据字段名称与列名称进行匹配,建立DataReader字段与Grid++Report记录集的字段之间的对应关系
  138. int MatchFieldCount = 0;
  139. for (int i = 0; i < dr.FieldCount; ++i)
  140. {
  141. foreach (IGRField fld in Report.DetailGrid.Recordset.Fields)
  142. {
  143. if (String.Compare(fld.RunningDBField, dr.GetName(i), true) == 0)
  144. {
  145. MatchFieldPairs[MatchFieldCount].grField = fld;
  146. MatchFieldPairs[MatchFieldCount].MatchColumnIndex = i;
  147. ++MatchFieldCount;
  148. break;
  149. }
  150. }
  151. }
  152. // 将 DataReader 中的每一条记录转储到 Grid++Report 的记录集中去
  153. while (dr.Read())
  154. {
  155. Report.DetailGrid.Recordset.Append();
  156. for (int i = 0; i < MatchFieldCount; ++i)
  157. {
  158. if (!dr.IsDBNull(MatchFieldPairs[i].MatchColumnIndex))
  159. MatchFieldPairs[i].grField.Value = dr.GetValue(MatchFieldPairs[i].MatchColumnIndex);
  160. }
  161. Report.DetailGrid.Recordset.Post();
  162. }
  163. }
  164. // 将 DataTable 的数据转储到 Grid++Report 的记录集中
  165. public static void FillRecordToReport(IGridppReport Report, DataTable dt)
  166. {
  167. MatchFieldPairType[] MatchFieldPairs = new MatchFieldPairType[Math.Min(Report.DetailGrid.Recordset.Fields.Count, dt.Columns.Count)];
  168. //根据字段名称与列名称进行匹配,建立DataReader字段与Grid++Report记录集的字段之间的对应关系
  169. int MatchFieldCount = 0;
  170. for (int i = 0; i < dt.Columns.Count; ++i)
  171. {
  172. foreach (IGRField fld in Report.DetailGrid.Recordset.Fields)
  173. {
  174. if (String.Compare(fld.Name, dt.Columns[i].ColumnName, true) == 0)
  175. {
  176. MatchFieldPairs[MatchFieldCount].grField = fld;
  177. MatchFieldPairs[MatchFieldCount].MatchColumnIndex = i;
  178. ++MatchFieldCount;
  179. break;
  180. }
  181. }
  182. }
  183. // 将 DataTable 中的每一条记录转储到 Grid++Report 的记录集中去
  184. foreach (DataRow dr in dt.Rows)
  185. {
  186. Report.DetailGrid.Recordset.Append();
  187. for (int i = 0; i < MatchFieldCount; ++i)
  188. {
  189. if (!dr.IsNull(MatchFieldPairs[i].MatchColumnIndex))
  190. MatchFieldPairs[i].grField.Value = dr[MatchFieldPairs[i].MatchColumnIndex];
  191. }
  192. Report.DetailGrid.Recordset.Post();
  193. }
  194. }
  195. public static uint RGBToOleColor(byte r, byte g, byte b)
  196. {
  197. return ((uint)b) * 256 * 256 + ((uint)g) * 256 + r;
  198. }
  199. public static uint ColorToOleColor(System.Drawing.Color val)
  200. {
  201. return RGBToOleColor(val.R, val.G, val.B);
  202. }
  203. //判断当前运行进程是不是64位程序
  204. public static bool Is64bitProcess()
  205. {
  206. //IsWow64Process
  207. //也可以直接用Environment.Is64BitProcess,不过需要DotNet4.0或以上版本。
  208. return (IntPtr.Size == 8);
  209. }
  210. //生成数据源连接串,根据当前运行环境与配置参数进行实际调整
  211. public static string BuildOLEDBConnectionString()
  212. {
  213. //Grid++Report的64位程序通过OLE DB连接Access与32位程序使用完全不同的数据驱动程序,
  214. //此数据驱动程序(AccessDatabaseEngine_X64.exe)没有跟随Windows系统自动安装,需要从
  215. //微软网站下载并安装, 下载地址:https://www.microsoft.com/zh-CN/download/details.aspx?id=13255
  216. //如果直接不能安装,要先将Ofiice卸载后再进行安装,驱动程序安装后,在重新安装Office。
  217. return (Is64bitProcess() ? "Provider = Microsoft.ACE.OLEDB.12.0;" : "Provider=Microsoft.Jet.OLEDB.4.0;") +
  218. "User ID=Admin;Data Source=" + @"C:\Grid++Report 6\Samples\Data\NorthWind.mdb";
  219. }
  220. }
  221. public class ReportQueryItem
  222. {
  223. public string QuerySQL;
  224. public string RecordsetName;
  225. public ReportQueryItem(string AQuerySQL, string ARecordsetName)
  226. {
  227. QuerySQL = AQuerySQL;
  228. RecordsetName = ARecordsetName;
  229. }
  230. };
  231. }