利用GDI+函数构造图形报表

一、文章引言:近段时间,由于工作的需要,需要以报表和图形的形式对数据进行统计分析,由于手头没有相关的开发组件,于是自己利用GDI+函数进行地层的图形绘制,配合中间层的数据统计及组合,表层嵌入HTML文件中,形成了一整套生成饼状图、柱状图和折线图的应用,现在把设计思路及部分源代码提供出来,和大家相互交流。
二、设计思路:
        用户请求 ——》数据采集 ——》逻辑组织——》调用自定义底层函数——》调用.net GDI+图形函数——》生成JPG文件——》返回指向JPG图形的HTML文件 ——》完成
二、部分代码:

  1. 自定义底层图形函数

/// <summary>
/// JpgProxy 的摘要说明。
/// </summary>
public class JpgProxy
{
  #region 饼状图 
  /// <summary>
  /// 绘制饼状图
  /// </summary>
  /// <param name="height">画布高度</param>
  /// <param name="width">画布宽度</param>
  /// <param name="title">图形标题</param>
  /// <param name="partName">图形组成元素名称</param>
  /// <param name="partPoint">图形组成元素坐标</param>
  /// <param name="partCount">图形组成元素总数</param>
  /// <param name="partColor">图形组成元素颜色</param>
  /// <param name="imgName">输出图形文件名称</param>
  /// <param name="unit">统计单位</param>
  /// <param name="bgColor">图形背景颜色</param>
  /// <param name="strErr">功能调用返回信息</param>
  /// <param name="debug">功能调用测试</param>
  /// <returns>功能调用是否成功</returns>
  public static bool DrawPie(int height,int width,string title,string[] partName,float[,] partPoint,int[]partCount,Color[] partColor,string imgName,string unit,Color bgColor,out string strErr,bool debug)
  {
   #region 分离参数
   //参数检测
   if( partPoint.GetLength(0) != partColor.Length)
   {
    strErr = "坐标参数与颜色参数不对称,拒绝功能调用"; 
    return false;
   }
   else if(partPoint.GetLength(0) != 2)
   {
    strErr = "坐标参数数组定义与约定不符,拒绝功能调用";
   }
   else if(partPoint.GetLength(0) != partName.Length)
   {
    strErr = "坐标参数与组成名称参数不对称,拒绝功能调用"; 
    return false;
   }
   string outPutName = imgName.Split('\\')[imgName.Split('\\').Length - 1].Split('.')[0].ToString();
   string outPutParth = "";
   for( int i = 0 ; i < imgName.Split('\\').Length - 1; i ++)
   {
    outPutParth = outPutParth + imgName.Split('\\')[i].ToString() + "\\";
   }
   #endregion
   #region 基本图形
   //功能调用  
   Bitmap bmp = new Bitmap(width,height);
   Graphics g = Graphics.FromImage(bmp);
   Pen pen = new Pen(Color.Black);

   Rectangle outline = new Rectangle(0,0,height - 5,width -5);
   g.SmoothingMode = SmoothingMode.AntiAlias;
   g.Clear(bgColor);
   g.DrawEllipse(pen,outline);
   //输出图形区域
   for(int i = 0 ; i < partName.Length; i ++)
   {
    g.FillPie(new SolidBrush(partColor[i]),outline,partPoint[i,0],partPoint[i,1]);   
   }
   //输出到图片
   bmp.Save(imgName,ImageFormat.Jpeg);
   #endregion
   #region 图形标题
   if(debug)
   {
    bmp = new Bitmap(200 , 30);
    g = Graphics.FromImage(bmp); 
    g.Clear(bgColor);  
    g.DrawString(title,new Font("Arail",14,FontStyle.Regular),SystemBrushes.WindowText,new PointF(0,0));   
    bmp.Save(outPutParth + outPutName + "_" + "Title" + ".jpg",ImageFormat.Jpeg);
   }
   #endregion
   #region 描述图形
   //输出颜色方块
   for(int i = 0; i < partName.Length ; i++)
   {
    bmp = new Bitmap(15 , 15);
    g = Graphics.FromImage(bmp);
    pen = new Pen(Color.Black);
    g.Clear(bgColor);  
    outline = new Rectangle(0,0,10,10);
    g.DrawRectangle(pen,outline);   
    g.FillRectangle(new SolidBrush(partColor[i]),0,0,10,10);
    bmp.Save(outPutParth + outPutName + "_" + "DesColor" + "_" + i.ToString() +".jpg",ImageFormat.Jpeg);
   }  
   #endregion
   #region 描述文字
   if(debug)
   {
    for(int i = 0; i < partName.Length ; i++)
    {
     bmp = new Bitmap(120 , 15);
     g = Graphics.FromImage(bmp); 
     g.Clear(bgColor);  
     g.DrawString(partName[i].ToString() + ": " + Convert.ToString( partCount[i])  + " " +  unit,new Font("Arail",9,FontStyle.Regular),SystemBrushes.WindowText,new PointF(0,0));   
     bmp.Save(outPutParth + outPutName + "_" + "DesText" + "_" + i.ToString() +".jpg",ImageFormat.Jpeg);
    }
   }
   #endregion
   #region 释放资源
   g.Dispose();
   bmp.Dispose();
   strErr = imgName + "绘制成功";
   return true;
   #endregion
  }
  #endregion

2.   中间逻辑组织函数

   #region 构建饼状图
  /// <summary>
  /// 构建饼状图
  /// </summary>
  /// <param name="pie">图形参数</param>
  /// <param name="JpgName">图形名称</param>
  /// <returns>目标文件地址</returns>
  private static string CreatePie(JPGPie pie,string JpgName)
  {

   //计算总和
   int Count = 0;
   for(int i = 0 ; i < pie.ElementValue.Length; i ++)
   {
    Count = Count + pie.ElementValue[i];
   }
   string strContent = "";
   if(Count != 0)
   {
   
    #region 组织图形参数
    //图形组成元素坐标
    float[,]partPoint = new float[pie.ElementCount,2];
    for(int i = 0 ; i < partPoint.GetLength(0); i ++)
    {
     for(int j = 0 ; j < partPoint.GetLength(1); j ++)
     {
      if( i == 0 && j == 0) //第一个扇形的第一条边
      {
       partPoint[i,j] = 0.0F;
      }
      else if( j == 0) //中间扇形的第一条边
      {
       partPoint[i,j] = partPoint[i-1,0] + partPoint[i -1,1];
      }
      else if( j == 1 && i == partPoint.GetLength(0) - 1)//最后一个扇型
      {
       partPoint[i,j] = Convert.ToSingle( pie.ElementValue[i]  * 360 / Count + 2 );
      }
      else if( j == 1)//中间扇形的第二条边
      {
       partPoint[i,j] = Convert.ToSingle( pie.ElementValue[i]  * 360 / Count );
      }
     }
    }
    #endregion
    string strErr = "";
    string strImgName =  JPGReportManage.JpgPath("Pie\\"+ JpgName +".jpg");
    #region 调用图形函数
    JpgProxy.DrawPie(pie.BgHeight,pie.BgWidth,pie.BgTitle,pie.ElementName,partPoint,pie.ElementValue,pie.ElementColor,strImgName,pie.Unit,pie.BgColor,out strErr,false);
    #endregion
    #region 组织HTML代码
    #region 格式控制
    //换算值长度
    int vir_max_lenth = 0;    
    //实际数值长度
    int val_max_lenth = 0;
    //最大元素下标
    int flag = 0;
    #region 求出最大元素下标
    int k = 0;   
    int max_Value = pie.ElementValue[0];
    for(int i = 0 ; i < pie.ElementValue.Length; i ++)
    {
     if(k < pie.ElementValue.Length -1)
     {
      k = i + 1;
     }
     else
     {
      break;
     }
     if( max_Value < pie.ElementValue[k] )
     {
      max_Value = pie.ElementValue[k];
      flag = k; 
     }
    }
    #endregion
    //长度标准
    vir_max_lenth = Convert.ToString(pie.ElementValue[flag] * 100 / Count).Length;
    val_max_lenth = pie.ElementValue[flag].ToString().Length;
    #endregion
    string strDynamic = "";
    for(int i = 0 ; i < pie.ElementCount; i ++)
    {
     strDynamic = strDynamic +
      "<tr>"  +
      "<td>"  +
      "<img src = '../jpg/pie/"+ JpgName +"_DesColor_"+ i.ToString() +".jpg'>"  +
      "</td>" +
      "<td>"  +
      "<font size = 2 >" +
      pie.ElementName[i].ToString() + " : " + Convert.ToString(pie.ElementValue[i] * 100 / Count) + JPGReportManage.HTMLSpaceGenerator(vir_max_lenth - Convert.ToString(pie.ElementValue[i] * 100 / Count).Length) + pie.Unit + "[" + pie.ElementValue[i].ToString() + JPGReportManage.HTMLSpaceGenerator(val_max_lenth - pie.ElementValue[i].ToString().Length) +"]" +  
      "</font>" +
      "</td>" +
      "</tr>" ;
    }
    strContent = "<HTML><Head></Head><Body>" +
     "<table align = 'center' width = '100%' height = '100%'>" +
     "<tr>" +
     "<td>" +
     "<table align = 'center'>" +
     "<tr>" +
     "<td>" +
     "<img src = '../jpg/pie/"+ JpgName +".jpg'>" +
     "<td>" +
     "<td>" +
     "<table align = 'center'>" +
     strDynamic +
     "</table>" +
     "<td>" +
     "</tr>" +
     "</table>" +
     "</td>" +      
     "<tr>" +
     "</table>" +
     "</Body></HTML>";
    #endregion
   }
   else
   {
    #region 组织HTML代码
    strContent = "<HTML><Head></Head><Body>" +
     "<table align = 'center' width = '100%' height = '100%'>" +
     "<tr>" +
     "<td>" +
     "<table align = 'center'>" +
     "<tr>" +
     "<td>" +
     "没有数据可以显示" +
     "</td>" +
     "</tr>" +
     "</table>" +
     "</td>" +      
     "<tr>" +
     "</table>" +
     "</Body></HTML>";
    #endregion
   }
   #region 生成HTML文件
   JPGReportManage.CreateHtmFile(JPGReportManage.HtmlPath(JpgName + ".htm"),strContent);
   #endregion
   return "../Html/"+ JpgName +".htm";
  }
  #endregion

3.   特定应用调用

  #region 各区办件数量同比柱状图
  /// <summary>
  /// 各区办件数量同比柱状图
  /// </summary>
  /// <param name="param"></param>
  /// <returns></returns>
  private static string Create_Cit_Case_Amount_Pos_Column(PosContrastParam param)
  {
   #region 逻辑处理
   #region 参数处理
   LiLongDataReport.JPGColumn column = new JPGColumn();
   //图片颜色
   column.BgColor = System.Drawing.Color.White;
   //图片高度
   column.BgHeight = 860;
   //图片标题
   column.BgTitle = "";
   //图片宽度
   column.BgWidth = 860;
   //柱状颜色
   System.Drawing.Color[]color = {System.Drawing.Color.Blue};
   column.ElementColor = color;
   //柱状总数
   column.ElementCount = 1;
   //柱状描述
   string[]name = new string[PosNameDataBag.NameList.Length];
   for(int i = 0 ; i < name.Length ; i ++)
   {
    name[i] = PosNameDataBag.NameList[i].Substring(0,2);
   }
   column.ElementName = name;
   //统计单位
   column.XUnit = "区";
   //统计单位
   column.YUnit = "件";
   //柱状高度
   int[]position = new int[PosNameDataBag.NameList.Length];  
   string Begin = "";
   string End = "";
   for(int i = 0 ; i < param.StartDate.Split('-').Length; i ++)
   {
    Begin = Begin + param.StartDate.Split('-')[i];
   }
   for(int i = 0 ; i < param.EndDate.Split('-').Length; i ++)
   {
    End = End + param.EndDate.Split('-')[i];
   }
   #endregion
   #region 提交查询
   string strErr = "";
   string Result = "";
   string strSql = "";
   for(int i = 0; i < position.Length ; i ++)
   { 
    XMLProxy.SetNodeValue(System.Web.HttpContext.Current.Server.MapPath("..") + "\\" + "state.xml","综合查询","正在处理"+ PosNameDataBag.NameList[i] +"区数据 任务数["+ PosNameDataBag.NameList.Length.ToString() +"] 已处理["+ i.ToString() +"] 未处理["+ Convert.ToString(PosNameDataBag.NameList.Length - i) +"]");
    strSql = "SELECT count(*) as col from 办件表 where  Cast(受理日期 as datetime) >= '"+ Begin + "' and Cast(受理日期 as datetime) <= '"+ End + "'";
    DataBaseProxy.ExceuteSql(ConfigManage.ConnectionStringProxy(PosNameDataBag.NameList[i]),strSql,out Result,out strErr);
    position[i] = int.Parse(Result);  
   }
   #endregion
   #region 绑定到参数
   column.ElementValue = position;
   #endregion
   #endregion
   #region 内核调用
   string strReturn = null;
   strReturn = JPGReportManage.CreateColumn(column,"Cit_Case_Amount_Pos_Column");
   #endregion
   return strReturn;
  }
  #endregion

4. 表层调用函数

#region 构造区级统计类图形
  /// <summary>
  /// 构造区级统计类图形
  /// </summary>
  /// <param name="jpgType">图形类型</param>
  /// <param name="param">统计参数</param>
  /// <returns>目标文件地址</returns>
  public static string BuildPosAmountJPG(EJpgReportType jpgType,PosAmountParam param)
  { 
   string strReturn = null;
   switch(jpgType)
   {  
    
    case EJpgReportType.Pos_Case_Amount_Type_Pie:
    {
     strReturn = JPGReportManage.Create_Pos_Case_Amount_Type_Pie(param);
     break;
    }
    case EJpgReportType.Pos_Case_Amount_Year_Curve:
    {
     strReturn = JPGReportManage.Create_Pos_Case_Amount_Year_Curve(param);
     break;
    }
    default:
    {
     strReturn = "";
     break;
    }
   }
   return strReturn;
  }
  #endregion

5. 相关参数列举

/// <summary>
/// 图形报表类型
/// </summary>
public enum EJpgReportType
{
  /// <summary>
  /// 区级年度办件数量走势折线图
  /// </summary>
  Pos_Case_Amount_Year_Curve = 0,
  /// <summary>
  /// 区级办件数量中各办件类型所占比例饼状图
  /// </summary>
  Pos_Case_Amount_Type_Pie =1,
  /// <summary>
  /// 各区办件数量同比柱状图
  /// </summary>
  Cit_Case_Amount_Pos_Column = 2,
  /// <summary>
  /// 各区办件数量排名饼状图
  /// </summary>
  Cit_Case_Amount_Pos_Pie = 3,
  /// <summary>
  /// 市级年度办件数量走势折线图
  /// </summary>
  Cit_Case_Amount_Year_Curve = 4,
  /// <summary>
  /// 各区所有办件中各办件类型所占比例饼状图
  /// </summary>
  Cit_Case_Type_Pie = 5,
  /// <summary>
  /// 委办局年度办件数量走势折线图
  /// </summary>
  Adm_Case_Amount_Year_Curve = 6,
  /// <summary>
  /// 委办局办件数量同比柱状图
  /// </summary>
  Adm_Case_Amount_Adm_Column = 7,
  /// <summary>
  /// 委办局各分局办件数量同比柱状图
  /// </summary>
  Adm_Case_Amount_Sub_Column = 8, 
  /// <summary>
  /// 区级年度办件办结效率评估分析饼状图
  /// </summary>
  Pos_Case_End_Efficiency_Year_Pie = 9
}


#region 饼状图数据结构
/// <summary>
/// 饼状图数据结构
/// </summary>
public class JPGPie
{
  //饼状组成元素个数
  private int elementCount;
  //饼状组成元素名称
  private string[]elementName;
  //饼状组成元素颜色
  private Color[]elementColor;
  //饼状组成元素大小
  private int[]elementValue;
  //饼装图形背景颜色
  private Color bgColor;
  //饼状图形高度
  private int bgHeight;
  //饼状图形宽度
  private int bgWidth;
  //饼状图形标题
  private string bgTitle;
  //饼状图统计单位
  private string unit;
  /// <summary>
  /// 饼状图统计单位
  /// </summary>
  public string Unit
  {
   get
   {
    return unit;
   }
   set
   {
    unit = value;
   }
  }
  /// <summary>
  /// 饼状组成元素个数
  /// </summary>
  public int ElementCount
  {
   get
   {
    return elementCount;
   }
   set
   {
    elementCount = value;
   }
  }
 
  /// <summary>
  /// 饼状组成元素名称
  /// </summary>
  public string[]ElementName
  {
   get
   {
    return elementName;
   }
   set
   {
    elementName = value;
   }
  }
  /// <summary>
  /// 饼状组成元素颜色
  /// </summary>
  public Color[]ElementColor
  {
   get
   {
    return elementColor;
   }
   set
   {
    elementColor = value;
   }
  }
  /// <summary>
  /// 饼状组成元素大小
  /// </summary>
  public int[]ElementValue
  {
   get
   {
    return elementValue;
   }
   set
   {
    elementValue = value;
   }
  }
  /// <summary>
  /// 饼装图形背景颜色
  /// </summary>
  public Color BgColor
  {
   set
   {
    bgColor = value;
   }
   get
   {
    return bgColor;
   }
  }
  /// <summary>
  /// 饼状图形高度
  /// </summary>
  public int BgHeight
  {
   get
   {
    return  bgHeight;
   }
   set
   {
    bgHeight = value;
   }
  }

  /// <summary>
  /// 饼状图形宽度
  /// </summary>
  public int BgWidth
  {
   get
   {
    return bgWidth;
   }
   set
   {
    bgWidth = value;
   }
  }
  /// <summary>
  /// 饼状图形标题
  /// </summary>
  public string BgTitle
  {
   get
   {
    return bgTitle;
   }
   set
   {
    bgTitle = value;
   }
  }
}
#endregion

      希望能够有更多的知识与大家分享,共同进步!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值