1、使用第三方控件,CSDN首页上有介绍
2、有这样一个示例:利用XML实现通用WEB报表打印(http://www.microsoft.com/china/community/article.asp?oBODY=TechZone/TechArticle/TechDoc/xmlwebreport&oXSLT=TechZone/TechArticle/TechContent)

解决方案 »

  1.   

    : sumanden(心头慌,打中张) 这个文章很好。 用来做一些特殊的报表很好文章的下篇
    http://www.microsoft.com/china/community/TechZone/TechArticle/TechDoc/xmlwebprint.asp
      

  2.   

    把你最麻烦的报表样式 给我看看。 看看 楼上的这种xml 写的dll 能不能实现!
      

  3.   

    那个XML打印的源程序:不过要先译成DLL才可以.
    using System;
    using System.Xml;
    using System.Data;
    using System.Drawing;
    using System.Collections;
    using System.Windows.Forms;
    using System.ComponentModel;
    using System.Drawing.Printing;
    using System.Drawing.Drawing2D;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;
    case "linechart"://新增加的linechart
    printElement = new LineChart(element);
    break;
    default:
    printElement = new PrintElement();
    break;
    }
    return printElement;
    }
    } public class LineChart : PrintElement
    {
    private XmlNode chart;
    public LineChart(XmlNode Chart)
    {
    chart = Chart;
    }

    public override bool Draw(Graphics g)
    {
    DrawCoordinate(g, chart["coordinate"]);//画坐标轴
    DrawChart(g, chart["chart"]);
    return false;
    }

    private void DrawCoordinate(Graphics g, XmlNode coo)
    {
    DrawXCoor(g, coo["xcoordinate"]);//画X坐标
    DrawYCoor(g, coo["ycoordinate"]);//画Y坐标
    }

    private void DrawXCoor(Graphics g, XmlNode xcoo)
    {
    int x = int.Parse(xcoo.Attributes["x"].InnerText);
    int y = int.Parse(xcoo.Attributes["y"].InnerText);
    int length = int.Parse(xcoo.Attributes["length"].InnerText);
    bool arrow = bool.Parse(xcoo.Attributes["arrow"].InnerText);
    int stroke = int.Parse(xcoo.Attributes["stroke"].InnerText);
    Color color = Color.FromName(xcoo.Attributes["color"].InnerText);
    Pen pen = new Pen(color, (float)stroke);
    if(arrow)//是否有箭头
    {
    AdjustableArrowCap Arrow = new AdjustableArrowCap(
    (float)(stroke * 1.5 + 1.5), 
    (float)(stroke * 1.5 + 2), true);
    pen.CustomEndCap = Arrow;
    }
    g.DrawLine(pen, x, y, x + length, y);//画坐标
    //画刻度
    foreach(XmlNode scale in xcoo.ChildNodes)
    {
    int len = int.Parse(scale.Attributes["length"].InnerText);
    int height = int.Parse(scale.Attributes["height"].InnerText);
    int width = int.Parse(scale.Attributes["width"].InnerText);
    int fontsize = int.Parse(scale.Attributes["fontsize"].InnerText);
    Color clr = Color.FromName(scale.Attributes["color"].InnerText);
    string name = scale.InnerText;

    Pen p = new Pen(clr, (float)width);
    g.DrawLine(p, x + len, y, x + len, y - height);
    Font font = new Font("Arial", (float)fontsize);
    g.DrawString(
    name, font, new SolidBrush(clr), 
    (float)(x + len - 10), (float)(y + 10));
    }
    }

    private void DrawYCoor(Graphics g, XmlNode ycoo)
    {
    int x = int.Parse(ycoo.Attributes["x"].InnerText);
    int y = int.Parse(ycoo.Attributes["y"].InnerText);
    int length = int.Parse(ycoo.Attributes["length"].InnerText);
    bool arrow = bool.Parse(ycoo.Attributes["arrow"].InnerText);
    int stroke = int.Parse(ycoo.Attributes["stroke"].InnerText);
    Color color = Color.FromName(ycoo.Attributes["color"].InnerText);
    Pen pen = new Pen(color, (float)stroke);
    if(arrow)//是否有箭头
    {
    AdjustableArrowCap Arrow = new AdjustableArrowCap(
    (float)(stroke * 1.5 + 2), 
    (float)(stroke * 1.5 + 3), 
    true);
    pen.CustomEndCap = Arrow;
    }
    g.DrawLine(pen, x, y, x, y + length);//画坐标
    //画刻度
    foreach(XmlNode scale in ycoo.ChildNodes)
    {
    int len = int.Parse(scale.Attributes["length"].InnerText);
    int height = int.Parse(scale.Attributes["height"].InnerText);
    int width = int.Parse(scale.Attributes["width"].InnerText);
    int fontsize = int.Parse(scale.Attributes["fontsize"].InnerText);
    Color clr = Color.FromName(scale.Attributes["color"].InnerText);
    string name = scale.InnerText;
    Pen p = new Pen(clr, (float)width);
    g.DrawLine(p, x, y + len, x + height, y + len);
    Font font = new Font("Arial", (float)fontsize);
    StringFormat sf = new StringFormat();
    sf.Alignment = StringAlignment.Far;
    RectangleF rect = new RectangleF(
    (float)(x - 100), 
    (float)(y + len - 25),
    90f, 
    50f);
    sf.LineAlignment = StringAlignment.Center;
    g.DrawString(name, font, new SolidBrush(clr), rect, sf);
    }
    }
      

  4.   

    接上页: private void DrawChart(Graphics g, XmlNode chart)
    {
    foreach(XmlNode lines in chart.ChildNodes)
    {
    DrawLines(g, lines);
    }
    } private void DrawLines(Graphics g, XmlNode lines)
    {
    int Stroke = int.Parse(lines.Attributes["stroke"].InnerText);
    Point[] points = new Point[lines.ChildNodes.Count];
    Color linecolor = Color.FromName(lines.Attributes["color"].InnerText);
    for(int i = 0; i < lines.ChildNodes.Count; i++)
    {
    XmlNode node = lines.ChildNodes[i];
    points[i] = new Point(
    int.Parse(node.Attributes["x"].InnerText), 
    int.Parse(node.Attributes["y"].InnerText));
    int Radius = int.Parse(node.Attributes["radius"].InnerText);
    Color pointcolor = Color.FromName(node.Attributes["color"].InnerText);
    if(Radius != 0)//画点
    {
    g.FillEllipse(new SolidBrush(pointcolor),
    points[i].X - Radius, 
    points[i].Y - Radius, 
    Radius * 2, 
    Radius * 2);
    }
    }
    Pen pen = new Pen(linecolor);
    g.DrawLines(pen, points);//画线
    }
    } public class PrintElement
    {
    public PrintElement()
    {
    } public virtual bool Draw(Graphics g)
    {
    return false;
    }
    } public class Table : PrintElement
    {
    private XmlNode table;
    public static int count = 0, pc = 1; public Table(XmlNode Table)
    {
    table = Table;
    } public override bool Draw(Graphics g)
    {
    //表格坐标
    int tableX = int.Parse(table.Attributes["x"].InnerText);
    int tableY = int.Parse(table.Attributes["y"].InnerText);
    int x = tableX, y = tableY;
    DrawTopLine(g, table);//画表格顶线
    Pen pen = new Pen(Color.FromName(table.Attributes["bordercolor"].InnerText), 
    float.Parse(table.Attributes["border"].InnerText));
    int trheight = 0;
    //表头
    foreach(XmlNode tr in table["tablehead"].ChildNodes)
    {
    trheight = int.Parse(tr.Attributes["height"].InnerText);
    DrawTR(x, y, tr, pen, g);
    y += trheight;
    }
    //表项
    for(int i = 0; i < int.Parse(table.Attributes["maxlines"].InnerText); i++)
    {
    XmlNode tr = table["tablebody"].ChildNodes[count];
    trheight = int.Parse(tr.Attributes["height"].InnerText);
    DrawTR(x, y, tr, pen, g);
    y += trheight;
    count++;
    if(count == table["tablebody"].ChildNodes.Count)
    break;
    }
    x = tableX;
    //表底
    foreach(XmlNode tr in table["tablefoot"].ChildNodes)
    {
    trheight = int.Parse(tr.Attributes["height"].InnerText);
    DrawTR(x, y, tr, pen, g);
    y += trheight;
    }
    int currentpage = pc;
    pc++;
    bool hasPage = false; if(count < table["tablebody"].ChildNodes.Count - 1)
    {
    hasPage = true;//需要继续打印
    }
    else
    {
    count = 0;
    pc = 1;
    hasPage = false;//表格打印完毕
    }
    return hasPage;
    } private void DrawTopLine(Graphics g, XmlNode table)
    {
    Pen pen = new Pen(Color.FromName(table.Attributes["bordercolor"].InnerText), 
    float.Parse(table.Attributes["border"].InnerText));
    int width = 0;
    foreach(XmlNode td in table.FirstChild.FirstChild)
    {
    width += int.Parse(td.Attributes["width"].InnerText);
    }
    int x = int.Parse(table.Attributes["x"].InnerText);
    int y = int.Parse(table.Attributes["y"].InnerText);
    g.DrawLine(pen, x, y, x + width, y);
    } //画表格行
    private void DrawTR(int x, int y, XmlNode tr, Pen pen, Graphics g)
    {
    int height = int.Parse(tr.Attributes["height"].InnerText);
    int width;
    g.DrawLine(pen, x, y, x, y + height);//画左端线条
    foreach(XmlNode td in tr)
    {
    width = int.Parse(td.Attributes["width"].InnerText);
    DrawTD(x, y, width, height, td, g);
    g.DrawLine(pen, x + width, y, x + width, y + height);//右线
    g.DrawLine(pen, x, y + height, x + width, y + height);//底线
    x += width;
    }
    } //画单元格
    private void DrawTD(int x, int y, int width, int height, XmlNode td, Graphics g)
    {
    Brush brush = new SolidBrush(Color.FromName(td.Attributes["bgcolor"].InnerText));
    g.FillRectangle(brush, x, y, width, height);
    FontStyle style = FontStyle.Regular;
    //设置字体样式
    if(td.Attributes["b"].InnerText == "true")
    style |= FontStyle.Bold;
    if(td.Attributes["i"].InnerText == "true")
    style |= FontStyle.Italic;
    if(td.Attributes["u"].InnerText == "true")
    style |= FontStyle.Underline;
    Font font = new Font(td.Attributes["fontname"].InnerText, 
    float.Parse(td.Attributes["fontsize"].InnerText), style);
    brush = new SolidBrush(Color.FromName(td.Attributes["fontcolor"].InnerText));
    StringFormat sf = new StringFormat();
    //设置对齐方式
    switch(td.Attributes["align"].InnerText)
    {
    case "center":
    sf.Alignment = StringAlignment.Center;
    break;
    case "right":
    sf.Alignment = StringAlignment.Near;
    break;
    default:
    sf.Alignment = StringAlignment.Far;
    break;
    }
    sf.LineAlignment = StringAlignment.Center;
    RectangleF rect = new RectangleF( (float)x, (float)y, (float)width, (float)height);
    g.DrawString(td.InnerText, font, brush, rect, sf);
    }
    } public class Text : PrintElement
    {
    private XmlNode text = null;
    public Text(XmlNode Text)
    {
    text = Text;
    }
    public override bool Draw(Graphics g)
    {
    Font font = new Font(text.Attributes["fontname"].InnerText, 
    int.Parse(text.Attributes["fontsize"].InnerText));
    Brush brush = new SolidBrush(Color.FromName(text.Attributes["fontcolor"].InnerText));
    g.DrawString(text.InnerText, font, brush, float.Parse(text.Attributes["x"].InnerText), 
    float.Parse(text.Attributes["y"].InnerText));
    return false;
    }
    }
      

  5.   

    再接上页: public class PrintControl : System.Windows.Forms.UserControl
    {
    private System.Windows.Forms.Button button1;
    private System.Windows.Forms.Button button2;
    private System.Windows.Forms.Button button3;
    private System.Windows.Forms.Label label1;
    private System.Drawing.Printing.PrintDocument printDocument1;
    private System.Windows.Forms.PageSetupDialog pageSetupDialog1;
    private System.Windows.Forms.PrintPreviewDialog printPreviewDialog1;
    private XmlDocument doc = new XmlDocument();
    public static int Pages = 1;
    /// <summary>
    /// 必需的设计器变量。
    /// </summary>
    private System.ComponentModel.Container components = null; private void SettingPrinter(XmlNode ps)
    {
    //打印方向(纵/横)
    this.printDocument1.DefaultPageSettings.Landscape = bool.Parse(ps["landscape"].InnerText);
    //设置纸张类型
    string papername = ps["paperkind"].InnerText;
    bool fitpaper = false;
    //获取打印机支持的所有纸张类型
    foreach(PaperSize size in this.printDocument1.PrinterSettings.PaperSizes)
    {
    if(papername == size.PaperName)//看该打印机是否有我们需要的纸张类型
    {
    this.printDocument1.DefaultPageSettings.PaperSize = size;
    fitpaper = true;
    }
    }
    if(!fitpaper)
    {
    //假如没有我们需要的标准类型,则使用自定义的尺寸
    this.printDocument1.DefaultPageSettings.PaperSize = 
    new PaperSize("Custom", int.Parse(ps["paperwidth"].InnerText), 
    int.Parse(ps["paperheight"].InnerText));
    }
    } public PrintControl()
    {
    // 该调用是 Windows.Forms 窗体设计器所必需的。
    InitializeComponent();
    // TODO: 在 InitializeComponent 调用后添加任何初始化
    this.printDocument1.PrintPage += new PrintPageEventHandler(this.pd_PrintPage);
    } /// <summary>
    /// 清理所有正在使用的资源。
    /// </summary>
    protected override void Dispose( bool disposing )
    {
    if( disposing )
    {
    if( components != null )
    components.Dispose();
    }
    base.Dispose( disposing );
    } #region Component Designer generated code
    /// <summary>
    /// 设计器支持所需的方法 - 不要使用代码编辑器 
    /// 修改此方法的内容。
    /// </summary>
    private void InitializeComponent()
    {
    System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(PrintControl));
    this.button1 = new System.Windows.Forms.Button();
    this.button2 = new System.Windows.Forms.Button();
    this.button3 = new System.Windows.Forms.Button();
    this.label1 = new System.Windows.Forms.Label();
    this.printDocument1 = new System.Drawing.Printing.PrintDocument();
    this.pageSetupDialog1 = new System.Windows.Forms.PageSetupDialog();
    this.printPreviewDialog1 = new System.Windows.Forms.PrintPreviewDialog();
    this.SuspendLayout();
    // 
    // button1
    // 
    this.button1.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
    this.button1.Enabled = false;
    this.button1.Location = new System.Drawing.Point(192, 40);
    this.button1.Name = "button1";
    this.button1.TabIndex = 0;
    this.button1.Text = "页面设置";
    this.button1.Click += new System.EventHandler(this.button1_Click);
    // 
    // button2
    // 
    this.button2.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
    this.button2.Enabled = false;
    this.button2.Location = new System.Drawing.Point(280, 40);
    this.button2.Name = "button2";
    this.button2.TabIndex = 1;
    this.button2.Text = "打印预览";
    this.button2.Click += new System.EventHandler(this.button2_Click);
    // 
    // button3
    // 
    this.button3.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
    this.button3.Enabled = false;
    this.button3.Location = new System.Drawing.Point(368, 40);
    this.button3.Name = "button3";
    this.button3.TabIndex = 2;
    this.button3.Text = "打  印";
    this.button3.Click += new System.EventHandler(this.button3_Click);
    // 
    // label1
    // 
    this.label1.Anchor = System.Windows.Forms.AnchorStyles.Left;
    this.label1.AutoSize = true;
    this.label1.Location = new System.Drawing.Point(8, 40);
    this.label1.Name = "label1";
    this.label1.Size = new System.Drawing.Size(48, 14);
    this.label1.TabIndex = 3;
    this.label1.Text = "状态...";
    // 
    // pageSetupDialog1
    // 
    this.pageSetupDialog1.Document = this.printDocument1;
    // 
    // printPreviewDialog1
    // 
    this.printPreviewDialog1.AutoScrollMargin = new System.Drawing.Size(0, 0);
    this.printPreviewDialog1.AutoScrollMinSize = new System.Drawing.Size(0, 0);
    this.printPreviewDialog1.ClientSize = new System.Drawing.Size(400, 300);
    this.printPreviewDialog1.Document = this.printDocument1;
    this.printPreviewDialog1.Enabled = true;
    this.printPreviewDialog1.Icon = ((System.Drawing.Icon)(resources.GetObject("printPreviewDialog1.Icon")));
    this.printPreviewDialog1.Location = new System.Drawing.Point(275, 14);
    this.printPreviewDialog1.MaximumSize = new System.Drawing.Size(0, 0);
    this.printPreviewDialog1.Name = "printPreviewDialog1";
    this.printPreviewDialog1.Opacity = 1;
    this.printPreviewDialog1.TransparencyKey = System.Drawing.Color.Empty;
    this.printPreviewDialog1.Visible = false;
    // 
    // PrintControl
    // 
    this.BackColor = System.Drawing.Color.White;
    this.Controls.AddRange(new System.Windows.Forms.Control[] {
      this.label1,
      this.button3,
      this.button2,
      this.button1});
    this.Name = "PrintControl";
    this.Size = new System.Drawing.Size(456, 88);
    this.Load += new System.EventHandler(this.PrintControl_Load);
    this.ResumeLayout(false); }
    #endregion private void PrintControl_Load(object sender, System.EventArgs e)
    {
    try
    {
    //装载报表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;
    }
    } 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;
    }
    } //在页底中间输出页码
    Font font = new Font("Arial", 12.0f);
    Brush brush = new SolidBrush(Color.Black);
    g.DrawString("The" + Pages.ToString() + "Page",
    font,brush,ev.MarginBounds.Width / 2 + ev.MarginBounds.Left - 30, 
    ev.PageBounds.Height - 60); if(HasMorePages)
    {
    Pages++;
    }
    ev.HasMorePages = HasMorePages;
    } private void button1_Click(object sender, System.EventArgs e)
    {
    this.pageSetupDialog1.ShowDialog();
    this.printDocument1.DefaultPageSettings = this.pageSetupDialog1.PageSettings;
    } private void button2_Click(object sender, System.EventArgs e)
    {
    try
    {
    this.printPreviewDialog1.ShowDialog();
    }
    catch(Exception ex)
    {
    this.label1.Text = ex.Message;
    }
    } private void button3_Click(object sender, System.EventArgs e)
    {
    try
    {
    this.printDocument1.Print();
    }
    catch(Exception ex)
    {
    this.label1.Text = ex.Message;
    }
    }
    }
    }
    终于完事了.
      

  6.   

    to:hongshun(好好)
    我还没有开始做
      

  7.   

    旧帖子(2002年3月至今)需要重新build静态页面,方法是:http://expert.csdn.net/expert/buildtopic.asp?id=帖子id