zoukankan      html  css  js  c++  java
  • RDLC后台自己定义报表模板

    首先封装一个公共类,统一来操作RDLC报表

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Xml;
    using System.Data;
    using Microsoft.Reporting.WebForms;
    using System.Text;
    using System.Collections;
    using System.IO;
    using System.Reflection;
    using System.Xml.Serialization;
    
    
    namespace WebApplication3
    {
        public class DynamicReport : IDynamicReport
        {
            #region 空白文档
    
    
            /// <summary>
            /// 空白文档的xml文件
            /// </summary>
            protected string _docTemplate =
                "<?xml version="1.0" encoding="utf-8"?

    ><Report xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner" xmlns="http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition">" + "<DataSources>" + " <DataSource Name="DummyDataSource">" + " <ConnectionProperties>" + " <DataProvider>SQL</DataProvider>" + " <ConnectString />" + " </ConnectionProperties>" + " <rd:DataSourceID>3eecdab9-6b4b-4836-ad62-95e4aee65ea8</rd:DataSourceID>" + " </DataSource>" + "</DataSources>" + "<DataSets>@DataSets</DataSets>" + "<Body>" + "<ReportItems>@Title@Tablix" + "</ReportItems>" + "<Style />" + "<Height>8cm</Height>" + "</Body>" + "<Width>17cm</Width>" + "<Page>" + "<PageHeight>29.7cm</PageHeight>" + "<PageWidth>21cm</PageWidth>" + "<LeftMargin>1.8cm</LeftMargin>" + "<RightMargin>1.8cm</RightMargin>" + "<TopMargin>1.8cm</TopMargin>" + "<BottomMargin>1.8cm</BottomMargin>" + "<ColumnSpacing>0.13cm</ColumnSpacing>" + "<Style />" + "</Page>" + "<rd:ReportID>809f16cf-ea78-4469-bf43-965c4afe69d0</rd:ReportID>" + "<rd:ReportUnitType>Cm</rd:ReportUnitType>" + "</Report>"; protected string TitlePattern = " <Textbox Name="Textbo@TextboxName"> " + @"<CanGrow>true</CanGrow> <KeepTogether>true</KeepTogether> <Paragraphs> <Paragraph> <TextRuns> <TextRun> <Value>@Title</Value> <Style>@FontStyle</Style> </TextRun> </TextRuns> <Style>@Style</Style> </Paragraph> </Paragraphs> <rd:DefaultName>Textbo@TextboxName</rd:DefaultName> <Top>@TopPositioncm</Top> <Left>1cm</Left> <Height>0.83813cm</Height> <Width>14.35207cm</Width> <ZIndex>1</ZIndex> <Style> <Border> <Style>None</Style> </Border> <PaddingLeft>2pt</PaddingLeft> <PaddingRight>2pt</PaddingRight> <PaddingTop>2pt</PaddingTop> <PaddingBottom>2pt</PaddingBottom> </Style> </Textbox>"; #endregion private ReportViewer _report; private List<ReportColoumStyle> _coloumStyle = new List<ReportColoumStyle>(); private List<ReportItemPattern> _reportItemPatterns = new List<ReportItemPattern>(); private List<string> _reportTitlePatterns = new List<string>(); private List<ReportItemPattern> _reportHeadPatterns = new List<ReportItemPattern>(); internal const float ColoumWidth = 1.6F; //行宽 public ReportType ReportType { get; set; } public DynamicReport() { } /// <summary> /// 从现有报表中载入报表并进行改动 /// </summary> /// <param name="url"></param> public void LoadReport(string url) { try { _docTemplate = File.ReadAllText(url); } catch (Exception ex) { } } public void SetReport(ReportViewer reportViewer) { this._report = reportViewer; } public void SetColoumStyle(List<ReportColoumStyle> coloumStyle) { this._coloumStyle = coloumStyle; } public void AddText(string text) { if (!string.IsNullOrEmpty(text)) { var pos = CaculatePlacePostion(); var titlePattern = TitlePattern .Replace("@Title", text) .Replace("@TopPosition", pos.ToString()) .Replace("@TextboxName", _reportTitlePatterns.Count.ToString()) .Replace("@FontStyle", "<FontFamily>微软雅黑</FontFamily><FontSize>12pt</FontSize>") .Replace("@Style", "<TextAlign>Center</TextAlign>"); _reportTitlePatterns.Add(titlePattern); } } public void AddText(string text, int chapterGrade) { if (!string.IsNullOrEmpty(text)) { var pos = CaculatePlacePostion(); var titlePattern = TitlePattern .Replace("@Title", text) .Replace("@TopPosition", pos.ToString()) .Replace("@TextboxName", _reportTitlePatterns.Count.ToString()); switch (chapterGrade) { case 1: titlePattern = titlePattern.Replace("@FontStyle", "<FontFamily>宋体</FontFamily><FontSize>18pt</FontSize><Color>#000000</Color>") .Replace("@Style", "<TextAlign>Center</TextAlign>"); break; case 2: titlePattern = titlePattern.Replace("@FontStyle", "<FontFamily>黑体</FontFamily><FontSize>14pt</FontSize><Color>#000000</Color>") .Replace("@Style", "<TextAlign>Left</TextAlign>"); break; case 3: titlePattern = titlePattern.Replace("@FontStyle", "<FontFamily>宋体</FontFamily><FontSize>12pt</FontSize><FontWeight>Bold</FontWeight>") .Replace("@Style", "<TextAlign>Left</TextAlign>"); break; default: case 10: titlePattern = titlePattern.Replace("@FontStyle", "<FontFamily>宋体</FontFamily><FontSize>12pt</FontSize>") .Replace("@Style", "<LineHeight>22pt</LineHeight>"); break; } _reportTitlePatterns.Add(titlePattern); } } public void AddData<T>(IEnumerable<T> data) { if (data.Count() != 0) { var properites = typeof(T).GetProperties(); //得到实体类属性的集合 AddReportItemPattern(properites.Select(p => p.Name).ToArray(), data); } } public void AddData(DataTable dataTable) { if (dataTable != null) { var coloumNames = new List<string>(); foreach (DataColumn dataColumn in dataTable.Columns) { var protertyName = dataColumn.ColumnName; coloumNames.Add(protertyName); } AddReportItemPattern(coloumNames.ToArray(), dataTable); } } /// <summary> /// 计算開始摆放的位置 /// </summary> /// <returns></returns> protected float CaculatePlacePostion() { //每一个标题的高度 float titleCount = _reportTitlePatterns.Count * 1f; //每一个数据表的高度 float itemCount = _reportItemPatterns.Count * 2f; // 每一个空表头的高度 float emptyItemCount = _reportHeadPatterns.Count * 0.5f; switch (ReportType) { case ReportType.Tables: return titleCount + itemCount + emptyItemCount + 0.5f; case ReportType.Chart: case ReportType.Finally: return titleCount + itemCount + emptyItemCount + 25.7f; } return 0f; } /// <summary> /// 添加一个报表 /// </summary> /// <param name="coloumNames"></param> /// <param name="data"></param> /// <param name="dataType"></param> protected void AddReportItemPattern(string[] coloumNames, dynamic data) { var fields = new StringBuilder(); var coloums = new StringBuilder(); var tablixHearders = new StringBuilder(); var tablixCells = new StringBuilder(); var tablixMembers = new StringBuilder(); var currentNamePrefix = _reportItemPatterns.Count + _reportHeadPatterns.Count + 1; var tableWidth = 0F; var dataRows = GetDataRowsCount(data); //数据行数 foreach (var coloumName in coloumNames) { var coloumWidth = ColoumWidth; var textAlign = TextAlign.Right; var reportColoumStyle = _coloumStyle.FirstOrDefault(r => r.ColoumName == coloumName); if (reportColoumStyle != null) { textAlign = reportColoumStyle.TextAlign; coloumWidth = reportColoumStyle.ColoumWidth; } tableWidth += coloumWidth; var bottomBorder = string.Empty; //每一个单元格底部border if (dataRows == 0) { bottomBorder = "<BottomBorder><Style>None</Style></BottomBorder>"; } var coloumValue = coloumName; //例外,假设coloumName包括Coloum之类的字段,则将value设成空 if (coloumName.IndexOf("Column", System.StringComparison.Ordinal) > -1) { coloumValue = " "; } fields.AppendFormat( "<Field Name="{0}"><DataField>{0}</DataField><rd:TypeName>System.String</rd:TypeName></Field>", coloumName); coloums.AppendFormat("<TablixColumn><Width>{0}cm</Width></TablixColumn>", coloumWidth); tablixHearders.AppendFormat("<TablixCell><CellContents>" + "<Textbox Name="Textbox{0}{1}"><CanGrow>true</CanGrow><KeepTogether>true</KeepTogether><Paragraphs><Paragraph>" + "<TextRuns><TextRun><Value>{2}</Value><Style /></TextRun></TextRuns><Style><TextAlign>Center</TextAlign></Style></Paragraph></Paragraphs>" + "<rd:DefaultName>Textbox{0}{1}</rd:DefaultName><Style><Border><Color>LightGrey</Color><Style>Solid</Style></Border>{3}" + "<PaddingLeft>2pt</PaddingLeft><PaddingRight>2pt</PaddingRight><PaddingTop>2pt</PaddingTop><PaddingBottom>2pt</PaddingBottom></Style></Textbox></CellContents></TablixCell>", coloumName, currentNamePrefix, coloumValue, bottomBorder); tablixCells.AppendFormat( "<TablixCell><CellContents><Textbox Name="{0}{1}1"><CanGrow>true</CanGrow><KeepTogether>true</KeepTogether>" + "<Paragraphs><Paragraph><TextRuns><TextRun><Value>=Fields!{0}.Value</Value><Style /></TextRun></TextRuns><Style><TextAlign>{2}</TextAlign></Style></Paragraph></Paragraphs>" + "<rd:DefaultName>{0}{1}1</rd:DefaultName><Style><Border><Color>LightGrey</Color><Style>Solid</Style></Border>" + "<PaddingLeft>2pt</PaddingLeft><PaddingRight>2pt</PaddingRight><PaddingTop>2pt</PaddingTop><PaddingBottom>2pt</PaddingBottom></Style></Textbox></CellContents></TablixCell>", coloumName, currentNamePrefix, textAlign); tablixMembers.AppendFormat("<TablixMember />"); } //计算表格应该离左边多少距离 var leftPosition = 0F; if (tableWidth < 17) { leftPosition = (17F - tableWidth) / 2; } var dataSetName = string.Format("Data{0}", _reportItemPatterns.Count + _reportHeadPatterns.Count + 1); var reportItemPattern = new ReportItemPattern(); reportItemPattern.Data = DynamicReportExtension.RemoveZeroData(data); reportItemPattern.DataSetName = dataSetName; reportItemPattern.DataSetString = reportItemPattern.DataSetPattern .Replace("@DataSetName", dataSetName) .Replace("@Fields", fields.ToString()); reportItemPattern.TablixString = reportItemPattern.TablixPattern .Replace("@DataSetName", dataSetName) .Replace("@TablixColumns", coloums.ToString()) .Replace("@TablixHeader", tablixHearders.ToString()) .Replace("@TablixCells", tablixCells.ToString()) .Replace("@TablixMember", tablixMembers.ToString()) .Replace("@TopPosition", CaculatePlacePostion().ToString()) .Replace("@LeftPostion", leftPosition.ToString()); //读取行数,假设是空行就加到新的 if (dataRows == 0) { _reportHeadPatterns.Add(reportItemPattern); } else { _reportItemPatterns.Add(reportItemPattern); } } /// <summary> /// 得到某种类型数据的数量 /// </summary> /// <param name="data"></param> /// <returns></returns> private int GetDataRowsCount(dynamic data) { if (data is DataTable) { return ((DataTable)data).Rows.Count; } else if (data is IEnumerable) { return Enumerable.Count(data); } else return 0; } /// <summary> /// 终于显示报表 /// </summary> public void ShowReport() { //将每一个patter转换 if (_reportItemPatterns.Count > 0 || _reportTitlePatterns.Count > 0) { var dataSetsString = new StringBuilder(); var tablixString = new StringBuilder(); foreach (var reportItemPattern in _reportItemPatterns) { dataSetsString.Append(reportItemPattern.DataSetString); tablixString.Append(reportItemPattern.TablixString); } foreach (var reportItemPattern in _reportHeadPatterns) { dataSetsString.Append(reportItemPattern.DataSetString); tablixString.Append(reportItemPattern.TablixString); } var reportTitleString = new StringBuilder(); foreach (var reportTitlePattern in _reportTitlePatterns) { reportTitleString.Append(reportTitlePattern); } //把文档中的文字替换掉 switch (ReportType) { case ReportType.Tables: _docTemplate = _docTemplate.Replace("@DataSets", dataSetsString.ToString()) .Replace("@Tablix", tablixString.ToString()) .Replace("@Title", reportTitleString.ToString()); break; case ReportType.Chart: break; case ReportType.Finally: //替换datasetstring var pos = _docTemplate.IndexOf("<Body>", StringComparison.Ordinal); _docTemplate = _docTemplate.Insert(pos, string.Format( "<DataSources><DataSource Name="DummyDataSource"><ConnectionProperties><DataProvider>SQL</DataProvider><ConnectString /></ConnectionProperties><rd:DataSourceID>3eecdab9-6b4b-4836-ad62-95e4aee65ea8</rd:DataSourceID></DataSource></DataSources><DataSets>{0}</DataSets>", dataSetsString)); //替换Tablix pos = _docTemplate.IndexOf("<ReportItems>", StringComparison.Ordinal); _docTemplate = _docTemplate.Insert(pos + 13, tablixString.ToString()); //替换title _docTemplate = _docTemplate.Insert(pos + 13, reportTitleString.ToString()); break; } var doc = new XmlDocument(); doc.LoadXml(_docTemplate); Stream stream = GetRdlcStream(doc); //载入报表定义 _report.LocalReport.LoadReportDefinition(stream); _report.LocalReport.DataSources.Clear(); foreach (var reportItemPattern in _reportItemPatterns) { _report.LocalReport.DataSources .Add(new ReportDataSource(reportItemPattern.DataSetName + "Data", reportItemPattern.Data)); } foreach (var reportItemPattern in _reportHeadPatterns) { _report.LocalReport.DataSources .Add(new ReportDataSource(reportItemPattern.DataSetName + "Data", reportItemPattern.Data)); } _report.LocalReport.Refresh(); } } /// <summary> /// 序列化到内存流 /// </summary> /// <returns></returns> protected Stream GetRdlcStream(XmlDocument xmlDoc) { Stream ms = new MemoryStream(); XmlSerializer serializer = new XmlSerializer(typeof(XmlDocument)); serializer.Serialize(ms, xmlDoc); ms.Position = 0; return ms; } } public interface IDynamicReport { void SetReport(ReportViewer reportViewer); void AddData<T>(IEnumerable<T> data); void AddData(DataTable dataTable); void ShowReport(); void LoadReport(string reportPath); void SetColoumStyle(List<ReportColoumStyle> coloumStyle); void AddText(string title); } public class ReportColoumStyle { public string ColoumName { get; set; } public float ColoumWidth { get; set; } public TextAlign TextAlign { get; set; } public ReportColoumStyle() { ColoumWidth = DynamicReport.ColoumWidth; } } public enum TextAlign { Left, Center, Right } public enum ReportType { Tables, Chart, Finally } internal enum DataType { DataTable, Enumerable } internal class ReportItemPattern { public string DataSetName { get; set; } public string DataSetString { get; set; } public string TablixString { get; set; } public dynamic Data { get; set; } public string DataSetPattern { get { return " <DataSet Name="@DataSetNameData">" + " <Fields>@Fields</Fields>" + " <Query>" + " <DataSourceName>DummyDataSource</DataSourceName>" + " <CommandText />" + " </Query>" + " </DataSet>"; } } public string TablixPattern { get { return " <Tablix Name="Tablix@DataSetName">" + " <TablixBody>" + " <TablixColumns>@TablixColumns</TablixColumns>" + " <TablixRows>" + " <TablixRow>" + " <Height>0.23622in</Height>" + " <TablixCells>@TablixHeader</TablixCells>" + " </TablixRow>" + " <TablixRow>" + " <Height>0.23622in</Height>" + " <TablixCells>@TablixCells</TablixCells>" + " </TablixRow>" + " </TablixRows>" + " </TablixBody>" + " <TablixColumnHierarchy>" + " <TablixMembers>@TablixMember</TablixMembers>" + " </TablixColumnHierarchy>" + " <TablixRowHierarchy>" + " <TablixMembers>" + " <TablixMember>" + " <KeepWithGroup>After</KeepWithGroup>" + " </TablixMember>" + " <TablixMember>" + " <Group Name="具体信息@DataSetName" />" + " </TablixMember>" + " </TablixMembers>" + " </TablixRowHierarchy>" + " <DataSetName>@DataSetNameData</DataSetName>" + " <Top>@TopPositioncm</Top>" + " <Left>@LeftPostioncm</Left>" + " <Height>1.2cm</Height>" + " <Width>14.35207cm</Width>" + " <Style>" + " <Border>" + " <Style>None</Style>" + " </Border>" + " </Style>" + "</Tablix>"; } } } internal static class DynamicReportExtension { public static dynamic RemoveZeroData(this object data) { if (data is DataTable) { return ((DataTable)data).ChangeEachColumnTypeToString(); } else if (data is IEnumerable) { var _data = ((IEnumerable)data).Cast<object>(); return _data.CopyToDataTable().RemoveZeroData(); } return data; } public static DataTable ChangeEachColumnTypeToString(this DataTable dt) { DataTable tempdt = new DataTable(); foreach (DataColumn dc in dt.Columns) { DataColumn tempdc = new DataColumn(); tempdc.ColumnName = dc.ColumnName; tempdc.DataType = typeof(String); tempdt.Columns.Add(tempdc); } int coloumCount = dt.Columns.Count; foreach (DataRow dr in dt.Rows) { var newrow = tempdt.NewRow(); for (int i = 0; i < coloumCount; i++) { var value = dr[i].ToString(); switch (value) { case "0": case "0.00%": newrow[i] = "-"; break; default: newrow[i] = value; break; } } tempdt.Rows.Add(newrow); } return tempdt; } } internal static class DataSetLinqOperators { public static DataTable CopyToDataTable<T>(this IEnumerable<T> source) { return new ObjectShredder<T>().Shred(source, null, null); } public static DataTable CopyToDataTable<T>(this IEnumerable<T> source, DataTable table, LoadOption? options) { return new ObjectShredder<T>().Shred(source, table, options); } } internal class ObjectShredder<T> { private FieldInfo[] _fi; private PropertyInfo[] _pi; private Dictionary<string, int> _ordinalMap; private Type _type; public ObjectShredder() { _type = typeof(T); _fi = _type.GetFields(); _pi = _type.GetProperties(); _ordinalMap = new Dictionary<string, int>(); } public DataTable Shred(IEnumerable<T> source, DataTable table, LoadOption?

    options) { if (typeof(T).IsPrimitive) { return ShredPrimitive(source, table, options); } if (table == null) { table = new DataTable(typeof(T).Name); } // now see if need to extend datatable base on the type T + build ordinal map table = ExtendTable(table, typeof(T)); table.BeginLoadData(); using (IEnumerator<T> e = source.GetEnumerator()) { while (e.MoveNext()) { if (options != null) { table.LoadDataRow(ShredObject(table, e.Current), (LoadOption)options); } else { table.LoadDataRow(ShredObject(table, e.Current), true); } } } table.EndLoadData(); return table; } public DataTable ShredPrimitive(IEnumerable<T> source, DataTable table, LoadOption? options) { if (table == null) { table = new DataTable(typeof(T).Name); } if (!table.Columns.Contains("Value")) { table.Columns.Add("Value", typeof(T)); } table.BeginLoadData(); using (IEnumerator<T> e = source.GetEnumerator()) { Object[] values = new object[table.Columns.Count]; while (e.MoveNext()) { values[table.Columns["Value"].Ordinal] = e.Current; if (options != null) { table.LoadDataRow(values, (LoadOption)options); } else { table.LoadDataRow(values, true); } } } table.EndLoadData(); return table; } public DataTable ExtendTable(DataTable table, Type type) { // value is type derived T, may need to extend table. foreach (FieldInfo f in type.GetFields()) { if (!_ordinalMap.ContainsKey(f.Name)) { DataColumn dc = table.Columns.Contains(f.Name) ? table.Columns[f.Name] : table.Columns.Add(f.Name, f.FieldType); _ordinalMap.Add(f.Name, dc.Ordinal); } } foreach (PropertyInfo p in type.GetProperties()) { if (!_ordinalMap.ContainsKey(p.Name)) { DataColumn dc = table.Columns.Contains(p.Name) ? table.Columns[p.Name] : table.Columns.Add(p.Name, p.PropertyType); _ordinalMap.Add(p.Name, dc.Ordinal); } } return table; } public object[] ShredObject(DataTable table, T instance) { FieldInfo[] fi = _fi; PropertyInfo[] pi = _pi; if (instance.GetType() != typeof(T)) { ExtendTable(table, instance.GetType()); fi = instance.GetType().GetFields(); pi = instance.GetType().GetProperties(); } Object[] values = new object[table.Columns.Count]; foreach (FieldInfo f in fi) { values[_ordinalMap[f.Name]] = f.GetValue(instance); } foreach (PropertyInfo p in pi) { values[_ordinalMap[p.Name]] = p.GetValue(instance, null); } return values; } } }

    以下的情况在前端绑定就能够

     

    private DataTable CreateData()
            {
                DataTable dt = new DataTable();
                dt.Columns.Add("专业名称");
                dt.Columns.Add("学院");
                dt.Columns.Add("就业去向");
                for (int i = 0; i < 100; i++)
                {
                    DataRow dr = dt.NewRow();
                    dr[0] = "我是"+i;
                    dr[1] = "三年级";
                    dr[2] = "二班";
                    dt.Rows.Add(dr);
                }
                return dt;
            }
    
    
            private void DynamicBindRV()
            {
                //new一个报表类对象
                var dynamicReport = new DynamicReport { ReportType = ReportType.Tables };
                //设置报表为本地报表
                dynamicReport.SetReport(this.ReportViewer1);
                //设置列宽度和对齐方式(可选)
                dynamicReport.SetColoumStyle(new List<ReportColoumStyle>()
                        {
                            new ReportColoumStyle(){ColoumName = "专业名称", ColoumWidth = 4F},
                            new ReportColoumStyle() {ColoumName = "学院", ColoumWidth = 3.5F},
                            new ReportColoumStyle(){ColoumName = "就业去向", ColoumWidth = 10F},
                        });
                //增加标题
                dynamicReport.AddText("測试");
                //增加数据
                dynamicReport.AddData(CreateData());
                //设置导出报表的名称
                ReportViewer1.LocalReport.DisplayName = "測试";
                //处理报表数据并显示
                dynamicReport.ShowReport();
            }




  • 相关阅读:
    每日日报
    每日日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    NavigationDuplicated {_name: "NavigationDuplicated", name: "NavigationDuplicated"}
    2020.11.07
    2020.11.05
    2020.11.09
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6806432.html
Copyright © 2011-2022 走看看