逐步解說:列印本機報表而不進行預覽

本逐步解說示範如何使用 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

其他資源

範例與逐步解說