C#中直接列印Report檔案(rdlc)

iDotNetSpace發表於2010-08-12

Visual Studio自帶的報表檔案(rdlc,後面提到的報表,都指rdlc報表檔案)雖然功能相對不是十分強大,但應付一般的報表要求也是綽綽有餘了。關於rdlc報表的使用和設計方法,這裡就不做講解了,本文主要介紹一下如何不使用報表預覽控制元件(ReportViewer),直接將報表的內容在印表機上列印出來。

一般情況下,我們設計好報表後,在程式執行的時候,會將其載入到ReprotViewer控制元件中進行預覽並列印,但有些情況下,我們不想預覽報表的內容,而直接將其在印表機上列印出來,又該怎麼做呢?要想實現直接列印的功能,我們需要用到.Net提供的2個物件,LocalReport和PrintDocument。LocalReport物件負責載入一個報表檔案生成實際的報表並將報表按照知道的格式輸出,PrintDocument物件負責將LocalReport的輸出內容傳送到印表機列印。具體的實現步驟如下:

Step 1: 宣告一個LocalReport物件並載入一個報表檔案(假定我們已經設計好一個報表檔案,名稱為PrintMe.rdlc)。

   1: LocalReport report = new LocalReport();
   2: //設定需要列印的報表的檔名稱。
   3: report.ReportPath = @"c:\PrintMe.rdlc";
   4: //建立要列印的資料來源
   5: ReportDataSource source = new ReportDataSource(SourceTalbe.TableName, SourceTalbe);
   6: report.DataSources.Add(source);
   7: //重新整理報表中的需要呈現的資料
   8: report.Refresh();

Step 2: 將報表的內容輸出為指定格式的資料流。

   1: string deviceInfo =
   2:   "" +
   3:   "  EMF" +
   4:   "  8.5in" +
   5:   "  11in" +
   6:   "  0.25in" +
   7:   "  0.25in" +
   8:   "  0.25in" +
   9:   "  0.25in" +
  10:   "";
  11: Warning[] warnings;
  12: //將報表的內容按照deviceInfo指定的格式輸出到CreateStream函式提供的Stream中。
  13: report.Render("Image", deviceInfo, CreateStream, out warnings);

這裡使用LocalReport物件的Render方法,將報表的內容輸出到指定的資料流(Stream)中。Render方法的第一個引數指定輸出的流的格式,這裡指定為Image格式(圖形格式);第二個引數為一個XML格式的字串,用來描述輸出格式的詳細資訊;第三個引數是一個回撥函式(CreateStreamCallback委託型別),你需要為這個引數宣告一個函式,Render方法會將報表的內容輸出到這個函式返回的Stream物件的例項中,這個函式看上去類似下面的宣告

   1: //宣告一個Stream物件的列表用來儲存報表的輸出資料
   2: //LocalReport物件的Render方法會將報表按頁輸出為多個Stream物件。
   3: private List<Stream> m_streams;
   4: //用來提供Stream物件的函式,用於LocalReport物件的Render方法的第三個引數。
   5: private Stream CreateStream(string name, string fileNameExtension,
   6:   Encoding encoding, string mimeType, bool willSeek)
   7: {
   8:     //如果需要將報表輸出的資料儲存為檔案,請使用FileStream物件。
   9:     Stream stream = new MemoryStream();
  10:     m_streams.Add(stream);
  11:     return stream;
  12: }

你可以使用這個函式的引數執行更多的操作,具體內容請參考CreateStreamCallback委託

第四個引數用來輸出報表處理過程中產生的警告資訊。

Step 3: 使用PrintDocument物件執行列印操作。

   1: //用來記錄當前列印到第幾頁了
   2: private int m_currentPageIndex;
   3:  
   4: private void Print()
   5: {
   6:     m_currentPageIndex = 0;
   7:  
   8:     if (m_streams == null || m_streams.Count == 0)
   9:         return;
  10:     //宣告PrintDocument物件用於資料的列印
  11:     PrintDocument printDoc = new PrintDocument();
  12:     //指定需要使用的印表機的名稱,使用空字串""來指定預設印表機
  13:     printDoc.PrinterSettings.PrinterName = "";
  14:     //判斷指定的印表機是否可用
  15:     if (!printDoc.PrinterSettings.IsValid)
  16:     {
  17:         MessageBox.Show("Can't find printer");
  18:         return;
  19:     }
  20:     //宣告PrintDocument物件的PrintPage事件,具體的列印操作需要在這個事件中處理。
  21:     printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
  22:     //執行列印操作,Print方法將觸發PrintPage事件。
  23:     printDoc.Print();
  24: }

具體的PrintPage事件處理程式如下:

   1: private void PrintPage(object sender, PrintPageEventArgs ev)
   2: {
   3:     //Metafile物件用來儲存EMF或WMF格式的圖形,
   4:     //我們在前面將報表的內容輸出為EMF圖形格式的資料流。

m_streams[m_currentPageIndex].Position = 0;

5: Metafile pageImage = new Metafile(m_streams[m_currentPageIndex]);

   6:     //指定是否橫向列印
   7:     ev.PageSettings.Landscape = false;
   8:     //這裡的Graphics物件實際指向了印表機
   9:     ev.Graphics.DrawImage(pageImage, 0, 0);
  10:     m_streams[m_currentPageIndex].Close();
  11:     m_currentPageIndex++;
  12:     //設定是否需要繼續列印
  13:     ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
  14: }

到此,我們的報表資料就已經列印出來了,在這個過程中,你可以根據需要新增自己的列印邏輯。

 

獲取本地的印表機資訊請參考PrinterSettings

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-670844/,如需轉載,請註明出處,否則將追究法律責任。

相關文章