チュートリアル : プレビューを使用しないローカル レポートの印刷
このチュートリアルでは、LocalReport オブジェクトおよび CreateStreamCallback コールバック関数を使用して、レポートを表示せずにプログラムによって印刷する方法について説明します。
必要条件
サンプル レポートとデータ ソースへのアクセス権が必要です。詳細については、「印刷チュートリアルのサンプル データおよびレポート」を参照してください。
コンソール アプリケーション プロジェクトを作成するには、次の手順に従ってください。
新しいコンソール アプリケーション プロジェクトの作成
[ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。
[インストールされたテンプレート] ペインで [C#] または [Visual Basic] を選択します。Visual Studio の起動設定によっては、[C#] または [Visual Basic] ノードが [他の言語] に表示される場合もあります。
[テンプレート] ペインの [コンソール アプリケーション] を選択します。
[名前] ボックスに、プロジェクト名を「PrintLocalReport」と入力します。
[場所] ボックスにプロジェクトを保存するディレクトリを入力するか、[参照] をクリックしてディレクトリを選択します。
[OK] をクリックします。[コード] ウィンドウに Program コード ファイルが表示された状態でプロジェクトが開きます。
参照の追加
[プロジェクト] メニューの [参照の追加] をクリックします。
[参照の追加] ダイアログ ボックスの [.NET] タブで、System.Drawing、System.Windows.Forms、および Microsoft.ReportViewer.Winforms を選択します。
[OK] をクリックします。
既存のファイル report.rdlc および data.xml の追加
[プロジェクト] メニューの [既存項目の追加] をクリックします。[既存項目の追加] ダイアログ ボックスが表示されます。
report.rdlc と data.xml が保存されているフォルダーに移動します。両方のファイルを選択します。
[追加] をクリックします。2 つのファイルが、ソリューション エクスプローラーにプロジェクトの一部として表示されます。
コードの追加
Program コード ファイルが編集用に既に開いている状態になっています。開いていない場合は、[ソリューション エクスプローラー] ウィンドウで Program.cs ファイルまたは Module1.vb ファイルをダブルクリックします。
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
アプリケーションのビルドと実行
[ビルド] メニューの [ソリューションのビルド] をクリックしてアプリケーションをビルドします。ビルド プロセスの一環として、レポートがコンパイルされ、エラー (レポートで使用された式の構文エラーなど) が発生した場合、タスク一覧にそのエラーが追加されます。
F5 キーを押してアプリケーションを実行します。
上のコードを実行すると、レポートが .xps ファイルとして出力され、ファイルの場所を指定するよう求められます。印刷デバイスの名前を指定すると、レポートはその印刷デバイスに直接出力されます。
関連項目
参照
Microsoft.Reporting.WinForms.CreateStreamCallback
Microsoft.Reporting.WebForms.CreateStreamCallback