当前位置:网站首页>动态RDLC报表(四)
动态RDLC报表(四)
2022-08-09 16:51:00 【xgh815】
动态RDLC报表类DynamicReport:页眉、页脚节点数据填充
我们就从页眉开始,页眉包含Logo、标题和标签三部分。
首先要给页眉定一个高度,这个高度还必需是固定,定得高则页眉和主体之间空白太多不美观,定少又有部分内容显示不出来,偏偏这个页眉中的内容是不固定,那只能用一个参数 headerHeight 来记录了。后面的页脚也一样用一个参数footerHeight来记录。
private float headerHeight = 0.0F;
private float footerHeight = 0.0F;
Logo部分大致包含一个Logo图片、企业名称、地址、电话、传真、邮箱和微信二维码,这些资料通过一个DataTable传递进来,然后通过AddLogo(DataTable dataTable, Boolean showLine)处理,保存到一个reportLogoString可变的字符序列里
private StringBuilder reportLogoString = new StringBuilder();
这个DataTable的数据后面还会用到,干脆就连公章、微信二维码、签名、人名、是不是审核一起传递进来,这个DataTable的结构如下:
DataTable dt = new DataTable();
dt.Columns.Add("OutletsLogo", Type.GetType("System.Byte[]"));
dt.Columns.Add("OutletsName", Type.GetType("System.String"));
dt.Columns.Add("OutletsAddress", Type.GetType("System.String"));
dt.Columns.Add("OutletsTel", Type.GetType("System.String"));
dt.Columns.Add("OutletsFax", Type.GetType("System.String"));
dt.Columns.Add("OutletsEmail", Type.GetType("System.String"));
dt.Columns.Add("OS", Type.GetType("System.Byte[]"));
dt.Columns.Add("SignatureImg", Type.GetType("System.Byte[]"));
dt.Columns.Add("EmployeeName", Type.GetType("System.String"));
dt.Columns.Add("Reviewed", Type.GetType("System.String"));
dt.Columns.Add("OutletsWeChat", Type.GetType("System.Byte[]"));
这个DataTable需要增加到DataSets节点中,名称为DataLogo,保存在_reportItemPatterns中,然后添加Logo图片、企业名称、地址、电话、传真、邮箱和微信二维码并保存到reportLogoString中,然后根据需要来增加一条分隔线。
需要注意设置左右边距、上边距和页眉高。
private List<ReportItemPattern> _reportItemPatterns = new List<ReportItemPattern>();
private StringBuilder reportLogoString = new StringBuilder();
private Boolean isSignature = true;
private Boolean isSignatureImg = false;
public void AddLogo(DataTable dataTable, Boolean showLine)
{
if (dataTable != null && dataTable.Rows.Count > 0)
{
if (headerHeight == 0) headerHeight += TopMargin;
var fields = new StringBuilder();
foreach (DataColumn dataColumn in dataTable.Columns)
{
fields.AppendFormat("<Field Name=\"{0}\"><DataField>{0}</DataField><rd:TypeName>" + dataColumn.DataType + "</rd:TypeName></Field>", dataColumn.ColumnName);
}
var dataSetName = "DataLogo";
var reportItemPattern = new ReportItemPattern();
reportItemPattern.Data = DynamicReportExtension.RemoveZeroData(dataTable);
reportItemPattern.DataSetName = dataSetName;
reportItemPattern.DataSetString = reportItemPattern.DataSetPattern.Replace("@DataSetName", dataSetName).Replace("@Fields", fields.ToString());
_reportItemPatterns.Add(reportItemPattern);
float logoWidth = pageWidth - leftMargin * 2 - leftMargin / 2;
float topPosition = topMargin;
float leftPosition = leftMargin + leftMargin / 2;
string imagesString = "";
if (dataTable.Rows[0]["OutletsLogo"] != DBNull.Value)
{
string imgPattern = " <Image Name=\"LogoImg\">" +
" <Source>Embedded</Source>" +
" <Value>LogoImg</Value>" +
" <MIMEType>image/png</MIMEType>" +
" <Sizing>FitProportional</Sizing>" +
" <Top>" + topPosition + "cm</Top>" +
" <Left>" + leftPosition + "cm</Left>" +
" <Height>1.6cm</Height>" +
" <Width>1.6cm</Width>" +
" <Style>" +
" <Border><Style>None</Style></Border>" +
" </Style>" +
" </Image>";
reportLogoString.Append(imgPattern);
leftPosition += 1.7F;
headerHeight += 1.7F;
logoWidth -= 1.7F;
imagesString += "<EmbeddedImage Name=\"LogoImg\"><MIMEType>image/png</MIMEType><ImageData>" + Convert.ToBase64String((Byte[])dataTable.Rows[0]["OutletsLogo"]) + "</ImageData></EmbeddedImage>";
}
if (dataTable.Rows[0]["OutletsWeChat"] != DBNull.Value)
{
string imgPattern = " <Image Name=\"WeChatImg\">" +
" <Source>Embedded</Source>" +
" <Value>WeChatImg</Value>" +
" <MIMEType>image/png</MIMEType>" +
" <Sizing>FitProportional</Sizing>" +
" <Top>" + topPosition + "cm</Top>" +
" <Left>" + (pageWidth - leftMargin - 1.5) + "cm</Left>" +
" <Height>1.5cm</Height>" +
" <Width>1.5cm</Width>" +
" <Style>" +
" <Border><Style>None</Style></Border>" +
" </Style>" +
" </Image>";
reportLogoString.Append(imgPattern);
logoWidth -= 1.6F;
imagesString += "<EmbeddedImage Name=\"WeChatImg\"><MIMEType>image/png</MIMEType><ImageData>" + Convert.ToBase64String((Byte[])dataTable.Rows[0]["OutletsWeChat"]) + "</ImageData></EmbeddedImage>";
}
Image imageOs = null;
Image imageSignature = null;
if (dataTable.Rows[0]["OS"] != DBNull.Value) imageOs = BytesToImage((Byte[])dataTable.Rows[0]["OS"]);
if (dataTable.Rows[0]["SignatureImg"] != DBNull.Value) imageSignature = BytesToImage((Byte[])dataTable.Rows[0]["SignatureImg"]);
if (dataTable.Rows[0]["Reviewed"].ToString().ToUpper() == "TRUE")
{
isSignatureImg = true;
Bitmap bitmap = CombinImage(imageOs, imageSignature, dataTable.Rows[0]["OutletsName"].ToString().Trim(), dataTable.Rows[0]["EmployeeName"].ToString().Trim(), fontString);
imagesString += "<EmbeddedImage Name=\"SignatureImg\"><MIMEType>image/png</MIMEType><ImageData>" + Convert.ToBase64String(ImageToBytes(bitmap)) + "</ImageData></EmbeddedImage>";
}
if (imagesString != "")
{
_docTemplate = _docTemplate.Replace("@LogoImageData", imagesString);
}
else
{
_docTemplate = _docTemplate.Replace("<EmbeddedImages>@LogoImageData</EmbeddedImages>", "");
}
if (dataTable.Rows[0]["OutletsName"].ToString() != "")
{
string namePattern = " <Textbox Name=\"LogoName\">" +
" <CanGrow>true</CanGrow>" +
" <KeepTogether>true</KeepTogether>" +
" <Paragraphs>" +
" <Paragraph>" +
" <TextRuns>" +
" <TextRun>" +
" <Value>" + dataTable.Rows[0]["OutletsName"].ToString() + "</Value>" +
" <Style><FontFamily>" + fontString + "</FontFamily><FontSize>16pt</FontSize></Style>" +
" </TextRun>" +
" </TextRuns>" +
" <Style>None</Style>" +
" </Paragraph>" +
" </Paragraphs>" +
" <rd:DefaultName>LogoName</rd:DefaultName>" +
" <Top>" + topPosition + "cm</Top>" +
" <Left>" + leftPosition + "cm</Left>" +
" <Height>1.0cm</Height>" +
" <Width>" + logoWidth + "cm</Width>" +
" <ZIndex>1</ZIndex>" +
" <Style>" +
" <VerticalAlign>Bottom</VerticalAlign>" +
" <Border><Style>None</Style></Border>" +
" <PaddingLeft>0pt</PaddingLeft>" +
" <PaddingRight>0pt</PaddingRight>" +
" <PaddingTop>0pt</PaddingTop>" +
" <PaddingBottom>0pt</PaddingBottom>" +
" </Style>" +
" </Textbox>";
reportLogoString.Append(namePattern);
topPosition += 1.0F;
if (headerHeight < 1.7F) headerHeight += 1.7F;
}
string address = "";
if (dataTable.Rows[0]["OutletsAddress"].ToString() != "") address = dataTable.Rows[0]["OutletsAddress"].ToString();
if (address != "")
{
if (dataTable.Rows[0]["OutletsTel"].ToString() != "") address += " " + dataTable.Rows[0]["OutletsTel"].ToString();
if (dataTable.Rows[0]["OutletsFax"].ToString() != "") address += " " + dataTable.Rows[0]["OutletsFax"].ToString();
if (dataTable.Rows[0]["OutletsEmail"].ToString() != "") address += " " + dataTable.Rows[0]["OutletsEmail"].ToString();
float fontHeight = 0.5F;
if (Graphics.FromHwnd(IntPtr.Zero).MeasureString(address, new Font(fontString, 8)).Width * 1.12 > MillimetersToPixelsWidth(logoWidth * 10) - 3)
{
fontHeight += 0.3F;
headerHeight += 0.3F;
}
string addrPattern = " <Textbox Name=\"LogoAddr\">" +
" <CanGrow>true</CanGrow>" +
" <KeepTogether>true</KeepTogether>" +
" <Paragraphs>" +
" <Paragraph>" +
" <TextRuns>" +
" <TextRun>" +
" <Value>" + address + "</Value>" +
" <Style><FontFamily>" + fontString + "</FontFamily><FontSize>8pt</FontSize></Style>" +
" </TextRun>" +
" </TextRuns>" +
" <Style>None</Style>" +
" </Paragraph>" +
" </Paragraphs>" +
" <rd:DefaultName>LogoAddr</rd:DefaultName>" +
" <Top>" + topPosition + "cm</Top>" +
" <Left>" + leftPosition + "cm</Left>" +
" <Height>" + fontHeight + "cm </Height>" +
" <Width>" + logoWidth + "cm</Width>" +
" <ZIndex>2</ZIndex>" +
" <Style>" +
" <VerticalAlign>Top</VerticalAlign>" +
" <Border><Style>None</Style></Border>" +
" <PaddingLeft>2pt</PaddingLeft>" +
" <PaddingRight>2pt</PaddingRight>" +
" <PaddingTop>0pt</PaddingTop>" +
" <PaddingBottom>2pt</PaddingBottom>" +
" </Style>" +
" </Textbox>";
reportLogoString.Append(addrPattern);
topPosition += fontHeight + 0.05F;
if (headerHeight < 1.7F) headerHeight += 1.7F;
}
if (topPosition > topMargin)
{
if (showLine)
{
string linePattern = " <Line Name=\"LineLogo\">" +
" <Top>" + topPosition + "cm</Top>" +
" <Left>" + leftMargin / 2 + "cm</Left>" +
" <Height>0.0cm</Height>" +
" <Width>" + (pageWidth - leftMargin) + "cm</Width>" +
" <ZIndex>3</ZIndex>" +
" <Style>" +
" <Border><Style>Solid</Style></Border>" +
" </Style>" +
" </Line>";
reportLogoString.Append(linePattern);
}
headerHeight += 0.1F;
topMargin = topPosition + 0.1F;
}
}
}
在这里面,还生成了一个签名、盖章的图片,后面会调用到。图章的大小根据需要设定。
public byte[] ImageToBytes(Image image)
{
System.IO.MemoryStream ms = new System.IO.MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] bytes = ms.GetBuffer();
ms.Close();
return bytes;
}
public Image BytesToImage(byte[] bytes)
{
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
Image image = Image.FromStream(ms);
ms.Close();
return image;
}
public static Bitmap CombinImage(Image imgOS, Image imgSignature, string outletsName, string employeeName, string fontString)
{
int width = 143;
int height = 143;
int top = 90;
if (imgOS != null)
{
if (imgOS.Width > 165)
{
width = 171;
height = 116;
top = 82;
}
}
if (imgSignature != null)
{
if (imgSignature.Height < top) top = height - imgSignature.Height + 10;
}
Bitmap bmp = new Bitmap(300, height + 20);
Graphics g = Graphics.FromImage(bmp);
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.CompositingQuality = CompositingQuality.HighQuality;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.Clear(Color.Transparent);
g.DrawLine(new Pen(Color.Black, 1), new Point(0, height - 10), new Point(300, height - 10));
if (outletsName != "") g.DrawString(outletsName, new Font(fontString, 12), new SolidBrush(Color.Black), (300 - g.MeasureString(outletsName, new Font(fontString, 12)).Width) / 2, height - 11);
if (imgSignature != null)
{
g.DrawImage(imgSignature, (300 - imgSignature.Width) / 2, top, imgSignature.Width, imgSignature.Height);
}
else
{
if (employeeName != "") g.DrawString(employeeName, new Font(fontString, 16), new SolidBrush(Color.Black), (300 - g.MeasureString(employeeName, new Font(fontString, 16)).Width) / 2, height - g.MeasureString(employeeName, new Font(fontString, 16)).Height - 10);
}
if (imgOS != null) g.DrawImage(imgOS, (300 - width) / 2, 1, width, height);
GC.Collect();
return bmp;
}
标签部分是不确定的,可以是多行单列或多行二列,数据好是通过一个DataTable传递进来。DataTable的结构为:
DataTable dt = new DataTable();
dt.Columns.Add("LeftName", Type.GetType("System.String"));
dt.Columns.Add("LeftValue", Type.GetType("System.String"));
dt.Columns.Add("RightName", Type.GetType("System.String"));
dt.Columns.Add("RightValue", Type.GetType("System.String"));
当需要使用一列标签时就只输入LeftName、LeftValue的值,RightName、RightValue留空;需要使用二列标签时则4个值都添加。
传递进来的数据用前面定义的标签格式生成节点,保存到reportLabelPatterns中,然后根据需要来增加一条分隔线。需要留意处理页眉高。
private List<string> reportLabelPatterns = new List<string>();
public void AddLabel(DataTable dataTable, Color color, Boolean showLine)
{
if (dataTable != null && dataTable.Rows.Count > 0)
{
if (headerHeight == 0) headerHeight += TopMargin;
float topPosition = topMargin;
float leftPosition = leftMargin;
float labelWidt = pageWidth - leftMargin * 2 - 0.31F;
float aWidth = labelWidt * 0.3F;
float bWidth = labelWidt * 0.7F;
float cWidth = labelWidt * 0.22F;
float dWidth = labelWidt * 0.23F;
if (dataTable.Columns.Count > 2)
{
labelWidt = pageWidth - leftMargin - 0.61F;
leftPosition = leftMargin / 2;
aWidth = labelWidt * 0.2F;
bWidth = labelWidt * 0.35F;
}
foreach (DataRow dataRow in dataTable.Rows)
{
var labelPattern = LabelPattern
.Replace("@TopPosition", topPosition.ToString())
.Replace("@TextboxName", reportLabelPatterns.Count.ToString())
.Replace("@FontString", fontString)
.Replace("@Color", color.Name.ToString())
.Replace("@NameText", dataRow[0].ToString())
.Replace("@NamePosition", leftPosition.ToString())
.Replace("@NameWidth", aWidth.ToString())
.Replace("@SplitPosition", (leftPosition + aWidth + 0.01F).ToString())
.Replace("@ValuePosition", (leftPosition + aWidth + 0.32F).ToString())
.Replace("@ValueWidth", bWidth.ToString());
if (dataRow[1].ToString().Trim() != "")
{
labelPattern = labelPattern.Replace("@ValueText", dataRow[1].ToString());
}
else
{
labelPattern = labelPattern.Replace("<Value>@ValueText</Value>", "<Value />");
}
reportLabelPatterns.Add(labelPattern);
if (dataTable.Columns.Count > 2)
{
labelPattern = LabelPattern
.Replace("@TopPosition", topPosition.ToString())
.Replace("@TextboxName", reportLabelPatterns.Count.ToString())
.Replace("@FontString", fontString)
.Replace("@Color", color.Name.ToString())
.Replace("@NameText", dataRow[2].ToString())
.Replace("@NamePosition", (leftPosition + aWidth + bWidth + 0.33F).ToString())
.Replace("@NameWidth", cWidth.ToString())
.Replace("@SplitPosition", (leftPosition + aWidth + bWidth + cWidth + 0.34F).ToString())
.Replace("@ValuePosition", (leftPosition + aWidth + bWidth + cWidth + 0.65F).ToString())
.Replace("@ValueWidth", dWidth.ToString());
if (dataRow[3].ToString().Trim() != "")
{
labelPattern = labelPattern.Replace("@ValueText", dataRow[3].ToString());
}
else
{
labelPattern = labelPattern.Replace("<Value>@ValueText</Value>", "<Value />");
}
reportLabelPatterns.Add(labelPattern);
}
topPosition += 0.5F;
headerHeight += 0.5F;
if (Graphics.FromHwnd(IntPtr.Zero).MeasureString(dataRow[1].ToString(), new Font(fontString, 9)).Width * 1.12 > MillimetersToPixelsWidth(bWidth * 10) - 3)
{
headerHeight += 0.3F;
}
}
if (showLine)
{
string linePattern = " <Line Name=\"LineLabel\">" +
" <Top>" + (topPosition + 0.1F) + "cm</Top>" +
" <Left>" + leftMargin / 2 + "cm</Left>" +
" <Height>0.0cm</Height>" +
" <Width>" + (pageWidth - leftMargin) + "cm</Width>" +
" <ZIndex>3</ZIndex>" +
" <Style>" +
" <Border><Style>Solid</Style></Border>" +
" </Style>" +
" </Line>";
reportLabelPatterns.Add(linePattern);
}
headerHeight += 0.2F;
topMargin = topPosition + 0.2F;
}
}
标题部分比较简单,设置好样式就行。可以是添加多行标题,保存到_reportTitlePatterns中,同样要设置页眉高。
private List<string> _reportTitlePatterns = new List<string>();
public void AddTitle(string title, int fontSize, string fontWeight, Color color, TextAlign textAlign, float height)
{
if (!string.IsNullOrEmpty(title))
{
if (headerHeight == 0) headerHeight += TopMargin;
var titlePattern = TitlePattern
.Replace("@TextboxName", _reportTitlePatterns.Count.ToString())
.Replace("@Title", title)
.Replace("@FontString", fontString)
.Replace("@FontSize", fontSize.ToString())
.Replace("@FontWeight", fontWeight)
.Replace("@Color", color.Name.ToString())
.Replace("@TextAlign", textAlign.ToString())
.Replace("@TopPosition", topMargin.ToString())
.Replace("@LeftPosition", leftMargin.ToString())
.Replace("@TextboxName", _reportTitlePatterns.Count.ToString())
.Replace("@Height", height.ToString())
.Replace("@Width", (pageWidth - leftMargin * 3).ToString());
_reportTitlePatterns.Add(titlePattern);
topMargin += height + 0.01F;
headerHeight += height + 0.01F;
}
}
页脚可以是多行的,保存到_reportPageFooter中,需要设置页脚的高度。
private List<string> _reportPageFooter = new List<string>();
public void AddPageFooter(string footerText, int fontSize, string fontWeight, Color color, TextAlign textAlign, float height)
{
if (!string.IsNullOrEmpty(footerText))
{
if (footerHeight == 0) footerHeight = 0.02F;
string footerPattern = " <Textbox Name=\"Footer" + _reportPageFooter.Count.ToString() + "\">" +
" <CanGrow>true</CanGrow>" +
" <KeepTogether>true</KeepTogether>" +
" <Paragraphs>" +
" <Paragraph>" +
" <TextRuns>" +
" <TextRun>" +
" <Value>" + footerText + "</Value>" +
" <Style><FontFamily>" + fontString + "</FontFamily><FontSize>" + fontSize.ToString() + "pt</FontSize><FontWeight>" + fontWeight + "</FontWeight><Color>" + color.Name.ToString() + "</Color></Style>" +
" </TextRun>" +
" </TextRuns>" +
" <Style><TextAlign>" + textAlign.ToString() + "</TextAlign></Style>" +
" </Paragraph>" +
" </Paragraphs>" +
" <rd:DefaultName>Footer" + _reportPageFooter.Count.ToString() + "</rd:DefaultName>" +
" <Top>" + footerHeight.ToString() + "cm</Top>" +
" <Left>" + leftMargin.ToString() + "cm</Left>" +
" <Height>" + height.ToString() + "cm </Height>" +
" <Width>" + (pageWidth - leftMargin * 2).ToString() + "cm</Width>" +
" <ZIndex>1</ZIndex>" +
" <Style>" +
" <VerticalAlign>Middle</VerticalAlign>" +
" <Border><Style>None</Style></Border>" +
" <PaddingLeft>2pt</PaddingLeft>" +
" <PaddingRight>2pt</PaddingRight>" +
" <PaddingTop>2pt</PaddingTop>" +
" <PaddingBottom>2pt</PaddingBottom>" +
" </Style>" +
" </Textbox>";
_reportPageFooter.Add(footerPattern);
footerHeight += height + 0.01F;
}
}
边栏推荐
- 怎样选择一个好的SaaS知识库工具?
- 最新!2022版新员工基础安全知识教育培训PPT,企业拿去直接用
- Account opening requirements and exemptions for special futures such as crude oil
- 华为云全流程护航《流浪方舟》破竹首发,打造口碑爆款
- Experience far more than Hue, this is the favorite SQL tool for technicians
- 测试开发是什么,为什么现在这么吃香?
- Ark Standalone/Administrator Special Item Command Codes
- 基于ABP和Magicodes实现Excel导出操作
- 史上最全架构师知识图谱
- 一键生成 API 文档的妙招
猜你喜欢
The most complete architect knowledge map in history
程序员的专属浪漫——用3D Engine 5分钟实现烟花绽放效果
Volatile:JVM 我警告你,我的人你别乱动
JMeter笔记6 | JMeter录制(配置代理)
The senior told me that the MySQL of the big factory is connected through SSH
Smart Tool Management System
史上最全架构师知识图谱
Tan Zhongyi: Do you know who the "Queen of Open Source" is?
逻辑越权和水平垂直越权支付篡改,验证码绕过,接口
crm系统哪家好?好用的crm管理系统推荐
随机推荐
记一次 .NET 某工控自动化控制系统 卡死分析
Redis 定长队列的探索和实践
.NET Community Toolkit 8.0.0 版本发布
WPF效果第一百九十四篇之伸缩面板
怎样选择一个好的SaaS知识库工具?
低代码平台和专业开发人员——完美搭档?
测试开发是什么,为什么现在这么吃香?
The difference between approach and method
A carnival of art and technology, cloud XR supports Anaya 2022 Sandbox Immersive Art Season
Prometheus完整安装
【.NET 6】开发minimal api以及依赖注入的实现和代码演示
.NET 6学习笔记(4)——解决VS2022中Nullable警告
WinForm(四)一种实现登录的方式
华为云全流程护航《流浪方舟》破竹首发,打造口碑爆款
期货开户流程和手续费如何调整
SkiaSharp 之 WPF 自绘 粒子花园(案例版)
How to adjust futures account opening process and handling fee
approach和method的区别
从事软件测试一年,只会基础的功能测试,怎么进一步学习?
浅谈如何保证Mysql主从一致