none
Microsoft.Reporting.WebFormsを利用したドキュメント印刷について(ASP.NET) RRS feed

  • 質問

  • Microsoft.ReportViewer.WebFormsのReportViewを使用して、印刷を行おうと考えています。
    webform上にReportViewを表示し、ドキュメントのプレビューの表示も行えるのですが、
    肝心のクライアント端末での印刷を行うことができませんどうすればよいのでしょうか?
    Reportクラスにはプリントメソッドがいないため、直接印字できずにいます。

    環境
    VS2005 Proffesional + .NET 3.5

    現在の印刷ソースです。
    現在の状態だと、サーバーの規定のプリンタに対して印刷を行っています。

    これをクライアントに対して実行できればよいのですが・・・・。

    よろしくお願いいたします。


    Public Class Demo
        Implements IDisposable
    
        Private m_currentPageIndex As Integer
        Private m_streams As IList(Of Stream)
    
        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>42.4cm</PageWidth>" + _
              "  <PageHeight>30.1cm</PageHeight>" + _
              "  <MarginTop>1.5cm</MarginTop>" + _
              "  <MarginLeft>1cm</MarginLeft>" + _
              "  <MarginRight>1cm</MarginRight>" + _
              "  <MarginBottom>1.5cm</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()
            If m_streams Is Nothing Or m_streams.Count = 0 Then
                Return
            End If
    
            Dim printDoc As New PrintDocument()
            If Not printDoc.PrinterSettings.IsValid Then
                Dim msg As String = "Can't find printer"
                Console.WriteLine(msg)
                Return
            End If
            AddHandler printDoc.PrintPage, AddressOf PrintPage
    
            Dim prs As PrinterSettings
            Dim pps As PaperSize
            prs = New PrinterSettings
    
            For Each pps In prs.PaperSizes
                If pps.PaperName.IndexOf("A4") > -1 Then
                    prs.DefaultPageSettings.PaperSize = pps
                    prs.DefaultPageSettings.Landscape = True
                    Exit For
                End If
            Next
            printDoc.PrinterSettings = prs
            printDoc.DocumentName = "帳票1"
            printDoc.Print()
    
        End Sub
    
        Public Sub Run(ByVal report1 As LocalReport)
            Export(report1)
    
            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
    
    End Class
    


    2009年10月15日 5:45

回答

  • ReportView は使ったことがないのでハズレかもしれませんが・・・(ハズレだったらすみません)

    表題に ASP.NET と書いてあったので、ASP.NET ベースの Web アプリ開発の話で、サーバー
    は IIS、クライアントは IE など普通のブラウザを使用すると理解してレスします。

    > 現在の状態だと、サーバーの規定のプリンタに対して印刷を行っています。

    コードを見ると、PrintDocument など Windows アプリ用のコントロールを用いているようですが、
    それを Web アプリに組み込んでいるのですよね? それで、サーバーに接続されたプリンタには
    印刷できているということですよね?

    > これをクライアントに対して実行できればよいのですが・・・・。

    そうだとすると、その Web アプリに実装した PrintPage メソッド等を用いてクライアントのプリンタ
    で印刷するのは不可能です。(直接サーバーにクライアントのプリンタを接続すれば話は別です
    が・・・)

    Web アプリのプログラムはサーバー側だけで動いていることは理解されているでしょうか。(PrintPage
    メソッドの実行で、サーバーからクライアントのプリンタには何の信号も送られないということです)

    ごく普通に、ブラウザの[ファイル]→[印刷]を操作してブラウザに表示された結果を印刷してもらうの
    はダメなんですか?

    または、もし PDF に加工できるのなら、PDF ファイルをダウンロードしてもらい、それを Adobe Reader
     などを使って表示・印刷してもらうという方法もあると思います。

    • 回答としてマーク 菊地俊介 2009年11月2日 9:25
    2009年10月15日 12:37
  • > 好奇心ゆえのチャレンジです。

    それならそうと一番最初に書いておいていただきたかったのですが・・・

    > それを見えないウィンドウに表示し、Document.Printメソッドを実行し、完了
    > 後閉じることで実現できないかを考えています。

    ブラウザの[ファイル]→[印刷]を操作するのと、JavaScript の print を実
    行するのは同じことです。

    従って、まず、普通に[ファイル]→[印刷]で望みの内容が印刷できるページ
    を作って、そのページの一番最後に print して close する JavaScript を追加
    し、そのページを open してやるような仕組みを作れば可能だと思います。

    チャレンジするなら、是非その範囲を JavaScript にも広げてみてください。

    • 回答としてマーク 菊地俊介 2009年11月2日 9:25
    2009年10月20日 12:28

すべての返信

  •     Private Sub test(ByVal rpt As Report)
            Dim warnings As Warning() = Nothing
            Dim streamids As String() = Nothing
            Dim mimeType As String = Nothing
            Dim encoding As String = Nothing
            Dim extension As String = Nothing
            Dim deviceInfo As String
            Dim bytes As Byte()
    
            deviceInfo = _
         "<DeviceInfo><SimplePageHeaders>False</SimplePageHeaders></DeviceInfo>"
    
            'XML、NULL、CSV、IMAGE、PDF、HTML4.0、HTML3.2、MHTML、EXCEL
            bytes = rpt.Render("PDF", deviceInfo, _
          mimeType, encoding, extension, streamids, warnings)
    
            Response.Clear()
            Response.OutputStream.Write(bytes, 0, bytes.Length)
        End Sub
    追記です。
    途中まで考えているコードを記述します。

    PDFを直接表示します。

    プリントも同時にできればよいのですが・・・。


    2009年10月15日 6:17
  • ReportView は使ったことがないのでハズレかもしれませんが・・・(ハズレだったらすみません)

    表題に ASP.NET と書いてあったので、ASP.NET ベースの Web アプリ開発の話で、サーバー
    は IIS、クライアントは IE など普通のブラウザを使用すると理解してレスします。

    > 現在の状態だと、サーバーの規定のプリンタに対して印刷を行っています。

    コードを見ると、PrintDocument など Windows アプリ用のコントロールを用いているようですが、
    それを Web アプリに組み込んでいるのですよね? それで、サーバーに接続されたプリンタには
    印刷できているということですよね?

    > これをクライアントに対して実行できればよいのですが・・・・。

    そうだとすると、その Web アプリに実装した PrintPage メソッド等を用いてクライアントのプリンタ
    で印刷するのは不可能です。(直接サーバーにクライアントのプリンタを接続すれば話は別です
    が・・・)

    Web アプリのプログラムはサーバー側だけで動いていることは理解されているでしょうか。(PrintPage
    メソッドの実行で、サーバーからクライアントのプリンタには何の信号も送られないということです)

    ごく普通に、ブラウザの[ファイル]→[印刷]を操作してブラウザに表示された結果を印刷してもらうの
    はダメなんですか?

    または、もし PDF に加工できるのなら、PDF ファイルをダウンロードしてもらい、それを Adobe Reader
     などを使って表示・印刷してもらうという方法もあると思います。

    • 回答としてマーク 菊地俊介 2009年11月2日 9:25
    2009年10月15日 12:37
  • SurferOnWww様いつも回答していただきましてありがとうございます。
    また、回答が遅くなってしまいまして申し訳ありませんでした。

    >現在の状態だと、サーバーの規定のプリンタに対して印刷を行っています。
    とのご指摘ですが、そのとおりです。

    サーバーをプリンタサーバーのように運用するのであれば、プリンタ選択機能を追加すれば十分かもしれません。

    >そうだとすると、その Web アプリに実装した PrintPage メソッド等を用いてクライアントのプリンタ
    で印刷するのは不可能です。

    JavaScriptを組み合わせることで実現できないかを検討していますが、JavaScriptはさっぱりわからなくて・・・。

    2件目に投稿させていただいたソースと、JavaScriptのDocument.Printメソッドを組み合わせることで、
    何とかならないかを考えています。

    bytes = rpt.Render("PDF", deviceInfo, _
          mimeType, encoding, extension, streamids, warnings)

    によって、"PDF"を別のオプションにする必要ありますが、bytes()にはHTMLが格納されているわけですから。
    それを見えないウィンドウに表示し、Document.Printメソッドを実行し、完了後閉じることで実現できないかを
    考えています。



    >ごく普通に、ブラウザの[ファイル]→[印刷]を操作してブラウザに表示された結果を印刷してもらうの
    はダメなんですか?

    確かに十分と考えています。
    好奇心ゆえのチャレンジです。
    2009年10月20日 0:20
  • > 好奇心ゆえのチャレンジです。

    それならそうと一番最初に書いておいていただきたかったのですが・・・

    > それを見えないウィンドウに表示し、Document.Printメソッドを実行し、完了
    > 後閉じることで実現できないかを考えています。

    ブラウザの[ファイル]→[印刷]を操作するのと、JavaScript の print を実
    行するのは同じことです。

    従って、まず、普通に[ファイル]→[印刷]で望みの内容が印刷できるページ
    を作って、そのページの一番最後に print して close する JavaScript を追加
    し、そのページを open してやるような仕組みを作れば可能だと思います。

    チャレンジするなら、是非その範囲を JavaScript にも広げてみてください。

    • 回答としてマーク 菊地俊介 2009年11月2日 9:25
    2009年10月20日 12:28
  • 皆様、こんにちは。

    SurferOnWwwさん、いつも回答ありがとうございます。

    issei1102さん、フォーラムのご利用ありがとうございます。
    有用な情報と思われたため、SurferOnWwwさんの回答へ回答マークをつけさせていただきました。

    今後ともフォーラムをよろしくお願いします。
    それでは!
    2009年11月2日 9:27