工作中要用到打印
今天赶紧到BLOG上搜索
拜读了snaill的 “怎样用C#实现完整文档打印功能”,kingerq的“网页打印问题,打印设置,打印预览,打印分页,纵打,横打及页面的边距”等人的文章
下面写点心得体会
一:about win print
打印操作通常包括以下四个功能
1 打印设置 设置打印机的一些参数比如更改打印机驱动程序等
2 页面设置 设置页面大小纸张类型等
3 打印预览 类似于word中的打印预览
4 打印
打印有关的事件和方法
这个类包括以下几个属性 事件 和方法
1、PrinterSettings 属性
存放打印机的设置信息这个属性不需要程序员设置因为它是由打印对话框获取的
2、PrintCountroller 属性
控制打印过程
3、DefaultPageSettings 属性
存放页面设置信息 打印纸大小方向等也不需要程序员设置因为它是由页面设置对话框获取的
4、DocumentName 属性
指定文档名称,出现在打印机状态窗口中
1。 BeginPrint事件
在打印之前发出
2. PrintPage事件
每打印一页是发出,事件接受一个PrintPageEventArgs参数该参数封装了打印相关的信息
PrintPageEventArgs参数有很多重要的属性
1 Cancel 取消打印
2 Graphics 页面的绘图对象
3 HasMorePages 是否还有要打印的页面
若实现打印功能首先构造PrintDocument对象添加打印事件
可以写事件:
PrintDocument printDocument;
private void InitializeComponent()
{
...
printDocument=new PrintDocument();
printDocument.PrintPage += new PrintPageEventHandler (this.printDocument_PrintPage);
...
}
更方便的方法是在工具中拖出
先在窗体中拖出printDocument控件,然后在事件的pirntPage中编辑事件的名字 ,双击就生成事件
这个事件包括需要打印的内容以及相关设置(重要)
以下贴点实践的code
//实现打印事件功能
//打印和绘图类似都是调用Graphics 类的方法进行画图 不同的是一个在显示器上一个在打印纸上并且打印要进行一些复杂的计算
//如换行 分页等。
StringReader lineReader;
private void document_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
Graphics g = e.Graphics; //获得绘图对象
float linesPerPage = 0; //页面的行号
float yPosition = 0; //绘制字符串的纵向位置
int count = 65; //行计数器
float leftMargin = e.MarginBounds.Left; //左边距
float topMargin = e.MarginBounds.Top; //上边距
string line = null; //行字符串
Font printFont = this.textBox.Font; //当前的打印字体
SolidBrush myBrush = new SolidBrush(Color.Black);//刷子
linesPerPage = e.MarginBounds.Height / printFont.GetHeight(g);//每页可打印的行数
//StringReader lineReader = new StringReader(richTextBox1.Text); //这里死循环
//逐行的循环打印一页
while(count < linesPerPage && ((line = lineReader.ReadLine()) != null))
{
yPosition = topMargin + (count * printFont.GetHeight(g));
g.DrawString(line, printFont, myBrush, leftMargin, yPosition, new StringFormat());
count++;
}
//如果本页打印完成而line不为空说明还有没完成的页面这将触发下一次的打印事件在下一次的打印中lineReader会
//自动读取上次没有打印完的内容因为lineReader是这个打印方法外的类的成员它可以记录当前读取的位置
if(line != null)
e.HasMorePages = true;
else
e.HasMorePages = false;
}
//打印设置,构造打印对话框 将对话框中设置的Document属性赋给printDocument这样会将用户的设置自动保存到printDocument
//的PrinterSettings属性中
private void printSetToolStripMenuItem_Click(object sender, EventArgs e)
{
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDocument1;
printDialog.ShowDialog();
}
//页面设置和打印预览与打印设置原理相同都是构造对话框将用户在对话框中的设置保存到相应的类的属性中
private void pageSetToolStripMenuItem_Click(object sender, EventArgs e)
{
PageSetupDialog pageSetupDialog = new PageSetupDialog();
pageSetupDialog.Document = printDocument1;
pageSetupDialog.ShowDialog();
}
//打印预览
private void previewToolStripMenuItem1_Click(object sender, EventArgs e)
{
lineReader = new StringReader(richTextBox1.Text);
printPreviewDialog1.Document = printDocument1;
try
{
printPreviewDialog1.ShowDialog();
}
catch (Exception excep)
{
MessageBox.Show(excep.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
//打印就可以直接调用printDocument的Print()方法因为用户可能在打印之前还要再更改打印设置所以
//在这里再次显示打印设置对话框
private void printToolStripMenuItem_Click(object sender, EventArgs e)
{
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDocument;
lineReader = new StringReader(textBox.Text);
if (printDialog.ShowDialog() == DialogResult.OK)
{
try
{
printDocument.Print();
}
catch (Exception excep)
{
MessageBox.Show(excep.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
printDocument.PrintController.OnEndPrint(printDocument, new PrintEventArgs());
}
}
}
(注) 很多地方可以直接从工具中拖出控件,比如printDocument,PrintDialog ,printPreviewDialog等
二:about web print
function DP() {
if (window.print)
{
var Div1 = document.all.Div1.innerHTML;
// *****************************************************
// Div1、Div2即为你在打印的区域
// 这里根据你要打印的哪些内容,从原显示页面中用
// <div id=Div1>Div1....</div><div id=Div2>Div2...</div>
// 等标示出来,要打印多少项目就标示多少
// *****************************************************
var css = '<style type="text/css" media=all>' +
'p { line-height: 120%}' +
'.ftitle { line-height: 120%; font-size: 18px; color: #000000}' +
'td { font-size: 10px; color: #000000}' +
'@media print {.noprint {display:none}}' +
'</style>' ;
// *****************************************************
// 定义打印用的CSS,具体你想打印出什么样的格式全看你自己
// 了,但要注意:如果此处有什么同网页中不一致的,可能打印
// 出来的页面同网页格式、字体可能会有所不同
// *****************************************************
var body ='<table width="700" height = "500" border="0" cellspacing="0" cellpadding="5">' +
' <tr> ' +
' <td class="fbody"> ' +
' <div align="center" class=ftitle>' + Div1 + '</div>' +
' </td>' +
' </tr>' +
'</table>';
// ******************************************************
// 在此处重新设置的打印格式,根据你的打印要求,将原显示的
// 网页的DIV内容重新组合,可以根据你原来的表格内容,去掉
// 不要打印的,你也可以能下面定义的noprint忽略掉你不想打
// 印的东西,只调用你要打印的内容,但这样被忽略掉的地方将
// 打印出空,不是很美观。表格宽度要同打印的纸张宽度匹配。
// ******************************************************
document.body.innerHTML = '<center>' + css + body + '</center>'; ;
// ******************************************************
// 重设document.body,打印文档准备就绪
// ******************************************************
// 打印页面预览
wb.execwb(7,1);
//window.print();
window.history.back();
// ******************************************************
// 调用打印命令,打印当前窗口内容。当你打印时其实是一张新
// 的网页了,但网页文件还是原先的。紧接着调用
// window.history.go(0),再回到打印前的页面,效果相当不差
// ******************************************************
}
}
</script>
通用打印类库DLL
接口:
/// <summary>
/// PrintDocument.PrintPage的委托定义
/// </summary>
public delegate void PrintPageDelegate(Object obj, System.Drawing.Printing.PrintPageEventArgs ev);
interface IPrinterPageSetting
{
/// <summary>
/// 获取或设置打印文档
/// </summary>
System.Drawing.Printing.PrintDocument PrintDocument
{
get;
set;
}
/// <summary>
/// 关联一个方法,目的是让具体的打印由实例化者来操作
/// 如PrinterPageSetting1.PrintPage += new PrintPageDelegate(this.PrintPageEventHandler);
/// </summary>
PrintPageDelegate PrintPageValue
{
get;
set;
}
event PrintPageDelegate PrintPage;
/// <summary>
/// 显示页面设置对话框,并返回PageSettings
/// </summary>
/// <returns></returns>
System.Drawing.Printing.PageSettings ShowPageSetupDialog();
/// <summary>
/// 显示打印机设置对话框,并返回PrinterSettings
/// </summary>
/// <returns></returns>
System.Drawing.Printing.PrinterSettings ShowPrintSetupDialog();
/// <summary>
/// 显示打印预览对话框
/// </summary>
void ShowPrintPreviewDialog();
}
WIN打印
/// <summary>
/// WinForm下的打印纸张设置、打印机设置、打印预览对话框。
/// </summary>
public class WinPrinterPageSetting : IPrinterPageSetting
{
//把PrintPage委托声明为类的一个成员变量
private PrintPageDelegate _printPageValue;
// 打印文档
private PrintDocument _printDocument;
#region 构造函数
public WinPrinterPageSetting()
: this(null)
{
}
/// <summary>
/// 使用printDocument来初始化类的新实例,当printDocument为null时自动创建一个printDocument的实例
/// </summary>
/// <param name="printDocument"></param>
public WinPrinterPageSetting(PrintDocument printDocument)
{
if (printDocument != null)
{
_printDocument = printDocument;
}
else
{
_printDocument = new PrintDocument();
}
}
#endregion
#region IPrinterPageSetting 成员
/// <summary>
/// 获取或设置打印文档
/// </summary>
public PrintDocument PrintDocument
{
get
{
return this._printDocument;
}
set
{
this._printDocument = value;
}
}
/// <summary>
/// 一定要实例化此类后在调用打印/预览之前设置此属性,使之关联一个方法,目的是让具体的打印由实例化者来操作
/// 如PrinterPageSetting1.PrintPage += new PrintPageDelegate(this.PrintPageEventHandler);
/// </summary>
public PrintPageDelegate PrintPageValue
{
set
{
//初始委托变量,关联方法
_printPageValue = value;
//if (_printDocument == null)
//{
// throw new Exception("关联的打印文档不能为空!");
//}
_printDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this._printPageValue);
}
get
{
return _printPageValue;
}
}
public event printClassLib.PrintPageDelegate PrintPage
{
add
{
_printDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(value);
_printPageValue = value;
}
remove
{
_printDocument.PrintPage -= new System.Drawing.Printing.PrintPageEventHandler(value);
_printPageValue = null;
}
}
/// <summary>
/// 显示页面设置对话框,并返回PageSettings
/// </summary>
/// <returns></returns>
public PageSettings ShowPageSetupDialog()
{
return ShowPageSetupDialog(this._printDocument);
}
/// <summary>
/// 显示打印机设置对话框,并返回PrinterSettings
/// </summary>
/// <returns></returns>
public PrinterSettings ShowPrintSetupDialog()
{
return ShowPrintSetupDialog(this._printDocument);
}
/// <summary>
/// 显示打印预览对话框
/// </summary>
public void ShowPrintPreviewDialog()
{
ShowPrintPreviewDialog(this._printDocument);
}
#endregion
//***************注意:以下几个对话框方法可以独立使用***************
#region 页面设置对话框 protected virtual PageSettings ShowPageSetupDialog(PrintDocument printDocument)
/// <summary>
/// 页面设置对话框,可以独立使用
/// </summary>
/// <param name="printDocument"></param>
/// <returns></returns>
protected virtual PageSettings ShowPageSetupDialog(PrintDocument printDocument)
{
//声明返回值的PageSettings
PageSettings ps = new PageSettings();
if (printDocument == null)
{
throw new Exception("关联的打印文档不能为空!");
}
try
{
//申明并实例化PageSetupDialog
PageSetupDialog psDlg = new PageSetupDialog();
//相关文档及文档页面默认设置
psDlg.Document = printDocument;
psDlg.PageSettings = printDocument.DefaultPageSettings;
//显示对话框
DialogResult result = psDlg.ShowDialog();
if (result == DialogResult.OK)
{
ps = psDlg.PageSettings;
printDocument.DefaultPageSettings = psDlg.PageSettings;
}
}
catch (System.Drawing.Printing.InvalidPrinterException e)
{
MessageBox.Show("未安装打印机,请进入系统控制面版添加打印机!", "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
return ps;
}
#endregion
#region 打印设置对话框 protected virtual PrinterSettings ShowPrintSetupDialog(PrintDocument printDocument)
/// <summary>
/// 打印设置对话框,可以独立使用
/// </summary>
/// <param name="printDocument"></param>
/// <returns></returns>
protected virtual PrinterSettings ShowPrintSetupDialog(PrintDocument printDocument)
{
//声明返回值的PrinterSettings
PrinterSettings ps = new PrinterSettings();
if (printDocument == null)
{
throw new Exception("关联的打印文档不能为空!");
}
try
{
//申明并实例化PrintDialog
PrintDialog pDlg = new PrintDialog();
//可以选定页
pDlg.AllowSomePages = true;
//指定打印文档
pDlg.Document = printDocument;
//显示对话框
DialogResult result = pDlg.ShowDialog();
if (result == DialogResult.OK)
{
//保存打印设置
ps = pDlg.PrinterSettings;
//打印
printDocument.Print();
}
}
catch (System.Drawing.Printing.InvalidPrinterException e)
{
MessageBox.Show("未安装打印机,请进入系统控制面版添加打印机!", "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
return ps;
}
#endregion
#region 打印预览对话框 protected virtual void ShowPrintPreviewDialog(PrintDocument printDocument)
/// <summary>
/// 打印预览对话框,可以独立使用
/// </summary>
/// <param name="printDocument"></param>
/// <returns></returns>
/// <remarks>
protected virtual void ShowPrintPreviewDialog(PrintDocument printDocument)
{
if (printDocument == null)
{
throw new Exception("关联的打印文档不能为空!");
}
try
{
//申明并实例化PrintPreviewDialog
PrintPreviewDialog ppDlg = new PrintPreviewDialog();
//指定打印文档
ppDlg.Document = printDocument;
//显示对话框
DialogResult result = ppDlg.ShowDialog();
if (result == DialogResult.OK)
{
//...
}
}
catch (System.Drawing.Printing.InvalidPrinterException e)
{
MessageBox.Show("未安装打印机,请进入系统控制面版添加打印机!", "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
#endregion
}
WEB打印
/// <summary>
/// WebForm下的打印纸张设置、打印机设置、打印预览对话框。
/// </summary>
public class WebPrinterPageSetting : IPrinterPageSetting
{
public WebPrinterPageSetting()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
#region IPrinterPageSetting 成员
public System.Drawing.Printing.PrintDocument PrintDocument
{
get
{
// TODO: 添加 WebPrinterPageSetting.PrintDocument getter 实现
return null;
}
set
{
// TODO: 添加 WebPrinterPageSetting.PrintDocument setter 实现
}
}
public PrintPageDelegate PrintPageValue
{
get
{
// TODO: 添加 WebPrinterPageSetting.PrintPage getter 实现
return null;
}
set
{
// TODO: 添加 WebPrinterPageSetting.PrintPage setter 实现
}
}
public event printClassLib.PrintPageDelegate PrintPage;
public System.Drawing.Printing.PageSettings ShowPageSetupDialog()
{
// TODO: 添加 WebPrinterPageSetting.ShowPageSetupDialog 实现
return null;
}
public System.Drawing.Printing.PrinterSettings ShowPrintSetupDialog()
{
// TODO: 添加 WebPrinterPageSetting.ShowPrintSetupDialog 实现
return null;
}
public void ShowPrintPreviewDialog()
{
// TODO: 添加 WebPrinterPageSetting.ShowPrintPreviewDialog 实现
}
#endregion
}
//将WinPrinterPageSetting与WebPrinterPageSetting合二为一。
//在类的构造函数中增加自动判断Windows模式还是Web模式,同时也提供PrintMode属性可以让用户修改
/// <summary>
/// 打印方式
/// </summary>
public enum PrintModeFlag
{
/// <summary>
/// Windows窗口打印方式
/// </summary>
Win
,
/// <summary>
/// Web窗口打印方式
/// </summary>
Web
}
/// <summary>
/// 封装页面设置、打印机设置、打印预览,适合于Window和Asp.Net。
/// </summary>
public class PrinterPageSetting : IPrinterPageSetting
{
//申明一个封装页面设置、打印机设置、打印预览的接口
private IPrinterPageSetting _printerPageSetting;
//打印方式
private PrintModeFlag _printModeFlag;
public PrintModeFlag PrintMode
{
get
{
return this._printModeFlag;
}
set
{
this._printModeFlag = value;
//运用了抽象模式,创建接口对象的新实例,使其指象真正的实现其接口的对象
if (this._printModeFlag == PrintModeFlag.Win)
{
_printerPageSetting = new WinPrinterPageSetting();
}
else if (this._printModeFlag == PrintModeFlag.Web)
{
_printerPageSetting = new WebPrinterPageSetting();
}
}
}
/// <summary>
/// 获取或设置打印文档
/// </summary>
public PrintDocument PrintDocument
{
get
{
return _printerPageSetting.PrintDocument;
}
set
{
_printerPageSetting.PrintDocument = value;
}
}
/// <summary>
/// 一定要实例化此类后在调用打印/预览初始此变量,使之关联一个方法,目的是让具体的打印由实例化者来操作
/// 如PrinterPageSetting1.PrintPage += new PrintPageDelegate(this.PrintPageEventHandler);
/// </summary>
public PrintPageDelegate PrintPageValue
{
set
{
_printerPageSetting.PrintPageValue = value;
}
get
{
return _printerPageSetting.PrintPageValue;
}
}
public event PrintPageDelegate PrintPage
{
add
{
_printerPageSetting.PrintPage += new PrintPageDelegate(value);
}
remove
{
_printerPageSetting.PrintPage -= new PrintPageDelegate(value);
}
}
#region 构造函数
/// <summary>
/// 封装页面设置、打印机设置、打印预览,适合于Window和Asp.Net,Web方式下请在配置文件中增加键PrintMode及值Web,也可以实例化后设置PrintMode属性为PrintModeFlag.Web。
/// </summary>
public PrinterPageSetting()
: this(null)
{
}
/// <summary>
/// 封装页面设置、打印机设置、打印预览,适合于Window和Asp.Net,Web方式下请在配置文件中增加键PrintMode及值Web,也可以实例化后设置PrintMode属性为PrintModeFlag.Web。
/// </summary>
/// <param name="printDocument"></param>
public PrinterPageSetting(PrintDocument printDocument)
{
string strPrintMode = "";
//配置文件中键PrintMode
strPrintMode = System.Configuration.ConfigurationSettings.AppSettings["PrintMode"];
if (strPrintMode == null)
{
//默认为Win方式
strPrintMode = "Win";
}
//配置文件中键PrintMode的值Win/Web
if (strPrintMode.ToUpper() == "WIN")
{
this.PrintMode = PrintModeFlag.Win;
}
else
{
this.PrintMode = PrintModeFlag.Web;
}
/* //配置文件中添加键值的写法
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="PrintMode" value="Web"/>
</appSettings>
</configuration>
*/
if (printDocument != null)
{
_printerPageSetting.PrintDocument = printDocument;
}
}
#endregion
/// <summary>
/// 显示页面设置对话框,并返回PageSettings
/// </summary>
/// <returns></returns>
public PageSettings ShowPageSetupDialog()
{
return _printerPageSetting.ShowPageSetupDialog();
}
/// <summary>
/// 显示打印机设置对话框,并返回PrinterSettings
/// </summary>
/// <returns></returns>
public PrinterSettings ShowPrintSetupDialog()
{
return _printerPageSetting.ShowPrintSetupDialog();
}
/// <summary>
/// 显示打印预览对话框
/// </summary>
public void ShowPrintPreviewDialog()
{
_printerPageSetting.ShowPrintPreviewDialog();
}
}
三 : 通过LayoutControl实现单据打印
简单介绍LayoutControl:
XtraLayoutControl这个控件就是一个容器,这个容器允许程序员放入其他不同的控件,通过排列组成一个面板。
为什么我们需要这个容器?
没有这个容器,我们也可以很容易的设计一个窗体,在窗体中拖动控件。然而,当一个新控件需要添加或需要删除一个控件,或窗体的大小改变,或字体改变的时候,我们设计的样式很容易被破坏。因此,我们必须重新排列这些令人烦躁的控件。
这个时候,XtraLayoutControl为这个令人烦躁的工作提供了一个很好的解决方案,它提供了控件自动对齐的特征,从而确保控件之间不会重叠,从而维护了有效而稳固的样式结构。
最令人称道的是XtraLayoutControl提供了保存样式的功能,即使是终端用户也能够在运行时重新排列(如果需要的话)容器里面的控件以达到自己的需要,并且保存为以后用。
XtraLayoutContro这个容器自带打印和导出功能,可以直接预览,打印LayoutContro这个容器中的所有控件。值得注意的是,继承自BaseEdit的控件打印出来的是控件的值,不会打印控件的边框,而其他控件打印出来的是图片。
如何使用XtraLayoutControl
在这里我们用到了XtraLayoutControl的保存功能来设计单据。
为什么需要借助XtraLayoutControl的特征实现单据打印
(1)打印单据的需求
所见即所得的打印
单据变动的需要
(2)满足打印单据的需求
通过XtraLayoutControl设计模版,可以实现所见即所得的打印
通过保存样式的功能将模版样式保存成文件的形式,如果用户需要改变,则将改变后的样式文件发给用户,用户可以直接加载文件,而不用重新更新程序。
打印设计
采用LayoutControl 与 XtraGrid 相结合的模式实现打印。
通过LayoutControl设计总的模版样式,然后将XtraGrid嵌入到LayoutControl中
具体样式见下图1:
这样就需要保存LayoutControl 与 XtraGrid的样式文件(XML文件)
打印方面的优势: 可以灵活改变需要打印的单据的样式,用户可以通过选择需要的样式实现所见即所得的打印。
可以通过指定路径决定需要的样式,加载指定的路径后将路径保存到数据库,下次打开单据的时候直接加载数据库的样式路径
缺点:并不能保证完全的灵活性。
(1) Layout方面
由于LayoutControl读的是XML的树型样式结构,然后把读到的样式结构重新在模版结构的基础上重新绘制,绘制的基础是必须有足够的item,如果加载的样式比模版样式的总的items多,则多出的items不会显示
(2) Grid方面
在相同的grid模版下的样式可以灵活的变动,也就是说比模版grid的列或集合多也可以,但如果不是同一个grid模版,则样式会有不可预料的变化。
解决方案:
(1) Layout
模版样式可以加足够多的空的items,以免出现items不足
(2) Grid
每一个单据应该有自己的唯一的初始模版,只能在模版的基础上修改。基于不同模版的grid样式不能相互加载。
2 通过XtraGrid实现报表打印
XtraGrid介绍:
XtraGrid是一个数据采集控件,详细功能可以参考XtraGrid文档
为什么可以利用XtraGrid实现打印?
XtraGrid自带打印的功能和很多打印的样式,加上XtraGrid本身强大的采集和操作数据的能力以及集成XtraPrinting的打印功能,实现报表的打印并非不可能。并且可以实现所见即所得的报表打印。
XtraGrid另一个令人激动的功能与XtraLayoutControl非常相似,也就是保存样式的功能。
可见报表打印
通过PrintingSystem的link属性添加一个link:printableComponentLink1,然后关联GridControl,通过printableComponentLink1的事件CreateReportFooterArea和CreateReportHeaderArea画表头和表尾。
通过printableComponentLink1.CreateDocument();绘制
最后打印或预览printableComponentLink1.ShowPreview();
样式以XML文件的形式让用户下载后使用,避免为了简单改动报表而重新编译程序
注意: 对Grid的样式载入必须是基于同一个Grid
3 通过XtraReport实现收费单据打印
在PB里面是使用数据窗口组合而成,在.NET里面不好实现。
而不能用XtraLayoutControl打印收费单据的主要原因是XtraLayoutControl里面不能画表格,并且收费单据并不需要编辑的功能,所以也不需要用到XtraLayoutControl。
而不能用到XtraGrid的原因是在Grid里面不能象HTML那样自定义表格样式。
使用XtraReport打印收费单据
灵活的改变(layout)样式
可以通过载入指定的样式文件灵活更新样式,不同重新编译程序。
具体方法是在初始化报表数据前先指定载入样式:this.LoadLayout(fildName)
可以改变数据集,但如何改变数据绑定?也就是说数据源可以改变,但不能改变报表lable的绑定字段。
现在报表模版(没有数据源,只有样式的空报表)的数据都来自于
public void iniData(string strYLZH)这个方法,
新增一个未绑定数据的label之类的显示数据控件可以显示,这是因为报表文件已经保存了样式的结构。问题是如何指定控件绑定哪个字段的值?现在值是在XtraReport这个类中绑定的。
纯空的报表模版(也就是没有任何控件的报表)怎样能绑定数据字段?
通过实验发现这样的解决方案:
在设计报表的时候把可以预料到的字段都绑定到控件上,编译好。这样就相当于一个大的集合里面包含了需要的字段控件
用户使用报表前需要先加载一个样式,也就是用户需要显示哪些字段的样式。这也就相当于一个子集合,包含于我们最开始编译好的报表。
以后用户需要新增或删除字段或改变格局,我们就可以通过改变报表的样式,然后保存一个样式文件,将文件发给用户来实现。
总之,用户只需要加载自己需要的文件就能达到自己需要的报表,而不用重新编译程序。
动态生成药费单:
药费类型是通过查询动态生成的,一般不会超过12个。
所以在报表设计最开始先添加12个空的lbl控件,初始化报表的时候通过传递进的不同的数据集,将数据集的字段绑定到控件上
问题是:因为在最初需要将12个控件绑定到数据集的字段上,形如
xrlblFY0.Text = DS.Tables[0].Rows[0][0]),DS就是查询到的数据集
数据源的字段如果不是12个的话就不能匹配了
方案1 :用for循环实现动态绑定
方案2: 用Subreport(子报表嵌套)实现
未完待续— —!