逐步解說:列印本機報表而不進行預覽
本逐步解說示範如何使用 LocalReport 物件和 CreateStreamCallback 回呼函式,以程式設計方式列印報表而不檢視報表。
必要條件
您必須有範例報表和資料來源的存取權。如需詳細資訊,請參閱列印逐步解說的範例資料和報表。
請執行下列步驟來建立 Microsoft Visual Studio 主控台應用程式專案。
建立新的主控台應用程式專案
在 [檔案] 功能表中,指向 [開新檔案],再選取 [專案]。
在 [專案類型] 窗格中,選擇 [Visual C#] 或 [Visual Basic] 和 [Windows]。
在 [範本] 窗格中,選擇 [主控台應用程式],建立 Microsoft 主控台應用程式。
在 [名稱] 方塊中,輸入專案的名稱:PrintLocalReport。
在 [位置] 方塊中,輸入用來儲存專案的目錄,或按一下 [瀏覽] 來導覽找到它。此專案會與 [程式碼] 視窗一起開啟,顯示 Program 程式碼檔案。
新增參考
從 [專案] 功能表中,選取 [新增參考]。此時會出現 [新增參考] 對話方塊。
從 [.NET] 索引標籤上顯示的清單方塊中,選取 System.Drawing、System.Windows.Forms 和 Microsoft.Reporting.Winforms。
加入現有的檔案 report.rdlc 和 data.xml
從 [專案] 功能表上,選取 [加入現有項目]。[加入現有項目] 對話方塊隨即出現。
導覽至儲存 report.rdlc 和 data.xml 的資料夾。選取這兩個檔案。
按一下 [加入]。這兩個檔案會以專案之一部分的形式出現在 [方案總管] 中。
新增程式碼
Program 程式碼檔案應該已經開啟可供編輯。如果不是的話,請按兩下 [方案總管] 視窗中的 Program.cs 或 Module1.vb 檔案。
使用您選擇之程式設計語言的下列程式碼來取代 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
建立和執行應用程式
在 [建置] 功能表中,按一下 [建置方案] 來建立應用程式。建立過程中會編譯報表,並將找到的任何錯誤 (例如用於報表中的運算式語法錯誤) 加入到 [工作清單] 中。
按 F5 執行應用程式。
另請參閱
參考
LocalReport
Microsoft.Reporting.WinForms.CreateStreamCallback
Microsoft.Reporting.WebForms.CreateStreamCallback