スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

WPFでの印刷

FixedDocumen(固定形式ドキュメント)
WPFで印刷を行うには、印刷対象をSystem.Windows.Documents.FixedDocumentクラスにまとめるところから始める。
と言うか、FixedDocumenにしてしまえば、ほぼ終わりと言ってもいいくらい簡単に印刷できるのだが。

FixedDocumentは、一度に印刷したいすべてのページをセットにしたもので、各ページはPagesプロパティに格納する。
Pagesプロパティは、PageContentのコレクションであり、PageContentクラスはChildプロパティに唯一のFixedPageを持つ。
このFiexdPageが1ページにあたる。

つらつら書くとややこしいが、つまりこんな感じ。
FixedDocument
.Pages(PageContentCollection)
+PageContent(ページ1)
.Child
+FixedPage
+PageContent(ページ2)
.Child
+FixedPage
+PageContent(ページ3)
.Child
+FixedPage
+PageContent(ページ4)
.Child
+FixedPage



FixedPage
上記の通り、複数ページを印刷するには、FixedDpcument.PagesにPageContentをAddしていけばよいわけだが、初めてで重要なのは最初の1ページの印刷を成功させることだ。
FixedPageはSystem.Windows.Controls.UIElementCollection型のChildrenプロパティにCanvasなどパネルをAdd()すればいいだけのお手軽さだが、サイズや余白について知っておかなくては思った通りの印刷物はできない。


FixedPageの仮想デバイスの解像度
FixedPageでは、96DPI(ドット/インチ)がデバイス解像度となっている。
なので、FixedPage.Childrenに設定する為のCanvasに描画オブジェクトを並べる際は、1インチが96pixelだと考えて描画すればよい。
A4の場合、

210 × 297 ミリ(約 8.27 × 約 11.69 インチ)=794 × 1123 pixel

が概ねの描画可能領域の広さになる。※後述
固定形式ドキュメントの考え方として、こうしておけば実際の出力先の解像度が違ったとしても、同じサイズで出力してくれるというわけだ。
具体的には、出力先が120DPIのディスプレイでも、300DPIのプリンタでも、1インチは1インチで描画してくれる。


印刷ダイアログ
アプリに印刷機能を持たせる場合、やはり、印刷ダイアログを出して、プリンタの選択と設定を行う機会を使用者に提供したい。
それを行ってくれるSystem.Windows.Controls.PrintDialogクラスを使用すると、上記で説明したFixedDocumentの印刷までが簡単に行える。
PrintDialog.ShowDialog()メソッドで以下の様な印刷ダイアログが表示される。

PrintDialog.png

あとは、ShouwDialog()がtrueで返ったときに印刷処理を行えばよいのだ。


選択されたサイズと余白の取得
さて、紙に印刷する場合、余白と言うものが存在する。
見やすさの観点から意図的に設ける余白もあるが、ここで注意したいのはプリンタの仕様上の制限として印刷されないという意味での余白もあるという事だ。
つまるところ、見切れることを避けながら正確は位置に正確なサイズで印刷するためには、プリンタから余白の情報を取得したい。
こういう場合、前述のPrintDialogオブジェクトからPageImageableAreaを取得する。

var dPrt = new System.Windows.Controls.PrintDialog();
var area = dPrt.PrintQueue.GetPrintCapabilities(dPrt.PrintTicket).PageImageableArea;


PageImageableAreaには以下のプロパティがある。

ExtentHeight    イメージ可能領域の高さ。
ExtentWidth イメージ可能領域の幅。
OriginHeight 上余白の高さ。
OriginWidth 左余白の幅。


プロパティを取得した後でプリンタの用紙設定を変えない限り、実際の印刷可能領域のサイズは、このPageImageableAreaの値であると考えればよい。
右余白と下余白は明確に値を取得することはできないが、用紙サイズが分かっていればインチに直して96倍し、そこからPageImageableAreaで取得した値を減じれば求めることができるはず。
ちなみに、実際に余白を可能な限り狭く設定して確認すると、大抵のプリンタは右余白は左余白より広いし、下余白は上余白よりかなり広い。これは、(特に下余白が広いのは)機械的な制約も影響しているのだと思う。


まとめ
論よりソース。ここまでの説明を実際に印刷できるソースが以下。

※このソースでビルドと印刷を行うためには、以下の参照を追加しておきます。
ReachFramework
System.Printing

    // 印刷ダイアログを作成。
var dPrt = new PrintDialog();

// 印刷ダイアログを表示して、プリンタ選択と印刷設定を行う。
if (dPrt.ShowDialog() == true)
{
// ここから印刷を実行する。

// 印刷可能領域を取得する。
var area = dPrt.PrintQueue.GetPrintCapabilities().PageImageableArea;

// 上と左の余白を含めた印刷可能領域の大きさのCanvasを作る。
var canv = new Canvas();
canv.Width = area.OriginWidth + area.ExtentWidth;
canv.Height = area.OriginHeight + area.ExtentHeight;

// ここでCanvasに描画する。

/* ここで単ページのVisualを直接印刷する場合、PrintVisual()と言うメソッドもある。
dPrt.PrintVisual(canv, "PrintTest1");
*/

// FixedPageを作って印刷対象(ここではCanvas)を設定する。
var page = new FixedPage();
page.Children.Add(canv);

// PageContentを作ってFixedPageを設定する。
var cont = new PageContent();
cont.Child = page;

// FixedDocumentを作ってPageContentを設定する。
var doc = new FixedDocument();
doc.Pages.Add(cont);

// 印刷する。
dPrt.PrintDocument(doc.DocumentPaginator, "Print1");
}

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

筆者について

SHEN13

Author:SHEN13
近年は、.NET+WPF+SQL Serverを使用した、上流からコーディングも行うPM業務を中心に手掛けています。

仕事のオファー歓迎します。
非公開コメントでどうぞ

アクセスカウンタ
最新記事
カテゴリ

openclose

リンク
検索フォーム
RSSリンクの表示
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。