Пошаговое руководство. Печать локального отчета без просмотра
В этом пошаговом руководстве показано, как программным образом распечатать отчет без просмотра. Для этого используется объект LocalReport и функция ответного вызова CreateStreamCallback.
Предварительные требования
Необходимо иметь доступ к образцу отчета и источнику данных. Дополнительные сведения см. в разделе Образцы данных и образец отчета для пошагового руководства по печати.
Выполните следующие шаги, чтобы создать проект приложения командной строки среды Microsoft Visual Studio.
Создание нового проекта приложения командной строки
В меню Файл последовательно выберите команды Создать и Проект.
В области Типы проекта выберите Visual C# или Visual Basic и Windows.
В области Шаблоны выберите пункт Консольное приложение, чтобы создать приложение командной строки (Майкрософт).
В поле Имя введите имя проекта: 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