1

我有 ExtJS 应用程序,它正在查询数据库并在网格中显示结果,它工作正常。

用户可以通过复选框从网格中选择任何记录,然后发送到服务器打印出来。服务器端代码生成PDF文件(通过TCPDF)并返回结果浏览器,它也可以正常工作。

我的问题是,客户端不在浏览器窗口中显示 PDF 文件,而不是只显示 PDF 页面的二进制形式。

那么,您能帮我吗,我该如何处理返回的 PDF 文件以显示客户端屏幕?

客户端

{
xtype: 'button',
width: 90,
text: 'GÖNDER',
cls: 'x-btn-gonder',
handler: function(){
    var ppt     = Ext.getCmp('labelType').getValue();
    var sb      = Ext.getCmp('basic-statusbar');
    var count   = Ext.getCmp('labelGrids').getSelectionModel().getCount();
    var rows    = Ext.getCmp('labelGrids').getSelectionModel().getSelection();

    if(ppt == null) {
        dialog.show();
    } else {
    if(count > 0) {
        var paper = {};
        paper.PAPER = ppt;

        var prints = new Array();
        for (var i = 0; i < count; i++)
        {
            prints[i] = {'LABEL_ID': rows[i].data.LABEL_ID, 'LABEL_TYPE':rows[i].data.LABEL_TYPE}
        }
        paper.LABELS = prints;

        Ext.Ajax.request({
            url: 'lib/labels/print_label.php',
            timeout: 60000,

            success: function() 
            { 
                Ext.Msg.alert('İşlem Başarılı', 'Etiketler yazıcıya gönderildi.');

                // set statusbar text after print
                sb.setStatus({
                    text: 'Etiketler yazıcıya gönderildi..!',
                    iconCls: 'x-status-saved',
                    clear: true
                });

                // remove checked items
                Ext.select('.x-grid-row-selected').each(function (element) {
                    Ext.getCmp('labelGrids').getSelectionModel().deselectAll();
                });
            },
            failure: function() { Ext.Msg.alert('Yazdırma Hatası', 'Etiketler yazdırılamadı..!')},
            jsonData: Ext.JSON.encode(paper)
        });

        // clear combobox selected value after send to printer
        Ext.getCmp('labelType').reset();

        // console.log(Ext.JSON.encode(prints));
    } else if(count == 0) {
        sb.setStatus({
            iconCls: 'x-status-error',
            text: 'Lütfen yazdırmak istediğiniz etiketleri seçiniz!'
        });
    }                           
    winPaper.hide();
    }
}

}

服务器端

<?php
require_once('../tcpdf/config/lang/eng.php');
require_once('../tcpdf/tcpdf.php');

$db = new mysqli("10.10.10.10","blabla","blablabla","label");
$db->query("SET NAMES UTF8");
$db->query("SET SQL_MODE='NO_AUTO_VALUE_ON_ZERO'");
$db->query("SET lc_time_names = 'tr_TR'");

$datas = json_decode(file_get_contents("php://input"));

// get paper type from json array
$paper  = $datas->PAPER;

foreach($datas->LABELS as $data)
{
    $lblids[] = $data->LABEL_ID;
}

$ids = implode(",", $lblids);

// get labels from db
$sql = "SELECT LABEL_ID, SUBSYS_ART_NO, ARTICLE_DESC, END_DATE, PRODUCT_PRICE, SHELF_PRICE, LABEL_TEXT, LABEL_TYPE, LABEL_SIGN, PROMO FROM labels WHERE LABEL_ID IN (".$ids.")";
$result = $db->query($sql);

while($row = $result->fetch_assoc())
{
    $labels[] = $row;
}

switch($paper)
{
    case "SF":
        print_shelf($labels);
    break;
}

function print_shelf($labels)
{
    # defining PDF variables
    $width      = 100;
    $height     = 55;
    $pageSize   = array($width, $height);

    # create new BMPL PDF price label
    $pdf = new TCPDF('L', PDF_UNIT, $pageSize, true, 'UTF-8', false);

    # set PDF document information
    $pdf->SetCreator(PDF_CREATOR);
    $pdf->SetAuthor('Oğuz Çelikdemir, Metro Systems Turkey');
    $pdf->SetTitle('BMPL Price Label');

    # disable pdf document header and footer
    $pdf->setPrintHeader(false);
    $pdf->setPrintFooter(false);

    # set PDF default font
    $pdf->setDefaultMonospacedFont('PDF_FONT_MONOSPACED');

    # set auto page breaks
    $pdf->SetAutoPageBreak(true, 2);

    $crs   = array('width' => 0.5);
    $style = array('width' => 0.25, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0));

    for($i = 0; $i < count($labels); $i++)
    {
        # add PDF page
        $pdf->addPage();

        # split the price values
        $prdPrice = explode(".", $labels[$i]['PRODUCT_PRICE']);
        $shfPrice = explode(".", $labels[$i]['SHELF_PRICE']);

        $prcLeft  = $prdPrice[0];
        $prcRight = $prdPrice[1];
        $shfLeft  = $shfPrice[0];
        $shfRight = $shfPrice[1];

        # Label variables
        $priceLeft      = '<span style="color:#b4b4b4;">'.$prcLeft.'</span>';
        $priceLeftCent  = '<span style="color:#b4b4b4;">'.$prcRight.'</span';
        $priceRight     = '<span style="color:#b4b4b4;">'.$shfLeft.'</span>';
        $priceRightCent = '<span style="color:#000;">'.$shfRight.'</span>';
        $taxLabelLeft   = '<span style="color:#b4b4b4;">KDV\'Lİ</span>';
        $taxLabelRight  = 'KDV\'Lİ';
        $articleDesc    = '\''.$labels[$i]['ARTICLE_DESC'].'\'';
        $articleNumber  = $labels[$i]['SUBSYS_ART_NO'];
        $labelText      = '\''.$labels[$i]['LABEL_TEXT'].'\'';
        $promoDate      = $labels[$i]['END_DATE'];
        $promoLabel     = $labels[$i]['PROMO'];

        ////////////// PREPARE THE LABELS \\\\\\\\\\\\\\

        # LABEL BOTTOM
        $pdf->SetFont('dinpro', '', 6);
        $pdf->writeHTMLCell(20, 0,  5, 50, $articleNumber, '', 1, 0, true, 'L');
        $pdf->writeHTMLCell(20, 0, 28, 50, $promoDate, '', 1, 0, true, 'L');

        if(is_null($promoLabel)) {
            $pdf->writeHTMLCell(20, 0, 42, 50, '', '', 1, 0, true, 'R');
        } else {
            $pdf->writeHTMLCell(20, 0, 42, 50, 'FIRSAT', '', 1, 0, true, 'R');
        }

        # LABEL LEFT
        $pdf->SetFont('dinprob', 'B', 10);
        $pdf->MultiCell(90, 20, $articleDesc, 0, 'L', false, 1, 5, 5.50);
        $pdf->SetFont('dinprob', '', 8);
        $pdf->writeHTMLCell(45, 10, 5, 17, 'SATIŞ FİYATI', '', 1, 0, true, 'F');
        $pdf->SetFont('dinprob', 'B', 44);
        $pdf->writeHTMLCell(30, 27, 5, 24, $priceLeft, '', 1, 0, true, 'R', true);
        $pdf->SetFont('dinprob', 'B', 20);
        $pdf->writeHTMLCell(15, 10, 26.5, 28.5, $priceLeftCent, '', 1, 0, true, 'R', true);
        $pdf->SetFont('dinpro', '', 6);
        $pdf->writeHTMLCell(15, 10, 29.2, 37.3, $taxLabelLeft, '', 1, 0, 'L', true);

        if(!is_null($labels[$i]['LABEL_SIGN']))
        {
            $pdf->Line(7, 41, 38, 22, $crs);
        }

        # LABEL RIGHT
        $pdf->SetFont('dinprob','',8);
        $pdf->writeHTMLCell(45, 10, 50, 17, $labelText, '', 1, 0, true, 'C');
        $pdf->SetFont('dinprob', 'B', 58);
        $pdf->writeHTMLCell(45, 30, 42, 21, $priceRight, '', 1, 0, true, 'R', true);
        $pdf->SetFont('dinprob', 'B', 24);
        $pdf->writeHTMLCell(15, 10, 79.5, 28, $priceRightCent, '', 1, 0, true, 'R', true);
        $pdf->SetFont('dinpro', '', 6);
        $pdf->writeHTMLCell(15, 10, 81, 38.5, $taxLabelRight, '', 1, 0, 'L', true);

        $js .= 'print(true);';
        $pdf->IncludeJS($js);

        ob_end_clean();
        return $pdf->Output('bpml_label.pdf', 'I');
    }
}        
?>

控制台输出

4

3 回答 3

2

当您将 PDF 返回给客户时,请使用正确的内容类型发送它。在发回响应之前添加此标头

header('Content-Type: application/pdf');

然后客户端可以正确地决定如何处理文档。

于 2012-12-14T12:27:59.987 回答
1

我尝试了上述建议但没有成功,所以我做了如下替代方式:

首先,一些浏览器不支持像 PDF 这样的响应对象,因此,我回发到 PDF 文件 url,然后使用 Ext 窗口对象内的 iframe 进行处理。

success: function(response)
{
   var _url = response.responseText;

   new Ext.Window({
      title: 'Labels',
      id: 'pdfWindow',
      layout: 'fit',
      width: 600,
      height: 500,
      closeAction: 'destroy', // take notice that 'hide' action doesn't work
      items: [{
         xtype: 'component',
         autoEl: {
            tag: 'iframe', // we need iframes 'src' parameter to handle PDF
            style: 'height:100%; width:100%; border:none',
            // here we used special style to get rid of iframe title
            src: _url
         }
      }]
   }).show();
},

服务器端

// we need an unique ID to be able set unique file name
$uniqeid = uniqid(); # if you want add true parameter to extend sensibility
$filename = '/var/www/label/print/'.$uniqeid.'.pdf';
# F parameter creating the file in specified directory, don't forget to set security 777 for folder ortherwise you might take an error
$pdf->Output($filename, 'F');
echo('/print/'.$uniqeid.'.pdf');
于 2012-12-17T04:12:28.987 回答
0

将目标添加_blank到打印按钮。您的浏览器将在新窗口中打开它,其中包含服务器生成的 PDF 内容。

按照其他人的建议添加内容标题:

header('Content-Type: application/pdf');
于 2012-12-16T21:19:45.247 回答