如何通过.print()跳过打印预览并自动打印2份咖啡订单收据?
实现自动打印2份订单收据(预览优化)
问题说明
用jQuery和HTML开发的咖啡订单程序运行正常,需要实现点击下单后优化打印流程(受浏览器安全限制无法完全跳过预览,可实现一次预览打印两份),自动输出2份订单收据。以下是当前代码及修改方案:
当前代码
1. 打印流程代码
alert_toast("Data successfully saved.",'success') setTimeout(function(){ var nw = window.open('../receipt.php?id='+resp,"_blank","width=900,height=600") setTimeout(function(){ nw.print() setTimeout(function(){ nw.close() location.reload() },500) },500) },500)
2. Receipt.php代码
<?php include 'db_connect.php'; $order = $conn->query("SELECT * FROM orders where id = {$_GET['id']}"); foreach($order->fetch_array() as $k => $v){ $$k= $v; } $items = $conn->query("SELECT o.*,p.name FROM order_items o inner join products p on p.id = o.product_id where o.order_id = $id "); ?> <style> .flex{ display: inline-flex; width: 100%; } .w-50{ width: 50%; } .text-center{ text-align:center; } .text-right{ text-align:right; } table.wborder{ width: 100%; border-collapse: collapse; } table.wborder>tbody>tr, table.wborder>tbody>tr>td{ border:1px solid; } p{ margin:unset; } </style> <div class="container-fluid"> <p class="text-center"><b><?php echo $amount_tendered > 0 ? "Receipt" : "Bill" ?></b></p> <hr> <div class="flex"> <div class="w-100"> <?php if($amount_tendered > 0): ?> <p><b>Cafe 365 - Thank you for your Order!</b></p> <?php endif; ?> <p><b><?php $now = new DateTime(); echo $now->format('Y-m-d H:i:s'); ?></b></p> </div> </div> <hr> <p><b>Order List</b></p> <table width="100%"> <thead> <tr> <td><b>QTY</b></td> <td><b>Order</b></td> <td class="text-right"><b>Amount</b></td> </tr> </thead> <tbody> <?php while($row = $items->fetch_assoc()): ?> <tr> <td><?php echo $row['qty'] ?></td> <td><p><?php echo $row['name'] ?></p><?php if($row['qty'] > 0): ?><small>(R<?php echo number_format($row['price'],2) ?>)</small> <?php endif; ?></td> <td class="text-right">R<?php echo number_format($row['amount'],2) ?></td> </tr> <?php endwhile; ?> </tbody> </table> <hr> <table width="100%"> <tbody> <tr> <td><b>Total Amount</b></td> <td class="text-right"><b>R<?php echo number_format($total_amount,2) ?></b></td> </tr> <?php if($amount_tendered > 0): ?> <?php endif; ?> </tbody> </table> <hr> </div>
修改方案
方案1:前端触发两次打印(需处理延迟)
修改打印流程代码,监听新窗口加载完成后连续触发两次打印,设置合理延迟避免打印对话框冲突:
alert_toast("Data successfully saved.",'success') setTimeout(function(){ var nw = window.open('../receipt.php?id='+resp,"_blank","width=900,height=600") // 等待页面加载完成 nw.onload = function() { // 第一次打印 nw.print(); // 延迟1秒触发第二次打印 setTimeout(function(){ nw.print(); // 打印完成后关闭窗口并刷新 setTimeout(function(){ nw.close(); location.reload(); }, 500); }, 1000); }; }, 500);
方案2:收据页生成两份内容,一次打印(推荐)
修改Receipt.php,循环生成两份收据内容,配合CSS自动分页,一次打印即可输出两份,流程更稳定:
<?php include 'db_connect.php'; $order = $conn->query("SELECT * FROM orders where id = {$_GET['id']}"); foreach($order->fetch_array() as $k => $v){ $$k= $v; } $items = $conn->query("SELECT o.*,p.name FROM order_items o inner join products p on p.id = o.product_id where o.order_id = $id "); ?> <style> .flex{ display: inline-flex; width: 100%; } .w-50{ width: 50%; } .text-center{ text-align:center; } .text-right{ text-align:right; } table.wborder{ width: 100%; border-collapse: collapse; } table.wborder>tbody>tr, table.wborder>tbody>tr>td{ border:1px solid; } p{ margin:unset; } /* 打印时自动分页,确保两份收据各占一页 */ @media print { .container-fluid { page-break-after: always; } .container-fluid:last-child { page-break-after: avoid; } } </style> <?php // 循环生成两份收据 ?> <?php for($i=0;$i<2;$i++): ?> <div class="container-fluid"> <p class="text-center"><b><?php echo $amount_tendered > 0 ? "Receipt" : "Bill" ?></b></p> <hr> <div class="flex"> <div class="w-100"> <?php if($amount_tendered > 0): ?> <p><b>Cafe 365 - Thank you for your Order!</b></p> <?php endif; ?> <p><b><?php $now = new DateTime(); echo $now->format('Y-m-d H:i:s'); ?></b></p> </div> </div> <hr> <p><b>Order List</b></p> <table width="100%"> <thead> <tr> <td><b>QTY</b></td> <td><b>Order</b></td> <td class="text-right"><b>Amount</b></td> </tr> </thead> <tbody> <?php // 重置结果集指针,确保循环两次都能读取到订单商品 $items->data_seek(0); while($row = $items->fetch_assoc()): ?> <tr> <td><?php echo $row['qty'] ?></td> <td><p><?php echo $row['name'] ?></p><?php if($row['qty'] > 0): ?><small>(R<?php echo number_format($row['price'],2) ?>)</small> <?php endif; ?></td> <td class="text-right">R<?php echo number_format($row['amount'],2) ?></td> </tr> <?php endwhile; ?> </tbody> </table> <hr> <table width="100%"> <tbody> <tr> <td><b>Total Amount</b></td> <td class="text-right"><b>R<?php echo number_format($total_amount,2) ?></b></td> </tr> <?php if($amount_tendered > 0): ?> <?php endif; ?> </tbody> </table> <hr> </div> <?php endfor; ?>
对应的前端打印代码简化为:
alert_toast("Data successfully saved.",'success') setTimeout(function(){ var nw = window.open('../receipt.php?id='+resp,"_blank","width=900,height=600") nw.onload = function() { nw.print(); setTimeout(function(){ nw.close(); location.reload(); }, 500); }; }, 500);
注意事项
浏览器出于安全限制,无法完全跳过打印预览界面。方案2只需用户在预览界面点击一次打印即可得到两份收据,体验更流畅;方案1需要用户两次确认打印,适合必须分开触发打印的场景。
内容的提问来源于stack exchange,提问作者CodeLearnerZA
相关产品推荐
相关产品推荐

