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

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

系统必备

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

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

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

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

  2. 在**“已安装的模板”窗格中,选择“C#”“Visual Basic”。根据 Visual Studio 中的启动设置,“C#”“Visual Basic”节点可能会显示在“其他语言”**下。

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

  4. 在**“名称”**框中,键入项目的名称:PrintLocalReport。

  5. 在**“位置”框中,输入要保存项目的目录,或者单击“浏览”**以导航到该目录。

  6. 单击**“确定”。项目与显示“Program”代码文件的“代码”**窗口一起打开。

添加引用

  1. 从**“项目”菜单中,选择“添加引用”**。

  2. 在**“添加引用”对话框的“.NET”**选项卡上,选择 System.DrawingSystem.Windows.FormsMicrosoft.ReportViewer.Winforms

  3. 单击**“确定”**。

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

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

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

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

添加代码

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

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

    备注

    如果您的计算机上没有安装名为 Microsoft XPS Document Writer 的打印机,请将粗体代码更改为您计算机上的指定打印机。

    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 MemoryStream();
            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]);
    
            // Adjust rectangular area with printer margins.
            Rectangle adjustedRect = new Rectangle(
                ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
                ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
                ev.PageBounds.Width,
                ev.PageBounds.Height);
    
            // Draw a white background for the report
            ev.Graphics.FillRectangle(Brushes.White, adjustedRect);
    
            // Draw the report content
            ev.Graphics.DrawImage(pageImage, adjustedRect);
    
            // Prepare for the next page. Make sure we haven't hit the end.
            m_currentPageIndex++;
            ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
        }
    
        private void Print()
        {
            if (m_streams == null || m_streams.Count == 0)
                throw new Exception("Error: no stream to print.");
            PrintDocument printDoc = new PrintDocument();
            if (!printDoc.PrinterSettings.IsValid)
            {
                throw new Exception("Error: cannot find the default printer.");
            }
            else
            {
                printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
                m_currentPageIndex = 0;
                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);
            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();
            }
        }
    }
    
    Imports System
    Imports System.IO
    Imports System.Data
    Imports System.Text
    Imports System.Drawing
    Imports System.Drawing.Imaging
    Imports System.Drawing.Printing
    Imports System.Collections.Generic
    Imports System.Windows.Forms
    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
            ' Create a new DataSet and read sales data file 
            ' data.xml into the first DataTable.
            Dim dataSet As New DataSet()
            dataSet.ReadXml("..\..\data.xml")
            Return dataSet.Tables(0)
        End Function
    
        ' Routine to provide to the report renderer, in order to
        ' save an image for each page of the report.
        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 MemoryStream()
            m_streams.Add(stream)
            Return stream
        End Function
    
        ' Export the given report as an EMF (Enhanced Metafile) file.
        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()
            m_streams = New List(Of Stream)()
            report.Render("Image", deviceInfo, AddressOf CreateStream, warnings)
            For Each stream As Stream In m_streams
                stream.Position = 0
            Next
        End Sub
    
        ' Handler for PrintPageEvents
        Private Sub PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
            Dim pageImage As New Metafile(m_streams(m_currentPageIndex))
    
            ' Adjust rectangular area with printer margins.
            Dim adjustedRect As New Rectangle(ev.PageBounds.Left - CInt(ev.PageSettings.HardMarginX), _
                                              ev.PageBounds.Top - CInt(ev.PageSettings.HardMarginY), _
                                              ev.PageBounds.Width, _
                                              ev.PageBounds.Height)
    
            ' Draw a white background for the report
            ev.Graphics.FillRectangle(Brushes.White, adjustedRect)
    
            ' Draw the report content
            ev.Graphics.DrawImage(pageImage, adjustedRect)
    
            ' Prepare for the next page. Make sure we haven't hit the end.
            m_currentPageIndex += 1
            ev.HasMorePages = (m_currentPageIndex < m_streams.Count)
        End Sub
    
        Private Sub Print()
            If m_streams Is Nothing OrElse m_streams.Count = 0 Then
                Throw New Exception("Error: no stream to print.")
            End If
            Dim printDoc As New PrintDocument()
            If Not printDoc.PrinterSettings.IsValid Then
                Throw New Exception("Error: cannot find the default printer.")
            Else
                AddHandler printDoc.PrintPage, AddressOf PrintPage
                m_currentPageIndex = 0
                printDoc.Print()
            End If
        End Sub
    
        ' Create a local report for Report.rdlc, load the data,
        ' export the report to an .emf file, and print it.
        Private Sub Run()
            Dim report As New LocalReport()
            report.ReportPath = "..\..\Report.rdlc"
            report.DataSources.Add(New ReportDataSource("Sales", LoadSalesData()))
            Export(report)
            Print()
        End Sub
    
        Public Sub Dispose() Implements IDisposable.Dispose
            If m_streams IsNot Nothing Then
                For Each stream As 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 New Demo()
                demo.Run()
            End Using
        End Sub
    End Class
    

编译和运行应用程序

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

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

    上面的代码会将报表打印到 .xps 文件并提示您输入文件位置。如果您指定打印设备的名称,该代码会将报表直接打印到该设备。

请参见

参考

LocalReport

CreateStreamCallback

CreateStreamCallback

其他资源

示例和演练