0

請求書を生成するオプションを備えた PHP Web アプリケーションがあります。問題は、ドラフト モードでドット マトリックス プリンターを使用して請求書を印刷する必要があることです。試してみましたが、通常のプリンターのように大きなフォントで印刷されます。ページと同じ形式で印刷するだけです。

領収書のように印刷する必要があります。PHP で何かをフォーマットする必要がありますか?

4

1 に答える 1

0

raw モードで印刷する必要があると思います。

この問題を完全に解決したとは言いませんが、ここに私の試みを示します。

まず、ドット マトリックス プリンタが接続されているシステム (おそらくポート LPT1) に「汎用/テキストのみ」のドライバが必要です。

第 2 に、プリンターに ESCP コマンドを送信し、php の組み込みプロセスを使用して印刷しないようにする必要があります。

たとえば、135 * 66 文字の配列を作成できます。ここで、135 は通常のページ幅の文字数で、66 は通常の印刷行数です (8-1/2" x 12" 用紙の 24 ピン ドット マトリックス プリンターで)。サイズ)。配列を文字列ではなく文字で埋めるように注意する必要があります。次のように嘘をつきます。

    $GRAND_ARRAY = array();

    $maxCharactersPerLine = 135;
    $maxLines = 66;

    //initialize the array with spaces and the last column of \r\n
    for($i=0; $i<$maxLines; $i++){
        $pos = $i*$maxCharactersPerLine + ($maxCharactersPerLine-1) + $i + 1;
        $value = "\r\n";
        $this->printChars($GRAND_ARRAY, $pos, $value);
    }

    //make an array that fits every one character of the page
    //plus a column for the "next line" character
    $totalCells = $maxCharactersPerLine * $maxLines + $maxLines - 1;

    //what you want to print
    $value = "name:"; //here is a string with 5 characters

    //where you want to print it on the page
    //$line = 2
    //$column = 5
    //consider that array starts at 0 and not 1
    //$pos = ($column - 1) * $maxCharactersPerLine + $line + $column - 2;
    $pos = 275; //position is 5th character in line 2

    //do not just $GRAND_ARRAY[$pos] = $value because you should
    //make sure that every array cell has only one character
    $this->printChars($GRAND_ARRAY, $pos, $value, 1);

    // also included a flag if you want to print only the $limit characters of $newstring
    public function printChars(&$mainArray, $start, $newString, $limit=0){
        $j = $start;
        $charsArray = $this->mb_str_split($newString);
        //$len = mb_strlen($newString, "UTF-8"); //can't remember why not this
        $len = count($charsArray);
        for($i=0; $i<$len; $i++){
            if($limit > 0  &&  $limit < $i){
                return;
            }else{
                $mainArray[$j] = $charsArray[$i];
                $j = $j + 1;
            }
        }
    }


//this I found here on s.o. i think.
public function mb_str_split( $string ) {
    # Split at all position not after the start: ^
    # and not before the end: $
    return preg_split('/(?<!^)(?!$)/u', $string );
}

配列を作成した後、この配列を「汎用/テキストのみ」のドット マトリックスに送信するために、JavaScript 関数と Java アプレットを含むqz-print プラグイン ( https://code.google.com/p/jzebra/ ) を使用しました。クライアントのプリンター。

私が使用するJavaScript関数は次のとおりです。

//just before that, I turn the array into string str.
function printESCP2(str, type, quality, pitch, line_spacing, topOffset, commands) {
    if (notReady()) { return; }

    qz.appendHex("x1Bx40"); //ESC @ for reset settings

    var j = commands.length;
    for(var k=0;k<j;k++){
        console.log(':'+commands[k]);
        qz.appendHex(commands[k]);
    }

    if(topOffset){
        if(topOffset > 0){
            alert("topOffset: "+topOffset);
            for(var k=0; k<topOffset; k++){
                qz.appendHex("x0D"); //CR for carriage return
                qz.appendHex("x0A"); //LF for line feed
            }
        }
    }

    if(quality == <?php echo SettingsPrinter::FONT_QUALITY_LQ; ?>){
        alert("font quality: LQ");
        qz.appendHex("x1Bx78x31"); // ESC x 1 for LQ (31=1)
    }else{
        alert("font quality: draft");
        qz.appendHex("x1Bx78x30"); // ESC x 0 for Draft (30=0)
    }

    if(line_spacing == <?php echo SettingsPrinter::PRINTER_LINE_SPACING_NARROW; ?>){
        //alert("line spacing: narrow (1/8)");
        qz.appendHex("x1Bx30"); //ESC 0 for line spacing minimum (1/8)
    }else{
        //alert("line spacing: normal (1/6)");
        qz.appendHex("x1Bx32"); //ESC 2 for line spacing normal (1/6)
    }

    switch(pitch){
        case '<?php echo SettingsPrinter::FONT_PITCH_10; ?>':
            alert("pitch: 10");
            qz.appendHex("x1Bx50"); //ESC P for pitch 10 cpi
            break;
        case '<?php echo SettingsPrinter::FONT_PITCH_12; ?>':
            alert("pitch: 12");
            qz.appendHex("x1Bx4D"); //ESC M for pitch 12 cpi
            break;
        case '<?php echo SettingsPrinter::FONT_PITCH_15; ?>':
            alert("pitch: 15");
            qz.appendHex("x1Bx67"); // ESC g     for pitch 15 cpi
            break;
        case '<?php echo SettingsPrinter::FONT_PITCH_17; ?>':
            alert("pitch: 17");
            qz.appendHex("x1Bx50"); //ESC P for pitch 10 cpi
            qz.appendHex("x0F"); // SI for condensed resulting in pitch 17 cpi
            break;
        case '<?php echo SettingsPrinter::FONT_PITCH_20; ?>':
            alert("pitch: 20");
            qz.appendHex("x1Bx4D"); //ESC M for pitch 12 cpi
            qz.appendHex("x0F"); // SI for condensed resulting in pitch 20 cpi
            break;
        default:
            alert("pitch unknown -- not set");
            break;
    }

    qz.append(str);

    qz.appendHex("x0D"); //CR for carriage return

    qz.appendHex("x1Bx40"); //ESC @ for reset settings

    window["qzDoneAppending"] = function() {        
        // Tell the apple to print.
    qz.print();     

        // Remove any reference to this function
    window['qzDoneAppending'] = null;
    };
}

実際には、印刷する文字の配列を 2 次元配列として作成し、\r\n の最後の列を省略することができます。これは、すべてのドット マトリックス プリンターで十分に受け入れられていないと思うからです。その場合、すべきこと

//for each line of the array
qz.append($line); //line-1 turned into string, line-2  etc
qz.appendHex("x0D"); //CR for carriage return after each line

私が遭遇した 1 つの問題は、ユーザーが 17CPI を選択した場合、すべての文字が用紙内で占めるスペースが少なくなることです。これは、この場合、ページ全体にデータを広げるために 1 つのスペース文字に依存できないことを意味します。

誰かがこれに貢献できると思うなら、大歓迎です。

于 2014-04-29T13:26:50.400 に答える