2007年6月26日火曜日

.NET ReportDocument

先日からちょっと出力するためにクリスタルレポートを使用してプログラムを作っていたのですが
クリスタルレポートでは縦書きにはできないのですね!!

http://www.agtech.co.jp/support/faq/crystal_reports/v11j/all.htmlから抜粋です。
Q:Windows フォーム上で縦書きフォントを使用しても縦書きにならないようですが、何故でしょう?
A:Visual Studio.NET 2003 や Visual Studio 2005 の Windows フォームで縦書きフォント(例:@MS 明朝)を指定した時の不具合になります。既に開発元へは報告済みですが、修正時期は未定です。
この不具合により、縦書きフォントと回転 270 度を組み合わせた 『 縦方向の表示 』 が実現できません

ActiverReportも縦書きには対応していませんでした。

仕方ないのでReportDocumentを使ってみました。
ReportDocumentを使用するのは初めてだったのですが、シンプルで使いやすいかも。
ちょっとした出力ならReportDocumentでも十分ですね。


Public Class Report


 

    Private _PrintData As DataTable


 

    Private _iCurrentDataIndex As Integer = 0


 

    Private _PrintDoc As System.Drawing.Printing.PrintDocument


 


 

    Public Property PrintData() As DataTable

        Get

            Return Me._PrintData

        End Get

        Set(ByVal value As DataTable)

            Me._PrintData = value

        End Set

    End Property


 

    Public Sub New()

        'PrintDocumentを作成します。

        Me._PrintDoc = New System.Drawing.Printing.PrintDocument

        'PrintPageイベントハンドラを追加します。

        AddHandler Me._PrintDoc.PrintPage, AddressOf PrintDoc_PrintPage

        'BeginPrintイベントハンドラを追加します。

        AddHandler Me._PrintDoc.BeginPrint, AddressOf PrintDoc_BeginPage

    End Sub


 

    ''' <summary>

    ''' BeginPrintイベントハンドラ

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

    Protected Sub PrintDoc_BeginPage(ByVal sender As ObjectByVal e As System.Drawing.Printing.PrintEventArgs)

        'カレントデータのインデックスを初期値にします。

        Me._iCurrentDataIndex = 0

    End Sub


 

    ''' <summary>

    ''' PrintPageイベントハンドラ

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

    Protected Sub PrintDoc_PrintPage(ByVal sender As ObjectByVal e As System.Drawing.Printing.PrintPageEventArgs)


 

        '出力文字を作成

        Dim sOutPutText As String = Me._PrintData.Rows(Me._iCurrentDataIndex).Item(0).ToString


 

        '出力位置を作成

        Dim x As Integer = e.MarginBounds.Left

        Dim y As Integer = e.MarginBounds.Top

        x = 100

        y = 100


 

        '出力フォントを作成

        Dim font As New Font("MS Pゴシック"10, FontStyle.Bold)


 

        'StringFormatを作成

        Dim strformat As New StringFormat()

        '--縦書きにする

        'strformat.FormatFlags = StringFormatFlags.DirectionVertical

        '--左詰めにする

        'strformat.Alignment = StringAlignment.Near

        '--右詰めにする

        'strformat.Alignment = StringAlignment.Far


 

        '出力

        e.Graphics.DrawString(sOutPutText, font, Brushes.Black, x, y, strformat)


 

        '破棄

        font.Dispose()

        strformat.Dispose()


 

        'カレントデータのインデックスをカウントアップします。

        Me._iCurrentDataIndex += 1


 

        '次ページがあるかどうかチェックします。

        If Me._iCurrentDataIndex < Me._PrintData.Rows.Count Then

            '--次ページあり

            e.HasMorePages = True

        Else

            '--次ページなし

            e.HasMorePages = False

        End If


 

    End Sub


 

    ''' <summary>

    ''' 印刷します。

    ''' </summary>

    ''' <remarks></remarks>

    Public Sub Print()

        Me._PrintDoc.Print()

    End Sub


 

    ''' <summary>

    ''' プレビューを表示します。

    ''' </summary>

    ''' <remarks></remarks>

    Public Sub ShowPreView()

        'PrintPreviewDialogオブジェクトの作成

        Dim view As New PrintPreviewDialog

        'プレビューするPrintDocumentを設定

        view.Document = Me._PrintDoc

        'プレビューのサイズを設定する

        view.ClientSize = New Size(900500)

        'プレビューズーム

        view.PrintPreviewControl.Zoom = 1

        '印刷プレビューダイアログを表示する

        view.ShowDialog()

    End Sub


 

End Class


面倒なのは総ページ数、出力ページ数、位置合わせ、改ページ処理といったところでしょうか。
PrintPageイベントハンドラないでゴニョゴニョと計算してなんとかなりました。

ハマったのはプレビュー画面から印刷したときです。
プレビューは正常に表示されるのにプレビューから印刷ができません。
プレビューを表示せずに印刷すると正常に印刷されます。
原因は、プレビューを表示する際にPrintPageイベントが発生します。プレビュー画面で印刷ボタンを押すと再度PrintPageイベントが発生します。つまりPrintPageイベントで現在の出力ページをカウントアップしている変数をどこかで初期化しないといけないようです。どこに書くのがよいかわかりませんが、BeginPrintイベントハンドラ内でカウントアップ変数を初期化しました。

0 件のコメント: