演练:在不预览的情况下打印本地报表
本演练演示如何使用 LocalReport 对象和 CreateStreamCallback 回调函数以编程方式在不查看的情况下打印报表。
系统必备
您必须具有访问示例报表和数据源的权限。有关更多信息,请参见用于打印演练的示例数据和报表。
执行下列步骤可创建 Microsoft Visual Studio 控制台应用程序项目。
创建新的控制台应用程序项目
在**“文件”菜单上,指向“新建”,然后选择“项目”**。
在**“项目类型”窗格中,选择“Visual C#”或“Visual Basic”和“Windows”**。
在**“模板”窗格中,选择“控制台应用程序”**以创建 Microsoft 控制台应用程序。
在**“名称”框中,键入项目的名称:“打印本地报表”**。
在**“位置”框中,输入要保存项目的目录,或者单击“浏览”以导航到该目录。随即将打开项目,并在“代码”窗口中显示“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