2007-06-22

PrintDocumentで改ページ

.NETの System.Drawing.Printing.PrintDocumentを使って帳票印刷するときの話。
 
まず System.Drawing.Printing.PrintDocumentを継承して自前のドキュメントを作成します。
次に PrintPageイベントを処理するイベントハンドラを作成し、イベントハンドラの PrintPageEventArgs.Graphics を使用して実際の描画を行います。
public class MyPrintDocument : System.Drawing.Printing.PrintDocument
{
    // コンストラクタ
    public MyPrintDocument() {
    
        this.PrintPage += 
            new System.Drawing.Printing.PrintPageEventHandler(this.MyPrintDocument_PrintPage);
    }
    
    // 印刷イベント
    private void MyPrintDocument_PrintPage(object sender, PrintPageEventArgs e) {
    
        this.DrawPage(e.Graphics)
    }
    
    // 実際の印刷処理
    private void DrawPage(System.Drawing.Graphics g) {
    
     // Graphicsオブジェクト gに対して描画を行う...
     g.DrawString("hello",  new Font("MS ゴシック", 9.0f), Brushes.Black, 10.0f, 10.0f);
    }
}
 
あとはこれを System.Windows.Forms.PrintDialogあたりに食わせればちゃんと印刷してくれます。
public class MyForm : System.Windows.Forms
{
    private MyPrintDocument doc;
    
    // コンストラクタ
    public MyForm() {
        InitializeComponent();

        this.doc = new MyForm();
    }
          :
    
    // 印刷
    private void PrintDocument() {
        using (PrintDialog pd = new PrintDialog()) {
            pd.Document = this.doc;
            if (pd.ShowDialog() == DialogResult.OK) {
                this.doc.Print();
            }
        }
    }
}
 
前置きが長くなりましたね。
今回はこの MyPrintDocumentに DataTableを持たせてレコードごとに印刷をしようとして悩みました。
 
PrintDocument.PrintPage のヘルプによると、改ページをするためにはPrintPageイベントハンドラのPrintPageEventArgs.HasMorePagesに trueを指定するらしいので、
public class MyPrintDocument : System.Drawing.Printing.PrintDocument
{
    private DataTable myTable;
    
    public DataTable Table {
        get { return this.myTable;  }
        set { this.myTable = value; }
    }
    
    // コンストラクタ
    public MyPrintDocument() {
    
        this.PrintPage += 
            new System.Drawing.Printing.PrintPageEventHandler(this.MyPrintDocument_PrintPage);
    }
        
    // 印刷イベント
    private void MyPrintDocument_PrintPage(object sender, PrintPageEventArgs e) {
    
        for (int i = 0; i < myTable.Rows.Count; i++) {
            DrawPage(e.Graphics, myTable[i]);
            e.HasMorePages = true;
        }
        e.HasMorePages = false;
    }
    
    // 実際の印刷処理
    private void DrawPage(System.Drawing.Graphics g, DataRow myRow) {
    
     g.DrawString(myRow["Comment"],  new Font("MS ゴシック", 9.0f), Brushes.Black, 10.0f, 10.0f);
    }
}
 
うまく動きません(笑 (1ページ目しか出ないよ...)
 
PrintPageEventArgs.HasMorePagesを trueにすることで改ページ記号のようなものを出力してくれるのだと思っていたのですが、どうやら違ったようです。
 
いろいろ調べた結果、PrintPageEventArgs.HasMorePagesに trueをセットして一度 PrintDocument.PrintPageを抜けてやるのが正解だったみたいです。
public class MyPrintDocument : System.Drawing.Printing.PrintDocument
{
    private DataTable myTable;
    private int       pageIndex;
    
    public DataTable Table {
        get { return this.myTable;  }
        set { this.myTable = value; }
    }
    
    // コンストラクタ
    public MyPrintDocument() {
    
     this.pageIndex = 0;
    
        this.PrintPage += 
            new System.Drawing.Printing.PrintPageEventHandler(this.MyPrintDocument_PrintPage);
    }
    
    // 印刷イベント
    private void MyPrintDocument_PrintPage(object sender, PrintPageEventArgs e) {
        DrawPage(e.Graphics, myTable[this.pageIndex])
        if (this.currentPage < this.myTable.Rows.Count - 1) {
            this.pageIndex ++;
            e.HasMorePages = true;
        } else {
            e.HasMorePages = false;
        }
    }
    
    // 実際の印刷処理
    private void DrawPage(System.Drawing.Graphics g, DataRow myRow) {
    
     g.DrawString(myRow["Comment"],  new Font("MS ゴシック", 9.0f), Brushes.Black, 10.0f, 10.0f);
    }
}
 
分かってしまえば何ともない事ですが、ヘルプの解説だけだとすぐに理解できませんでした。
 

0 件のコメント: