// 输出 RML 格式的表格 // 本函数负责写入 <table> 元素 // parameters: // nTopLines 顶部预留多少行 public void OutputRmlTable( Report report, SQLiteDataReader table, XmlTextWriter writer, int nMaxLines = -1) { // StringBuilder strResult = new StringBuilder(4096); int i, j; #if NO if (nMaxLines == -1) nMaxLines = table.Count; #endif writer.WriteStartElement("table"); writer.WriteAttributeString("class", "table"); writer.WriteStartElement("thead"); writer.WriteStartElement("tr"); int nEvalCount = 0; // 具有 eval 的栏目个数 for (j = 0; j < report.Count; j++) { PrintColumn column = (PrintColumn)report[j]; if (column.Colspan == 0) continue; if (string.IsNullOrEmpty(column.Eval) == false) nEvalCount++; writer.WriteStartElement("th"); if (string.IsNullOrEmpty(column.CssClass) == false) writer.WriteAttributeString("class", column.CssClass); if (column.Colspan > 1) writer.WriteAttributeString("colspan", column.Colspan.ToString()); writer.WriteString(column.Title); writer.WriteEndElement(); // </th> } writer.WriteEndElement(); // </tr> writer.WriteEndElement(); // </thead> // 合计数组 object[] sums = null; // 2008/12/1 new changed if (report.SumLine) { sums = new object[report.Count]; for (i = 0; i < sums.Length; i++) { sums[i] = null; } } NumberFormatInfo nfi = new CultureInfo("zh-CN", false).NumberFormat; nfi.NumberDecimalDigits = 2; writer.WriteStartElement("tbody"); // Jurassic.ScriptEngine engine = null; if (nEvalCount > 0 && engine == null) { engine = new Jurassic.ScriptEngine(); engine.EnableExposedClrTypes = true; } // 内容行循环 for (i = 0; ; i++) // i < Math.Min(nMaxLines, table.Count) { if (table.HasRows == false) break; // Line line = table[i]; if (engine != null) engine.SetGlobalValue("reader", table); string strLineCssClass = "content"; #if NO if (report.OutputLine != null) { OutputLineEventArgs e = new OutputLineEventArgs(); e.Line = line; e.Index = i; e.LineCssClass = strLineCssClass; report.OutputLine(this, e); if (e.Output == false) continue; strLineCssClass = e.LineCssClass; } #endif // strResult.Append("<tr class='" + strLineCssClass + "'>\r\n"); writer.WriteStartElement("tr"); writer.WriteAttributeString("class", strLineCssClass); // 列循环 for (j = 0; j < report.Count; j++) { PrintColumn column = (PrintColumn)report[j]; if (column.ColumnNumber < -1) { throw (new Exception("PrintColumn对象ColumnNumber列尚未初始化,位置" + Convert.ToString(j))); } string strText = ""; if (column.ColumnNumber != -1) { if (string.IsNullOrEmpty(column.Eval) == false) { // engine.SetGlobalValue("cell", line.GetObject(column.ColumnNumber)); strText = engine.Evaluate(column.Eval).ToString(); } else if (column.DataType == DataType.PriceDouble) { if (table.IsDBNull(column.ColumnNumber /**/) == true) strText = column.DefaultValue; else { double v = table.GetDouble(column.ColumnNumber); /* NumberFormatInfo provider = new NumberFormatInfo(); provider.NumberDecimalDigits = 2; provider.NumberGroupSeparator = "."; provider.NumberGroupSizes = new int[] { 3 }; strText = Convert.ToString(v, provider); * */ strText = v.ToString("N", nfi); } } else if (column.DataType == DataType.PriceDecimal) { if (table.IsDBNull(column.ColumnNumber) == true) strText = column.DefaultValue; else { decimal v = table.GetDecimal(column.ColumnNumber); strText = v.ToString("N", nfi); } } else if (column.DataType == DataType.PriceDecimal) { if (table.IsDBNull(column.ColumnNumber) == true) strText = column.DefaultValue; else { decimal v = table.GetDecimal(column.ColumnNumber); strText = v.ToString("N", nfi); } } else if (column.DataType == DataType.Price) { // Debug.Assert(false, ""); if (table.IsDBNull(column.ColumnNumber) == true) strText = column.DefaultValue; // 2005/5/26 else strText = table.GetString(column.ColumnNumber); // } else strText = table.GetString(column.ColumnNumber/*, column.DefaultValue*/); } else { strText = table.GetString(0); // line.Entry; } writer.WriteStartElement(j == 0 ? "th" : "td"); if (string.IsNullOrEmpty(column.CssClass) == false) writer.WriteAttributeString("class", column.CssClass); writer.WriteString(strText); writer.WriteEndElement(); // </td> if (report.SumLine == true && column.Sum == true && column.ColumnNumber != -1) { try { // if (column.DataType != DataType.Currency) { object v = table.GetValue(column.ColumnNumber); #if NO if (report.SumCell != null) { SumCellEventArgs e = new SumCellEventArgs(); e.DataType = column.DataType; e.ColumnNumber = column.ColumnNumber; e.LineIndex = i; e.Line = line; e.Value = v; report.SumCell(this, e); if (e.Value == null) continue; v = e.Value; } #endif if (sums[j] == null) sums[j] = v; else { sums[j] = AddValue(column.DataType, sums[j], v); // sums[j] = ((decimal)sums[j]) + v; } } } catch (Exception ex) // 俘获可能因字符串转换为整数抛出的异常 { throw new Exception("在累加 行 " + i.ToString() + " 列 " + column.ColumnNumber.ToString() + " 值的时候,抛出异常: " + ex.Message); } } } // strResult.Append("</tr>\r\n"); writer.WriteEndElement(); // </tr> }
// 根据一个表格按照缺省特性创建一个Report对象 // parameters: // strDefaultValue 全部列的缺省值 // null表示不改变缺省值"",否则为strDefaultValue指定的值 // bSum 是否全部列都要参加合计 // bContentColumn 是否考虑内容行中比指定的栏目多出来的栏目 public static Report BuildReport(SQLiteDataReader table, string strColumnTitles, string strDefaultValue, bool bSum, bool bContentColumn = true) { // Debug.Assert(false, ""); if (table.HasRows == false) return null; // 无法创建。内容必须至少一行以上 Report report = new Report(); // Line line = table.FirstHashLine(); // 随便得到一行。这样不要求table排过序 // 列标题 { PrintColumn column = new PrintColumn(); column.ColumnNumber = -1; report.Add(column); } int nTitleCount = 0; if (strColumnTitles != null) { string[] aName = strColumnTitles.Split(new Char[] { ',' }); nTitleCount = aName.Length; } int nColumnCount = nTitleCount; if (bContentColumn == true) nColumnCount = Math.Max(table.FieldCount, nTitleCount); // 检查表格第一行 // 因为列标题column已经加入,所以现在最多加入nTitleCount-1栏 for (int i = 0; i < nColumnCount - 1; i++) { PrintColumn column = new PrintColumn(); column.ColumnNumber = i; if (strDefaultValue != null) column.DefaultValue = strDefaultValue; column.Sum = bSum; report.Add(column); } // 添加列标题 if (strColumnTitles != null) { string[] aName = strColumnTitles.Split(new Char[] { ',' }); /* if (aName.Length < report.Count) { string strError = "列定义 '" + strColumnTitles + "' 中的列数 " + aName.Length.ToString() + "小于报表实际最大列数 " + report.Count.ToString(); throw new Exception(strError); }*/ int j = 0; for (j = 0; j < report.Count; j++) { // 2007/10/26 if (j >= aName.Length) break; string strText = ""; strText = aName[j]; string strNameText = ""; string strNameClass = ""; int nRet = strText.IndexOf("||"); if (nRet == -1) strNameText = strText; else { strNameText = strText.Substring(0, nRet); strNameClass = strText.Substring(nRet + 2); } PrintColumn column = (PrintColumn)report[j]; if (j < aName.Length) { column.Title = strNameText; column.CssClass = strNameClass; } } } report.SumLine = bSum; // 计算 colspan PrintColumn current = null; foreach (PrintColumn column in report) { if (string.IsNullOrEmpty(column.Title) == false && column.Title[0] == '+' && current != null) { column.Colspan = 0; // 表示这是一个从属的列 current.Colspan++; } else current = column; } return report; }