uniapp(vue3) H5页面连接打印机并打印

一、找到对应厂商打印机的驱动并在windows上面安装。查看是否安装完成可以在:控制面板->查看设备和打印机,找到对应打印机驱动是否安装完成

二、打印机USB连接电脑

三、运行代码调用浏览器打印,主要使用的是window.print()功能。下面使用的是基于ifream的,这样可以控制到具体打印范围,全屏打印可以考虑不用。(原理应该就是打印机打印PDF)

四、打印样式不全或者其他,可以考虑设置打印格式 或者 代码样式调整

五、demo 代码

(1) 核心代码

(2) 完整代码

<template>
    <div class="mainContent" @click="emits('close')">
        <div class="printContent">
            <iframe style="width: 100%;height: 100%" :src="ticketUrl" ref="ticketIframe" @load="onIframeLoad"></iframe>
            <div class="btnPrint" @click="printReceipt">打印</div>
        </div>
    </div>
</template>

<script setup>
import {forDate} from "@/utlis/uni_api";
import {ref, onMounted, getCurrentInstance, toRefs} from 'vue';

let {proxy} = getCurrentInstance();
let emits = defineEmits(["print", "close"])
let props = defineProps(["data"])
const ticketIframe = ref(null);
const ticketUrl = '../static/print.html';
let {data} = toRefs(props)
let merOrderList = {}
let originalPrice = ""
let sendTxt = ""
let goodsDetails = ""

// 确保iframe加载完成
onMounted(async () => {
    await proxy.$nextTick();
    ticketIframe.value.contentWindow.focus();

    merOrderList = data.value.merOrderList

    let proList = data.value.goodList
    for (let i = 0; i < proList.length; i++) {
        let goodsName = proList[i].goodsName
        let goodsNum = proList[i].goodsNum
        let realPrice = proList[i].realPrice
        let spec = proList[i].goodsSpecification
        //商品信息
        goodsDetails += goodsName + "[" + spec + "]" + "&nbsp;X&nbsp;" + goodsNum + "&nbsp;&nbsp;&nbsp;&nbsp;¥" + realPrice + "</br>"
    }
    //原价
    originalPrice = merOrderList.price + merOrderList.discountsPrice
    //配送时间
    sendTxt = data.value.isIm ? "立即配送" : data.value.predictTime
});

function onIframeLoad() {
    console.log("data = ", data.value)
    let printerName = uni.getStorageSync("printerName")
    let iframe = ticketIframe.value
    let iframeDocument = iframe.contentWindow ? iframe.contentWindow.document : iframe.contentDocument;
    // 对于跨域限制不适用的情况,可以直接操作DOM
    if (iframeDocument) {
        if (printerName == "XP58C" || printerName == "POS58") {
            iframeDocument.body.innerHTML = ticketXP58C()
        }
    }
}

function ticketXP58C() {
    return `
            <img style="width: 160px;height: 70px;margin: 0 0 30px 20px;" src="../static/image/public/print_logo.png">
            <div style="font-size: 20px;font-weight: bold;margin-bottom: 20px;">#${data.value.dayNum}&nbsp;&nbsp;&nbsp;*外卖狮配送*</div>
            <div style="font-size: 10px;margin-bottom: 4px;">-----------------------------------------------</div>
            <div style="display: flex;justify-content: space-between;font-size: 11px;margin-bottom: 4px;">
                <div>送达时间:</div>
                <div>${sendTxt}</div>
            </div>
            <div style="display: flex;justify-content: space-between;font-size: 11px;margin-bottom: 4px;">
                <span>下单时间:</span>
                <span>${forDate(merOrderList.createTime)}</span>
            </div>
            <div style="display: flex;justify-content: space-between;font-size: 11px;margin-bottom: 4px;">
                <div>订单编号:</div>
                <div>${merOrderList.orderSn}</div>
            </div>
            <div style="font-size: 10px;margin-bottom: 4px;">-----------------------------------------------</div>
            <div style="display: flex;font-size: 18px;font-weight:bold;margin-bottom: 4px;">
                <span>备注:</span>
                <span>${data.value.remark ? data.value.remark : "无"}</span>
            </div>
            <div style="font-size: 12px;margin-bottom: 4px;">*************************************</div>
            <div style="font-size: 11px;margin-bottom: 4px;">---------------------餐品------------------</div>
            <div style="font-size: 11px;margin-bottom: 4px;">${goodsDetails}</div>
            <div style="font-size: 11px;margin-bottom: 4px;">---------------------其他------------------</div>
            <div style="display: flex;justify-content: space-between;font-size: 11px;margin-bottom: 4px;">
                <span>打包费:</span>
                <span>¥${merOrderList.packPrice}</span>
            </div>
            <div style="display: flex;justify-content: space-between;font-size: 11px;margin-bottom: 4px;">
                <span>配送费:</span>
                <span>¥${merOrderList.distributionPrice}</span>
            </div>
            <div style="display: flex;justify-content: space-between;font-size: 11px;margin-bottom: 4px;">
                <span>优惠价格:</span>
                <span>-¥${merOrderList.discountsPrice}</span>
            </div>
            <div style="font-size: 12px;margin-bottom: 4px;">*************************************</div>
            <div style="display: flex;justify-content: space-between;font-size: 11px;margin-bottom: 4px;">
                ${merOrderList.payType == "alipay" ? "支付宝支付" : "微信支付"}
            </div>
            <div style="display: flex;justify-content: space-between;font-size: 11px;margin-bottom: 4px;">
                原价:¥${originalPrice}
            </div>
            <div style="display: flex;justify-content: right;font-size: 18px;font-weight: bold;margin-bottom: 4px;">
               实付:¥${merOrderList.price}
            </div>
            <div style="font-size: 10px;margin-bottom: 30px;">------------------------------------------------</div>
            <div style="display: flex;font-size: 18px;font-weight: bold;margin-bottom: 20px;">
                ${data.value.name} ${data.value.phone.substr(0, 3) + "****" + data.value.phone.substr(data.value.phone.length - 4, data.value.phone.length)}
            </div>
            <div style="font-size: 12px;margin-bottom: 60px;">*************************************</div>
            <div style="font-size: 1px;">-</div>
        `
    //地址
    // < div style = "display: flex;font-size: 18px;font-weight: bold;margin-bottom: 15px;" >
    // ${merOrderList.address}
    // < /div>
}

function printReceipt() {
    emits("close")
    ticketIframe.value.contentWindow.print(); // 调用iframe内部的window.print()
    proxy.$refs.ticketIframe.contentWindow.location.reload(true);
}
</script>

<style scoped>
.mainContent {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    min-height: 100vh;
    background-color: rgba(0, 0, 0, 0.5);
    z-index: 999999;
    display: flex;
    align-items: center;
    justify-content: center;
}

.printContent {
    width: 70%;
    height: 50vh;
    background-color: #FFFFFF;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    border-radius: 10rpx;
    padding: 20rpx;
}

.btnPrint {
    width: 50%;
    margin: 80rpx auto 20rpx;
    font-size: 26rpx;
    color: #FFFFFF;
    background-color: #FF0000;
    text-align: center;
    padding: 10rpx 0;
    border-radius: 10rpx;
}

iframe {
    border: none;
}
</style>
相关推荐
逐·風3 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
Devil枫3 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦4 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子5 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山5 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享5 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
从兄6 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
清灵xmf7 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨7 小时前
VUE+Vite之环境文件配置及使用环境变量
前端
GDAL7 小时前
npm入门教程1:npm简介
前端·npm·node.js