none
報表列印的系統選擇 RRS feed

  • 問題

  • 1. vb 提供有 PrintDocument1、CrystalReport.rpt、Report1.rdlc 等系統可用於列印報表。
    2.我要列印,須不斷應用迴圈篩選記錄、反覆執行統計計算的繁雜報表。
    3.請問 vb 的三種報表系統中,哪類最適合自行編寫迴圈程式碼以列印繁雜報表。
    4.vb 的三種報表是否有其適用對象,我應該如何去決定,使用哪種報表系統來列印報表?

    敬請指導。


    chian
    2009年2月5日 下午 02:23

解答

  • 唔~
    我自己的程式碼分太細,很難跟你解釋,依順序稍微說一下,這要測一陣子的經驗,才知道細部的差異。

    1. 建立記憶體中的 EMF (這段封裝在自己的 EMF 類別初始化中)
    若有印表機:
    ' 參照預設印表機建立  
    m_PageUnit = System.Drawing.GraphicsUnit.Document  
     
    若無印表機參照螢幕:
    ' 自定解析度  
    m_PageUnit = System.Drawing.GraphicsUnit.Pixel  
     

    2. 繪圖時,不同繪圖程式碼都參照上面類別建立出來的單位,emf.PageUnit 會讀取上面的私有變數 m_PageUnit:
    grfx.PageUnit = emf.PageUnit 

    3. 自己的繪圖程式碼,所以這邊要自己畫報表。
    省略。

    4. 不管是預覽列印、列印都是呼叫 PrintPage ,這部分我放在 Main Form 內,因為我不想到處都放列印控制項,一放還要放三個,所以我自己是在各子視窗畫圖,再由 Main Form 取得目前作用中子視窗的文件當作 PrintObject,若是畫在螢幕上的話,簡單點可以用 PictureBox.Image = 上面畫出來的圖檔,我自己還有縮放,所以是用 Graphics.DrawImage 來畫顯示範圍。
    With sender  
        ' ...  
        ' 計算列印區域  
        Dim rectPrintingArea As RectangleF = GetPrintPageArea(.DefaultPageSettings)  
     
        Select Case TypeName(PrintObject)  
            Case "Image""Metafile""Bitmap" 
                Dim img As Image = PrintObject  
                Dim ZoomScale As Double = 1  
                Dim destRect As RectangleF  
                PrintDoc.DocumentName = Application.ProductName & "_fig" 
     
                ' 計算縮放區域  
                With rectPrintingArea  
                    ' ...  
                End With 
     
                e.Graphics.DrawImage(img, destRect)  
                e.HasMorePages = False 
            Case "String" 
                ' ...  
        End Select 
    End With 
    If e.HasMorePages Then 
        PageNumber += 1  
    Else 
        PageNumber = 0  
    End If 

    你做報表,不需要計算縮放,但是你報表的圖卻是要讓 HasMorePages 為 True ,持續到最末頁為止。有很多段可以不管,例如 DocumentName 只是顯示在列印管理員裡面的名稱,部分虛擬印表機會參照,不設定也沒啥關係。

    出血取得部分,我又分到另一個模組:
    Public Function GetPrintPageArea(ByVal docPageSetting As System.Drawing.Printing.PageSettings) As System.Drawing.RectangleF  
        ' 計算列印區域  
        Dim rectPrintingArea As RectangleF  
        With docPageSetting  
            ' 初始化包含列印區域矩形界限的區域變數。  
            Dim printSize As Size  
            If .Landscape Then 
                printSize = New Size(.PaperSize.Height - .Margins.Left - .Margins.Right, .PaperSize.Width - .Margins.Top - .Margins.Bottom)  
            Else 
                printSize = New Size(.PaperSize.Width - .Margins.Left - .Margins.Right, .PaperSize.Height - .Margins.Top - .Margins.Bottom)  
            End If 
     
            rectPrintingArea = New RectangleF(.Margins.Left, .Margins.Top, printSize.Width, printSize.Height)  
        End With 
        Return rectPrintingArea  
    End Function 

    自己做滿繁雜的,所以才會有報表控制項這種東西讓開發者省時間。

    更多的先前討論:
    EMF: http://www.google.com.tw/search?hl=zh-TW&q=EMF+site%3Asocial.msdn.microsoft.com%2FForums%2Fzh-TW%2F&meta=&aq=f&oq=
    列印: http://www.google.com.tw/search?hl=zh-TW&q=PrintPage+site%3Asocial.msdn.microsoft.com%2FForums%2Fzh-TW%2F&meta=&aq=f&oq=
    • 已標示為解答 chian 2009年2月16日 上午 07:51
    2009年2月16日 上午 03:20

所有回覆

  • HI,

    PrintDocument是列印功能, 不是報表功能, 要列印多頁時還要自行寫程式控制, 至於CrystalReport和Report都是報表功能, 差別在於一個是Crystal Decision提供的報表功能, 一個是Microsoft自己提供的報表功能, 這三者都能夠處理執行統計計算的繁雜報表

    tihs
    • 已提議為解答 bauannModerator 2009年2月6日 上午 05:25
    • 已標示為解答 Lolota Lee 2009年2月9日 上午 10:39
    • 已取消標示為解答 chian 2009年2月10日 上午 01:46
    2009年2月6日 上午 01:50
  • 1. 感謝說明。
    2. 若要搭配自行編寫程式碼, CrystalReport.rpt、Report1.rdlc 該選用哪項較好。例如要列印繁雜的郵件標籤,應該選用哪項較好。
    3. 我試著用PrintDocument1列印郵件標籤,報表紙為連張的點陣式印表紙,結果前數張標籤文字還能列印在標籤頁內,多印幾張之後,文字列就會失準,以至到最後會有多列字串沒印在標籤頁內,不知這是何故。

    請再指導。謝謝。
    chian
    2009年2月6日 上午 07:45
  • 精準列印時,要取得印表機出血、印表機解析度換算後列印。

    單位用 GraphicUnit.Document 可達最小,或是先用印表機解析度畫出 EMF+ 後,再用 Graphic.DrawImage 畫到 PrintDoc 上,這樣位置才不會因為進位誤差導致明顯偏移。

    我自己慣用是先用 EMF 畫在記憶體,再丟到螢幕顯示做預覽或是列印,開發階段時,建議你加畫標籤的框框,這樣印出來時,比較好比對誤差偏移量。

    至於套用報表軟體,通常很難做精準列印,因為報表軟體比較針對內容做最佳化顯示。

    2009年2月6日 上午 08:59
  • 1.感謝說明,這對我非常有用,謝了。
    2.是否可以針對您的說明,附個範例供參考,我被標籤列印問題搞得不知如何是好。

    敬請再指導,謝謝。
    chian
    2009年2月6日 下午 01:32
  • HI,

    列印郵件標籤的話, CrystalReport.rpt比Report1.rdlc方便, 因為有現成的範本可以套用

    tihs
    2009年2月8日 上午 03:33
  • 1. 感謝指導。
    2. 由於我需要作精準列印,因此請指導如何做印表機出血等設定或是 心冷熱情熄 前輩所介紹的各項設定。

    敬請再指導,謝了。

    chian
    2009年2月8日 上午 09:02
  • 唔~
    我自己的程式碼分太細,很難跟你解釋,依順序稍微說一下,這要測一陣子的經驗,才知道細部的差異。

    1. 建立記憶體中的 EMF (這段封裝在自己的 EMF 類別初始化中)
    若有印表機:
    ' 參照預設印表機建立  
    m_PageUnit = System.Drawing.GraphicsUnit.Document  
     
    若無印表機參照螢幕:
    ' 自定解析度  
    m_PageUnit = System.Drawing.GraphicsUnit.Pixel  
     

    2. 繪圖時,不同繪圖程式碼都參照上面類別建立出來的單位,emf.PageUnit 會讀取上面的私有變數 m_PageUnit:
    grfx.PageUnit = emf.PageUnit 

    3. 自己的繪圖程式碼,所以這邊要自己畫報表。
    省略。

    4. 不管是預覽列印、列印都是呼叫 PrintPage ,這部分我放在 Main Form 內,因為我不想到處都放列印控制項,一放還要放三個,所以我自己是在各子視窗畫圖,再由 Main Form 取得目前作用中子視窗的文件當作 PrintObject,若是畫在螢幕上的話,簡單點可以用 PictureBox.Image = 上面畫出來的圖檔,我自己還有縮放,所以是用 Graphics.DrawImage 來畫顯示範圍。
    With sender  
        ' ...  
        ' 計算列印區域  
        Dim rectPrintingArea As RectangleF = GetPrintPageArea(.DefaultPageSettings)  
     
        Select Case TypeName(PrintObject)  
            Case "Image""Metafile""Bitmap" 
                Dim img As Image = PrintObject  
                Dim ZoomScale As Double = 1  
                Dim destRect As RectangleF  
                PrintDoc.DocumentName = Application.ProductName & "_fig" 
     
                ' 計算縮放區域  
                With rectPrintingArea  
                    ' ...  
                End With 
     
                e.Graphics.DrawImage(img, destRect)  
                e.HasMorePages = False 
            Case "String" 
                ' ...  
        End Select 
    End With 
    If e.HasMorePages Then 
        PageNumber += 1  
    Else 
        PageNumber = 0  
    End If 

    你做報表,不需要計算縮放,但是你報表的圖卻是要讓 HasMorePages 為 True ,持續到最末頁為止。有很多段可以不管,例如 DocumentName 只是顯示在列印管理員裡面的名稱,部分虛擬印表機會參照,不設定也沒啥關係。

    出血取得部分,我又分到另一個模組:
    Public Function GetPrintPageArea(ByVal docPageSetting As System.Drawing.Printing.PageSettings) As System.Drawing.RectangleF  
        ' 計算列印區域  
        Dim rectPrintingArea As RectangleF  
        With docPageSetting  
            ' 初始化包含列印區域矩形界限的區域變數。  
            Dim printSize As Size  
            If .Landscape Then 
                printSize = New Size(.PaperSize.Height - .Margins.Left - .Margins.Right, .PaperSize.Width - .Margins.Top - .Margins.Bottom)  
            Else 
                printSize = New Size(.PaperSize.Width - .Margins.Left - .Margins.Right, .PaperSize.Height - .Margins.Top - .Margins.Bottom)  
            End If 
     
            rectPrintingArea = New RectangleF(.Margins.Left, .Margins.Top, printSize.Width, printSize.Height)  
        End With 
        Return rectPrintingArea  
    End Function 

    自己做滿繁雜的,所以才會有報表控制項這種東西讓開發者省時間。

    更多的先前討論:
    EMF: http://www.google.com.tw/search?hl=zh-TW&q=EMF+site%3Asocial.msdn.microsoft.com%2FForums%2Fzh-TW%2F&meta=&aq=f&oq=
    列印: http://www.google.com.tw/search?hl=zh-TW&q=PrintPage+site%3Asocial.msdn.microsoft.com%2FForums%2Fzh-TW%2F&meta=&aq=f&oq=
    • 已標示為解答 chian 2009年2月16日 上午 07:51
    2009年2月16日 上午 03:20