利用XML实现通用WEB报表打印(4)

转载 2004年08月27日 12:43:00
 最后,我们还需要一个解析器用来解析顶层的标签和生成相应的对象,它在此模式中的作用就是一个"工厂类",负责生产出用户需要的"产品"。代码如下:

using System;
using System.Xml;

namespace RemotePrint
{
public class Parser
{
public Parser()
{
}
public static PrintElement CreateElement(XmlNode element)
{
PrintElement printElement = null;
switch(element.Name)
{
case "text":
printElement = new Text(element);
break;
case "table":
printElement = new Table(element);
break;
default:
printElement = new PrintElement();
break;
}
return printElement;
}
}
}

  好了,核心的解析和标签的具体打印方法已经完成了,现在我们回到PrintControl中编写一些代码来测试我们的成果。

  首先,需要引用两个要用到的名称空间:

using System.Xml;

using System.Drawing.Printing;

  然后,在打印之前,需要根据XML文件中的pagesetting标签来设置一下打印机的页面,所以我们先写一个方法来设置打印机。在PrintControl类中增加一个私有的方法:

private void SettingPrinter(XmlNode ps)
{
file://打印方向(纵/横)
this.printDocument1.DefaultPageSettings.Landscape = bool.Parse(ps["landscape"].InnerText);
file://设置纸张类型
string papername = ps["paperkind"].InnerText;
bool fitpaper = false;
file://获取打印机支持的所有纸张类型
foreach(PaperSize size in this.printDocument1.PrinterSettings.PaperSizes)
{
if(papername == size.PaperName)//看该打印机是否有我们需要的纸张类型
{
this.printDocument1.DefaultPageSettings.PaperSize = size;
fitpaper = true;
}
}
if(!fitpaper)
{
file://假如没有我们需要的标准类型,则使用自定义的尺寸
this.printDocument1.DefaultPageSettings.PaperSize =
new PaperSize("Custom", int.Parse(ps["paperwidth"].InnerText),
int.Parse(ps["paperheight"].InnerText));
}
}

  接下来,我们类中添加一个XmlDocument的对象和一个静态变量计算页码:

private XmlDocument doc = new XmlDocument();

public static int Pages = 1;

  然后再控件的Load事件中为该对象加载XML报表数据,代码如下:

private void PrintControl_Load(object sender, System.EventArgs e)
{
try
{
file://装载报表XML数据
this.label1.Text = "正在加载报表数据,请稍侯...";
doc.Load("http://localhost/report.xml");
this.label1.Text = "报表数据加载完毕!";
this.button1.Enabled = this.button2.Enabled = this.button3.Enabled = true;
}
catch(Exception ex)
{
this.label1.Text = "出现错误:" + ex.Message;
}
}

  请注意,我们这里只是装入了一个本地的测试数据文件,其实,完全可以改成装载网络上任何地方的静态或者动态的XML文件,例如以上的doc.Load("http://localhost/report.xml")可以改写成:

doc.Load("http://www.anywhere.com/report.xml");

doc.Load("http://www.anywhere.com/report.asp");

doc.Load("http://www.anywhere.com/report.jsp?date=xxx");

  等等,只要装载的数据是符合我们规定的XML数据文档就可以。

  然后在控件的构造函数中加入打印事件的委托:

public PrintControl()

{

InitializeComponent();

this.printDocument1.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);

}

  该委托方法的代码如下:

private void pd_PrintPage(object sender, PrintPageEventArgs ev)
{
Graphics g = ev.Graphics;
bool HasMorePages = false;
PrintElement printElement = null;

foreach(XmlNode node in doc["root"]["reporttable"].ChildNodes)
{
printElement = Parser.CreateElement(node);//调用解析器生成相应的对象
try
{
HasMorePages = printElement.Draw(g);//是否需要分页
}
catch(Exception ex)
{
this.label1.Text = ex.Message;
}
}

file://在页底中间输出页码
Font font = new Font("黑体", 12.0f);
Brush brush = new SolidBrush(Color.Black);
g.DrawString("第 " + Pages.ToString() + " 页",
font,brush,ev.MarginBounds.Width / 2 + ev.MarginBounds.Left - 30,
ev.PageBounds.Height - 60);

if(HasMorePages)
{
Pages++;
}
ev.HasMorePages = HasMorePages;
}

  三个按纽的Click事件代码分别如下:

//页面设置
private void button1_Click(object sender, System.EventArgs e)
{
this.pageSetupDialog1.ShowDialog();
this.printDocument1.DefaultPageSettings = this.pageSetupDialog1.PageSettings;
}
file://打印预览
private void button2_Click(object sender, System.EventArgs e)
{
try
{
this.printPreviewDialog1.ShowDialog();
}
catch(Exception ex)
{
this.label1.Text = ex.Message;
}
}
file://打印
private void button3_Click(object sender, System.EventArgs e)
{
try
{
this.printDocument1.Print();
}
catch(Exception ex)
{
this.label1.Text = ex.Message;
}
}

  好了,我们的打印控件到这里就全部做完了,选择生成一个Release的版本,然后到工程目录下将生成的PrintControl.dll文件拷贝到IIS的虚拟根目录下,然后新建一个remoteprint.htm的HTML格式文件,在合适的地方加上:<object id="print" classid="http:RemotePrint.dll#RemotePrint.PrintControl" Width="100%" Height="60"> </object>,为了更加形象和美观,还可以将需要打印的数据做成网页形式放在上面,如果需要获取的XML是动态数据源,则可以采用asp等动态脚本来生成该网页表格,如果需要获取的XML是一个静态的文本,则可以采用XSLT直接将XML文件转换成网页表格。

  打开浏览器,输入:http://localhost/remoteprint.htm,如果您已经跟我一样,事先做好了一个XML报表数据文件的话,您就可以看到下图所示的效果

jt-030214-1-xmlwebprint6.jpg  

jt-030214-1-xmlwebprint7.jpg

  请注意:该图示例中的所有数据均为笔者随意虚拟,网页中的表格数据和打印数据并非来自同一数据源,也没有刻意去对等,仅仅只是为了演示一下效果,因此网页显示报表跟打印预览中的报表有一些出入是正常的。在实际应用中可以让网页显示数据跟打印输出数据完全一致。

J2EE vs. NET, Java vs. C#:比较公正的评价

J2EE vs. NET, Java vs. C#:Since theres been plenty of discussion on these topics, I thought Id write...
  • Nightmare
  • Nightmare
  • 2003-06-02 11:42:00
  • 1902

利用XML实现通用WEB报表打印

  • 2005年11月15日 15:25
  • 264KB
  • 下载

利用XML实现通用WEB报表打印 (收藏)

  专栏作品 利用XML实现通用WEB报表打印卢彦 方案适用性. 1. 远程数据打印。需要打印的数据并不在本地,必须进行远程读取。 2. 需要精确控制打印效果,包括页面格式,分页,附加条目,表格...
  • qunluo
  • qunluo
  • 2004-07-22 16:48:00
  • 1609

利用XML实现通用WEB报表打印(1)

 开发B/S结构的应用程序最头疼的问题可能就是报表打印了,由于只能采用浏览器来作为用户界面进行交互,所以不能精确控制客户端的打印机。而很多B/S结构的应用程序常常需要完成非常复杂的报表打印任务。而靠I...
  • tangkuai
  • tangkuai
  • 2004-08-27 13:00:00
  • 1118

利用XML实现通用WEB报表打印(5)

方案扩充:   那么如何打印一些特殊形态的图表,前文中已经提到,采用本方案可以非常方便的定义出自己所需要的标签,在理论上可以打印出任何样式的特殊图表。因此本文打算详细介绍一下增加自己定义的标签扩充打印...
  • tangkuai
  • tangkuai
  • 2004-08-27 12:37:00
  • 775

利用XML实现通用WEB报表打印(3)

.Net Web控件方案的实现和扩充  软件原理:   该软件的原理其实很简单,就是要方便的解析出定义好的XML格式标记,解读出文件中标记的参数定义,最后将这些信息还原成打印机输出的图形格式。  为了...
  • tangkuai
  • tangkuai
  • 2004-08-27 12:45:00
  • 929

利用XML实现通用WEB报表打印

目录方案适用性 方案原理 技术选择 可行性分析 伸缩性和安全性 方案设计图 格式定义 总结 作者方案适用性1. 远程数据打印。需要打印的数据并不在本地,必须进行远程读取。2. 需要精确控制打印效果,包...
  • dtljf
  • dtljf
  • 2004-12-04 23:42:00
  • 755

利用XML实现通用WEB报表打印简述

方案适用性.1. 远程数据打印。需要打印的数据并不在本地,必须进行远程读取。2. 需要精确控制打印效果,包括页面格式,分页,附加条目,表格等。3. 出于安全性考虑,不能直接连接到数据库。方案原理其实原...
  • lifuyun
  • lifuyun
  • 2008-05-08 09:43:00
  • 521

利用XML实现通用WEB报表打印(2)

伸缩性和安全性  伸缩性  由于采用的是XML标准数据格式作为中间数据交换,因此本解决方案具有非常好伸缩性,例如,客户端的.NET控件可以采用JAVA APPLET、ACTIVX或者是VB,VC等编写...
  • tangkuai
  • tangkuai
  • 2004-08-27 12:59:00
  • 904

利用XML实现通用WEB报表打印(1) 卢彦

摘要开发B/S结构的应用程序最头疼的问题可能就是报表打印了,由于只能采用浏览器来作为用户界面进行交互,所以不能精确控制客户端的打印机。而很多B/S结构的应用程序常常需要完成非常复杂的报表打印任务。而靠...
  • bh812
  • bh812
  • 2005-11-22 23:09:00
  • 972
收藏助手
不良信息举报
您举报文章:利用XML实现通用WEB报表打印(4)
举报原因:
原因补充:

(最多只允许输入30个字)