7

私のアプリケーションは請求書を印刷する必要があり、データベースから請求書を取得し、請求書に関する情報を大きな文字列 (行、列などに伝える) に挿入します。この後、文字列をプリンターに送信する準備が整います。

私の問題は、大きな文字列にいくつかの ESC/P コマンド/文字を入れる必要があることです。

私はこのようなことをしようとしました:

        char formFeed = (char)12;
        Convert.ToChar(12);

        MyBigString.Insert(10, formFeed);

これにより、10行目でFormFeedが実行されますが、これは機能しません

注: MybigString を一度にプリンターに送信します。

コードを機能させるには、データを 1 行ずつプリンターに送信する必要がありますか?

助けてくれてありがとう。

PS: 申し訳ありませんが、私の英語については、私は英語を (まだ) 話せないブラジルの開発者です。

4

3 に答える 3

6

私は自分でやらなければならなかった後、以前にこれについてブログを書きました。私自身のホーンを大声で鳴らしすぎないようにしますが、プリンタでの複雑なイメージ コマンドについて説明しているので、そのエントリを読むことをお勧めします。それが分かればなんでも印刷できる!

(小売店のレシート プリンターで使用される ESC/POS について話しますが、議論のセマンティクスは、古いドット マトリックス言語である ESC/P にも当てはまります。)

要するに、 a のBinaryWriter代わりに a を使用しstringないと、プリンターに送られる途中で特定の文字が間違ったエンコーディングで「焼き付けられる」ため、絶望的に混乱することになります (私が行ったように)。(これについては私を信じてください! StringBuilderESC/POS で話そうとしているときに a を使用しないでください。)

Write(string)のオーバーロードを使用しないように注意してくださいBinaryWriter。これは、文字列の長さをストリーム内のバイトとして先頭に追加するためです。これは、必要なものではありません。(私も同じプロジェクトで難しい方法を学んだ後、それについてブログに書きました。)

次に、いくつかのコードを使用してbyte、から取得した配列を、BinaryWriterP/Invoking によって直接プリンターに送信します。

private static void Print(string printerName, byte[] document)
{
    NativeMethods.DOC_INFO_1 documentInfo;
    IntPtr printerHandle;

    documentInfo = new NativeMethods.DOC_INFO_1();
    documentInfo.pDataType = "RAW";
    documentInfo.pDocName = "Bit Image Test";

    printerHandle = new IntPtr(0);

    if (NativeMethods.OpenPrinter(printerName.Normalize(), out printerHandle, IntPtr.Zero))
    {
        if (NativeMethods.StartDocPrinter(printerHandle, 1, documentInfo))
        {
            int bytesWritten;
            byte[] managedData;
            IntPtr unmanagedData;

            managedData = document;
            unmanagedData = Marshal.AllocCoTaskMem(managedData.Length);
            Marshal.Copy(managedData, 0, unmanagedData, managedData.Length);

            if (NativeMethods.StartPagePrinter(printerHandle))
            {
                NativeMethods.WritePrinter(
                    printerHandle,
                    unmanagedData,
                    managedData.Length,
                    out bytesWritten);
                NativeMethods.EndPagePrinter(printerHandle);
            }
            else
            {
                throw new Win32Exception();
            }

            Marshal.FreeCoTaskMem(unmanagedData);

            NativeMethods.EndDocPrinter(printerHandle);
        }
        else
        {
            throw new Win32Exception();
        }

        NativeMethods.ClosePrinter(printerHandle);
    }
    else
    {
        throw new Win32Exception();
    }
}

幸運を!

于 2010-05-14T21:42:07.353 に答える
5

ネイティブ コマンド言語を使用して、プリンター ドライバーをバイパスし、プリンターを直接制御するシナリオがサポートされています。P/Invoke については、このKB 記事で詳しく説明されています。

よろしいですか?控えめに言っても、通常は低コストの POS サーマルまたはマトリックス プリンターでのみ試みられることは珍しくありません。PrintDocument.PrintPage の仕組みが気に入らない場合は、このスレッドで私のコードを検討してください。FormFeed メソッドに注意してください。

于 2010-05-14T22:05:40.130 に答える
0

"....OpenPrinter(printerName.Normalize(), out printerHandle, IntPtr.Zero)..."

IntPtr.Zero も raw に設定する必要があるかもしれません。

プリンター、特にドット マトリックスは、DOS、CMD メソッドを使用して直接実行できます。これは、基本的な ESC/0x1b コマンド コードを使用してプリンターを制御することもできます。. 等

windowos/graphic のように、openprinter(,,printer_defaults) printer_defaults と doc-inf を設定することで、graphics と raw にすることができます。win32 SDK のリファレンスを参照してください。

生の印刷では、ESC コマンド (プリンターのマニュアルの詳細を参照) を使用して、Windows ドライバーと同じようにグラフィックを印刷できます。

raw で印刷する場合、oxoc(formfeed) 0x0doa(0x0a、0x0d、\n または改行) などの最初の 20 個の ascii のいずれかを追加するだけです。各プリンターにはわずかな ESC コマンドの違いがありますが、マスター ESC コマンドを使用すると、ほとんどのドットに対して罰金が科せられます。マトリックス類似。

raw モードの例として、 FormFeed 、 \n & \r

char cFormfeed=0x0c; // または \f

char cStr[]="1=テキスト,......@\n2=テキスト.....\r\f3=テキスト......."; // cFormfeed を使用せずに \f を使用すると解決できます

cStr > lpt1; // プリンタの dos または cmd メソッドへの出力。当然のことながら、lpt1 を利用可能にする必要があります。

プリントアウトになります

先頭ページ

1=テキスト,......@

2=テキスト.....

2ページ目は

3=テキスト.......

これが助けになることを願っています、頑張ってください。

于 2013-04-19T12:46:42.750 に答える