演练:在不预览的情况下打印本地报表

本演练演示如何使用 LocalReport 对象和 CreateStreamCallback 回调函数以编程方式在不查看的情况下打印报表。

系统必备

您必须具有访问示例报表和数据源的权限。有关更多信息,请参见用于打印演练的示例数据和报表

执行下列步骤可创建 Microsoft Visual Studio 控制台应用程序项目。

创建新的控制台应用程序项目

  1. 在**“文件”菜单上,指向“新建”,然后选择“项目”**。

  2. 在**“项目类型”窗格中,选择“Visual C#”“Visual Basic”“Windows”**。

  3. 在**“模板”窗格中,选择“控制台应用程序”**以创建 Microsoft 控制台应用程序。

  4. 在**“名称”框中,键入项目的名称:“打印本地报表”**。

  5. 在**“位置”框中,输入要保存项目的目录,或者单击“浏览”以导航到该目录。随即将打开项目,并在“代码”窗口中显示“Program”**代码文件。

添加引用

  1. 从**“项目”菜单中,选择“添加引用”。将显示“添加引用”**对话框。

  2. 从“.NET”选项卡上显示的列表框中,选择 System.DrawingSystem.Windows.FormsMicrosoft.Reporting.Winforms

添加现有的 report.rdlc 和 data.xml 文件

  1. 从**“项目”菜单中选择“添加现有项”。随即将显示“添加现有项”**对话框。

  2. 定位到保存 report.rdlc 和 data.xml 的文件夹。然后选择这两个文件。

  3. 单击**“添加”**。这两个文件将作为项目的一部分显示在解决方案资源管理器中。

添加代码

  1. Program 代码文件应该已经打开并处于待编辑状态。如果该文件尚未打开,请在**“解决方案资源管理器”窗口中双击“Program.cs”“Module1.vb”**文件。

  2. 根据您的编程语言选择下面的代码,并用其替换**“Program”**文件中的现有代码。

    对于 Visual C#,请使用下面的代码。

    using System;
    using System.IO;
    using System.Data;
    using System.Text;
    using System.Drawing.Imaging;
    using System.Drawing.Printing;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using Microsoft.Reporting.WinForms;
    
    public class Demo : IDisposable
    {
        private int m_currentPageIndex;
        private IList<Stream> m_streams;
    
        private DataTable LoadSalesData()
        {
            // Create a new DataSet and read sales data file 
            //    data.xml into the first DataTable.
            DataSet dataSet = new DataSet();
            dataSet.ReadXml(@"..\..\data.xml");
            return dataSet.Tables[0];
        }
        // Routine to provide to the report renderer, in order to
        //    save an image for each page of the report.
        private Stream CreateStream(string name,
          string fileNameExtension, Encoding encoding,
          string mimeType, bool willSeek)
        {
            Stream stream = new FileStream(@"..\..\" + name +
               "." + fileNameExtension, FileMode.Create);
            m_streams.Add(stream);
            return stream;
        }
        // Export the given report as an EMF (Enhanced Metafile) file.
        private void Export(LocalReport report)
        {
            string deviceInfo =
              "<DeviceInfo>" +
              "  <OutputFormat>EMF</OutputFormat>" +
              "  <PageWidth>8.5in</PageWidth>" +
              "  <PageHeight>11in</PageHeight>" +
              "  <MarginTop>0.25in</MarginTop>" +
              "  <MarginLeft>0.25in</MarginLeft>" +
              "  <MarginRight>0.25in</MarginRight>" +
              "  <MarginBottom>0.25in</MarginBottom>" +
              "</DeviceInfo>";
            Warning[] warnings;
            m_streams = new List<Stream>();
            report.Render("Image", deviceInfo, CreateStream,
               out warnings);
            foreach (Stream stream in m_streams)
                stream.Position = 0;
        }
        // Handler for PrintPageEvents
        private void PrintPage(object sender, PrintPageEventArgs ev)
        {
            Metafile pageImage = new
               Metafile(m_streams[m_currentPageIndex]);
            ev.Graphics.DrawImage(pageImage, ev.PageBounds);
            m_currentPageIndex++;
            ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
        }
    
        private void Print()
        {
            const string printerName =
               "Microsoft Office Document Image Writer";
            if (m_streams == null || m_streams.Count == 0)
                return;
            PrintDocument printDoc = new PrintDocument();
            printDoc.PrinterSettings.PrinterName = printerName;
            if (!printDoc.PrinterSettings.IsValid)
            {
                string msg = String.Format(
                   "Can't find printer \"{0}\".", printerName);
                MessageBox.Show(msg, "Print Error");
                return;
            }
            printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
            printDoc.Print();
        }
        // Create a local report for Report.rdlc, load the data,
        //    export the report to an .emf file, and print it.
        private void Run()
        {
            LocalReport report = new LocalReport();
            report.ReportPath = @"..\..\Report.rdlc";
            report.DataSources.Add(
               new ReportDataSource("Sales", LoadSalesData()));
            Export(report);
            m_currentPageIndex = 0;
            Print();
        }
    
        public void Dispose()
        {
            if (m_streams != null)
            {
                foreach (Stream stream in m_streams)
                    stream.Close();
                m_streams = null;
            }
        }
    
        public static void Main(string[] args)
        {
            using (Demo demo = new Demo())
            {
                demo.Run();
            }
        }
    }
    

    对于 Visual Basic,请使用下面的代码。

    Imports System.IO
    Imports System.Data
    Imports System.Text
    Imports System.Drawing.Imaging
    Imports System.Drawing.Printing
    Imports System.Collections.Generic
    Imports Microsoft.Reporting.WinForms
    
    Public Class Demo
        Implements IDisposable
    
        Private m_currentPageIndex As Integer
        Private m_streams As IList(Of Stream)
    
        Private Function LoadSalesData() As DataTable
            Dim dataSet As New DataSet()
            dataSet.ReadXml("..\..\data.xml")
            Return dataSet.Tables(0)
        End Function
    
        Private Function CreateStream(ByVal name As String, _
           ByVal fileNameExtension As String, _
           ByVal encoding As Encoding, ByVal mimeType As String, _
           ByVal willSeek As Boolean) As Stream
            Dim stream As Stream = _
                New FileStream("..\..\" + _
                 name + "." + fileNameExtension, FileMode.Create)
            m_streams.Add(stream)
            Return stream
        End Function
    
        Private Sub Export(ByVal report As LocalReport)
            Dim deviceInfo As String = _
              "<DeviceInfo>" + _
              "  <OutputFormat>EMF</OutputFormat>" + _
              "  <PageWidth>8.5in</PageWidth>" + _
              "  <PageHeight>11in</PageHeight>" + _
              "  <MarginTop>0.25in</MarginTop>" + _
              "  <MarginLeft>0.25in</MarginLeft>" + _
              "  <MarginRight>0.25in</MarginRight>" + _
              "  <MarginBottom>0.25in</MarginBottom>" + _
              "</DeviceInfo>"
            Dim warnings() As Warning = Nothing
            m_streams = New List(Of Stream)()
            report.Render("Image", deviceInfo, AddressOf CreateStream, _
               warnings)
    
            Dim stream As Stream
            For Each stream In m_streams
                stream.Position = 0
            Next
        End Sub
    
        Private Sub PrintPage(ByVal sender As Object, _
        ByVal ev As PrintPageEventArgs)
            Dim pageImage As New Metafile(m_streams(m_currentPageIndex))
            ev.Graphics.DrawImage(pageImage, ev.PageBounds)
    
            m_currentPageIndex += 1
            ev.HasMorePages = (m_currentPageIndex < m_streams.Count)
        End Sub
    
        Private Sub Print()
            Const printerName As String = _
              "Microsoft Office Document Image Writer"
    
            If m_streams Is Nothing Or m_streams.Count = 0 Then
                Return
            End If
    
            Dim printDoc As New PrintDocument()
            printDoc.PrinterSettings.PrinterName = printerName
            If Not printDoc.PrinterSettings.IsValid Then
                Dim msg As String = String.Format( _
                    "Can't find printer ""{0}"".", printerName)
                Console.WriteLine(msg)
                Return
            End If
            AddHandler printDoc.PrintPage, AddressOf PrintPage
            printDoc.Print()
        End Sub
    
        Private Sub Run()
            Dim report As LocalReport = New LocalReport()
            report.ReportPath = "..\..\Report.rdlc"
            report.DataSources.Add(New ReportDataSource("Sales", _
               LoadSalesData()))
    
            Export(report)
    
            m_currentPageIndex = 0
            Print()
        End Sub
    
        Public Overloads Sub Dispose() Implements IDisposable.Dispose
            If Not (m_streams Is Nothing) Then
                Dim stream As Stream
                For Each stream In m_streams
                    stream.Close()
                Next
                m_streams = Nothing
            End If
        End Sub
    
        Public Shared Sub Main(ByVal args As String())
            Using demo As Demo = New Demo()
                demo.Run()
            End Using
        End Sub
    End Class
    

编译和运行应用程序

  1. 在**“生成”菜单上单击“生成解决方案”以生成应用程序。在生成过程中,会编译报表并将发现的所有错误(例如报表中所用的表达式中的语法错误)都添加到“任务列表”**中。

  2. 按**“F5”**运行应用程序。

另请参见

参考

LocalReport
Microsoft.Reporting.WinForms.CreateStreamCallback
Microsoft.Reporting.WebForms.CreateStreamCallback

其他资源

示例和演练