.Net中复杂打印的灵活方法
来源:互联网 发布:白金数据 网盘 编辑:程序博客网 时间:2024/05/29 05:08
.Net中复杂打印的灵活方法
最近在用C#做一个关于水处理渗透系统设计的项目,其中需要打印复杂的分析报告(包括系统详细参数、概要图、各点水质分析、限制警告信息等)。很多内容都是根据具体的操作动态产生,所以在打印时就没有固定的模式和页面数量。而.Net的打印原理中,分页逻辑需要开发人员自己设计,对于这种比较复杂的情况,分页逻辑的实现就比较困难了。参考网上一些打印的方法,均不能灵活有较的解决问题,所以决定自己重新设计一种简单的打印模式。现将这一思路与大家共享,希望能给读者带来点启发。(注:本文不对.Net的基本打印原理进行,请初学者先了解基本原理再看本文思路)
1、首先参考Word的页面形式,将打印内容分为“页眉区-主体区-页脚区”。其中页眉区和页脚区为固定模式,打印比较简单,只需每页重复调用相应打印函数即可。“主体区”是打印的重点,也是复杂之所在。区域大小固定后,报告内容要根据需要分成若干分页打印。打印逻辑的设计就是为了解决这个分页问题。
2、在“主体区”中,又可参照Excel的形式,将内容看作是若干“行”的集合,而各“行”中又包含了若干“单元”。为了使这一形式能够表达各种复杂的报告形式,可以对“单元”赋于各种属性:Type“单元类型(文本/图片)”、Text“文本内容”、Width“单元宽度”、Font“文本字体”、TextAlign“文本对齐方式”、bPrintFrame“是否打印边框”等,可以根据需要完善属性。“行”属性:Height“行高”(为当前行中单元的最大高度)、CellSet“单元集”等。具体实现参考附录类。
(说明:每单元、每行均为独立的个体,没有相互制约性,其实现方式全由开发人员根据具体需要初使化。如一空白行,则可定义一默认行包含一个空文本的默认单元,不打印边框,设置行高就可;而对于数据表格,则可将对应的行高,单元宽度设置相同,边框打印,设置对齐方式即可;又如一小段文本,可以作为一个仅包含单个“单元”的“行”,行高为文本的总高度,或者根据需要划分为几行表示。)
举例原主体如下:
-------------------------------------------------------------------------------------------------------------------------------------
数据表
列1
列2
行1
XX
XX.00
行2
XX
XX.00
警告:XXXXX
-------------------------------------------------------------------------------------------------------------------------------------
转化为如下主体列表存储格式:
-------------------------------------------------------------------------------------------------------------------------------------
数据表
列1
列2
行1
XX
XX.00
行2
XX
XX.00
警告:XXXXX
-------------------------------------------------------------------------------------------------------------------------------------
3、打印内容的列表初使(注意:这只是对将要打印内容的列表化初使,不是正在的打印过程,在打印中将调用此列表数据)。这是打印编程过程中的主要劳动量所在,根据具体的打印内容,进行相应的初使操作。应用“主体列表”打印的思想,在此处初使时,仅需要考虑单个“行”对象的内容,完全不用考虑打印逻辑中的“分页”问题。就像是在一个足够长的页面中进行打印,直接简化了打印逻辑的复杂部份,使编程过程思想明确。
4、打印逻辑实现。用如下的代码简单说明:
/// <summary>
/// 打印报告的主体部份函数,返回false表示打印结束,返回true表示下一页
/// </summary>
/// <param name="g">打印对象</param>
/// <param name="rect">区域大小</param>
private bool printBody(ref Graphics g, Rectangle rect)
{
int posY = rect.Top;
int posX = rect.Left;
while( this.nCurrentLine < this.Lines.Count ) // 当列表未打印完继续
{
if( posY + this.Lines[this.nCurrentLine].Height > rect.Bottom)
// 若当前行将超出正文打印范围,则别起一页
return true;
for(int i=0; i<this.Lines[this.nCurrentLine].CellSet.Count; i++)
{
……// 打印当前行过程,略
posX += this.Lines[this.nCurrentLine].CellSet[i].Width; // X坐标移至下一单元框
}
posX = rect.Left; // X坐标初使
posY += this.Lines [this.nCurrentLine].Height; // Y坐标移至下一行
this.nCurrentLine++; // 当前打印行号++
}
return false;
}
/// <summary>
/// 打印文档
/// </summary>
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
Graphics g = e.Graphics;
this.printHeader(ref g, headerRectangle); // 打印页眉
bool bMorePage = this.printBody(ref g, bodyRectangle); // 打印正文
this.printFooter(ref g, footerRectangle); // 打印页脚
if( bMorePage == true) // 需分页
this.nCurrentPage++;
else // 打印结束
{
this.nCurrentPage = 1;
this.nCurrentLine = 0;
}
e.HasMorePages = bMorePage;
}
对象类设计代码:
/// <summary>
/// 打印中单元格类
/// </summary>
public class CPrintCell:ICloneable
{
private bool mvarbIsPicture; // 是否是图片单元格
private bool mvarbPrintFrame; // 是否打印文本框
private int mvarWidth; // 单元框宽度
private string mvarAlign; // 对集方式(LEFT|RIGHT|CENTER)
private Font mvarFontOfCell; // 单元文本字体
private string mvarText; // 单元文本内容
private string mvarPicAddress; // 或是图片,则存图片地址
//赋值及函数部分略
}
/// <summary>
/// 打印中的行内单元格集合类
/// </summary>
public class CPrintCellSet:CollectionBase,ICloneable
{
public CPrintCellSet()
{
}
public CPrintCell this[int index]
{
get
{
return (CPrintCell)List[index];
}
set
{
List[index] = value;
}
}
public void Add(CPrintCell printcell)
{
this.List.Add(printcell);
}
public int IndexOf(CPrintCell printcell)
{
return this.List.IndexOf(printcell);
}
public void Remove(CPrintCell printcell)
{
if( this.IndexOf(printcell) != -1 )
this.List.Remove(printcell);
}
}
/// <summary>
/// 打印中的单元行类
/// </summary>
public class CPrintLine:ICloneable
{
private int mvarHeight; // 行高度
private CPrintCellSet mvarCellSet = new CPrintCellSet(); // 行内单元集
//赋值及函数部分略
}
/// <summary>
/// 打印中的行集合类
/// </summary>
public class CPrintLineSet:CollectionBase
{
public CPrintLineSet()
{
}
public CPrintLine this[int index]
{
get
{
return (CPrintLine)List[index];
}
set
{
List[index] = value;
}
}
public void Add(CPrintLine printline)
{
this.List.Add(printline);
}
public int IndexOf(CPrintLine printline)
{
return this.List.IndexOf(printline);
}
public void Remove(CPrintLine printline)
{
if( this.IndexOf(printline) != -1 )
this.List.Remove(printline);
}
}
本文仅为了提供一种适用于复杂打印的新思路,文中举例的对象类设计还不够完善,可以根据具体需要进行补充。希望能给大家带来点打印编程方面的帮助。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wen8465/archive/2008/10/31/3193244.aspx
- .Net中复杂打印的灵活方法
- .Net中复杂打印的灵活方法
- .Net中复杂打印的灵活方法
- .Net中复杂打印的灵活方法
- ASP.NET中表格的灵活使用
- js灵活打印web页面区域内容的通用方法
- 解析大型.NET ERP系统 灵活复杂的界面控件Infragistics WinForms
- 一个灵活的打印控制
- Hibernate 资源文件中定义复杂的自定义sql,可灵活用于自定义的复杂增删改查
- 在C#中建立复杂的、灵活的SQL查询/命令
- 在C#中建立复杂的、灵活的SQL查询/命令
- 在C#中建立复杂的、灵活的SQL查询/命令
- 弄清.NET中复杂的文件类型
- 弄清.NET中复杂的文件类型()
- 一种灵活的远程设备打印解决方案
- 最灵活的WEB打印-自定义报表
- 乘法口诀表的灵活打印
- 编写灵活的.net代码
- SERU过程框架总结
- linux 软件的安装和卸载 RPM 命令参数(转)
- MySQL客户端显示汉字乱码的解决
- .Net中复杂打印的灵活方法
- .Net中复杂打印的灵活方法
- .Net中复杂打印的灵活方法
- .Net中复杂打印的灵活方法
- struts2 jquery 插件实现ajax异步请求(网上资料)
- directshow filter中添加属性页
- vc++对类内const static int变量初始化后的处理
- guides.rubyonrails.org 读书笔记(四)
- 如果表格内容为""空时表格样式就不显示
- 如何创建QuickAction在Android对话 类似于苹果的效果
- request.getParameter(),request.getAttribute(),request.setAttribute();