
.NETからPDFドキュメントを印刷するというトピックを続けます。
原則として、ドキュメントの印刷は難しくなく、既製のソリューションもあります。 一部の印刷オプションを管理する必要がある場合、問題が発生します。 私の練習では、ミニ印刷を実装するタスクに直面しました-ドキュメントを印刷するときに、次のシートを取り出すトレイを指定する必要がある場合、つまり テンプレートでドキュメントを印刷します。 既製の解決策を見つけようとして最初に試みたものの、適切なものを見つけることができなかったため、自分で解決策を見つけ始めました。
最初に思いついたのは、ビットマップイメージでドキュメントページをレンダリングし、標準の.NETツールを使用してそれらを印刷することでした。 PrintDocumentクラスを使用すると、プラークでプリンタートレイを変更できます。 以前の記事でこのアプローチについて書いた

最初のアプリケーションが機能し始めるとすぐに、このソリューションの重大な欠点が発見されました。 PDFを画像に変換した後、ファイルが巨大なサイズに膨らんだため、印刷に非常に長い時間がかかりました。 同時に、印刷量は増え続け、私は別の方法を見つけることにしました。
Hewlett-Packard PCLプリンター制御言語は私を助けてくれました。 インターネット上では、Runetはもちろんのこと、その情報は非常に少ないことが判明しました。 わかりやすい説明は、公式仕様のみです。 すぐに言ってやった。 彼はHP JetAsmからHEXエディター+ユーティリティを起動し、PCLの研究を開始しました。 悪魔は描かれているほどひどいものではありません。 言語はバイナリですが、非常にシンプルで論理的です。 その結果、数時間後にテストアプリケーションを作成しました。 そして、それが便利で面白いと思うかもしれない皆のために、PCLについて少しお話しします。

ウィキペディアによると:
「PCL(英語のプリンターコマンド言語)は、Hewlett-Packardが開発したプリンター制御言語です。 最初のバージョンでは、ASCII文字を印刷するための一連のコマンドでしたが、現在、バージョンPCL6およびPCL-Xでは、カラーでの印刷や画像の印刷が可能になりましたが、この言語はMicrosoft WindowsおよびHP-UX以外ではほとんど使用されません ''
これはバイナリ言語とスタック言語であると自分で追加します。着信データはスタックにプッシュされ、演算子が表示されると、データは演算子引数としてスタックから取得されます。
PCLの公式説明はインターネット上にあります。 また、HP JetAsmの無料ユーティリティは、PCLファイルの内容を理解および検証するのに役立ちます。 それと他の有用なファイルは、登録なしで公式サイトから取得できます。 これを行うには、リンクをクリックし、[SDK]-> [公開]をクリックして、目的のファイルを見つけます。
古き良きGhostScript

最初に、どこかでpclファイルを取得する必要があります。 前回の記事で知られている GhostScriptユーティリティは、すぐにPDFをPCLに変換できます。 次のコマンドでこれを行うことができます。
gswin64c.exe -o example.pcl -sDEVICE=pxlmono example.pdf
したがって、不必要な移動をせずに、RawDataとしてプリンターに送信できるPCLファイルを取得しました。
ただし、ドキュメントを印刷するだけでなく、プリンタトレイに配布する必要がある場合(たとえば、ある種のテンプレートに従って)、生成されたPCLファイルをそれに応じて変更する必要があります。 これを行うには、彼のデバイスに対処する必要があります。
そのため、HEXエディターでPCLファイルを開きます。 WinHexを使用しました 。

この言語には階層構造があります。 しかし、最初に、デバイスはPCLデータストリームがさらに送信されることを理解する必要があります。これには、初期化ラインが役立ちます。
PCLステートメントの階層は次のとおりです。
<> <> </> <> </> <> </> </>
この場合、いくつかのセッションがあり、ページ要素が他の要素にネストされている場合があります。
順番に始めましょう

ストリームの先頭は標準の文字列であると既に述べました。 デバイスは、PXLXL形式のデータがさらに送信されることを決定します。 初期化文字列の長さは99バイトです。

次に、PCLデータストリームが開始されます。 ドキュメントの要素の記述を開始するには、セッションを開く必要があります。これには、コード0x41のBeginSessionコマンドがあります。 これおよび他のコマンドコードは、マニュアルに記載されています。 1つのファイルに1つまたは複数のセッションを含めることができますが、多くの場合1つです。

また、BeginSessionに渡す必要のある引数も調べます。
引数の構造は次のとおりです。[データ型] [データ] [属性型] [属性]
UnitsPerMeasure-ワークスペースxとyの解像度。データ型はuint16_xy-2つのダブルバイトワードの構造です。

測定 -作業する測定単位の列挙{eInch | eMillimeter | eTenthsOfAMillimeter}

ErrorReportは、デバイスがエラーを処理する方法を決定する列挙です。

開始ページ
ページは同じ方法で初期化されます。 両面モードを設定し 、 用紙を取り出すトレイを指定できるのは、 BeginPageオペレーターです 。
BeginPage演算子の引数を調べてみましょう。
向き -ページの向き。値を取ることができます{ePortraitOrientation | eLandscapeOrientation | eReversePortrait | eReverseLandscape}

MediaSize-ページサイズ、列挙、eA4Paperの場合。 タイプMediaSizeの代わりに、CustomMediaSize、CustomMediaSizeUnitsがあります。

MediaSourceはペーパーソースです。
0-eDefaultSource
1-eAutoSelect
2-eManualFeed
3-eMultiPurposeTray
4-eUpperCassette
5-eLowerCassette
6-eEnvelopeTray
7-eThirdCassette
1-248-外部トレイ
MediaSourceの代わりに、ソースの名前を持つMediaTypeが存在する場合があります 。

SimplexPageMode-単一ページ印刷モード、eSimplexFrontSide = 0に設定する必要があります
SimplexPageModeの代わりに、DuplexPageModeまたはDuplexPageSideを指定できます。
DuplexPageSide -1枚のシートに1ページを印刷しますが、シートのどちら側に{eFrontMediaSide | eBackMediaSide}
DuplexPageMode -2つの連続したページが同じシートの両面に印刷されます。値を設定できますeDuplexHorizontalBinding = 0およびeDuplexVerticalBinding = 1

そして、これはすべてコード0x43のBeginPageコマンドで終了します

原則が明確であることを願っています。 これは、アプリケーションを開発し、PCLファイルを変更して、両面-シンプレックスモードを変更し、用紙を取り出すトレイを指定するのに十分です。 これを行うには、ファイル内の次のページのアナウンスを見つけて、必要に応じて変更する必要があります。
次の記事では、パターンPDFでのPDF印刷デモアプリケーションの実装について説明します。
不正確な点がある場合、または詳細が必要な場合は、コメントにこれについて書いてください。
一連の記事:
ラスターアプローチ
ベクトルアプローチ理論
ベクトル実践アプローチ