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

news2024/12/22 17:05:51

一、找到对应厂商打印机的驱动并在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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1538845.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Angular入门问题小本本

1、console.log打印object对象显示[object object] 解决方案&#xff1a;使用JSON.stringify console.log(JSON.stringify($rootScope.MaintainDeviceInfo));2、 State ‘goDiskManagement’’ is already defined 解决方案&#xff1a;同一个项目中&#xff0c;不能定义相同…

阅读MySQL知识4

一、MySQL数据库主从同步延迟产生的原因 MySQL的主从复制都是单线程的操作&#xff0c;主库对所有DDL和DML产生的日志写进binlog&#xff0c;由于binlog是顺序写&#xff0c;所以效率很高。 Slave的SQL Thread线程将主库的DDL和DML操作事件在slave中重放。DML和DDL的IO操作…

CCDP.02.OS正确部署后的Dashboard摘图说明

前言 在部署成功OpenStack后&#xff0c;应该可以在浏览器打开Dashboard&#xff0c;并对计算资源&#xff08;这里主要是指VM&#xff09;进行管理&#xff0c;也可以在Dashboard上面查看OpenStack是否存在错误&#xff0c;下面&#xff0c;已针对检查的关键点&#xff0c;用红…

JavaScript原型、原型对象、原型链系列详解(一)

(一)、JavaScript原型 原型 JavaScript 是一门面向对象的编程语言&#xff0c;其中原型&#xff08;prototype&#xff09;是一个重要的概念&#xff0c;它提供了一种创建对象的方式&#xff0c;使对象可以共享属性和方法。在 JavaScript 中&#xff0c;每个对象都有一个原型&a…

ruoyi-nbcio-plus基于vue3的flowable增加开始节点的表单绑定修改

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

在Linux上运行JMeter(非界面)

参考&#xff1a; 查看文件类型&#xff1a;https://www.linuxprobe.com/files-tehre-fangfa.html 华为云平台 配置&#xff1a;jdk环境、jmeter环境 jmeter配置&#xff08;在/etc/profile文件中&#xff09;&#xff1a; export JMETER_HOME/path/to/jmeter/installati…

基于FPGA的FFT图像滤波设计

1.FFT滤波算法介绍 FFT滤波就是通过傅里叶运算将图像转换到频域空间&#xff0c;然后在频域中对图像进行处理&#xff0c;最后将处理后的图像通过傅里叶逆运算将图像转会到时域空间。 在频域空间中&#xff0c;我们能够更好的对图像的噪声进行分析&#xff0c;然后找出相关规律…

Selenium不同版本配置自动下载驱动及打包细节

Selenium配置浏览器驱动 自动下载浏览器驱动的方法 selenium4.7.0自动下载浏览器驱动的方法 selenium4.11.0 或4.11.1手动设置浏览器驱动路径的方法pyinstaller打包程序时同时打包ChromeDriverchromedriver路径需要sys._MEIPASS的路径进行引用方法一&#xff1a;通过–add-data…

Ubuntu18.04显示--有线连接未托管

引用: Ubuntu18.04连不网 报"有线连接未托管"_ubuntu20.04以太网未托管-CSDN博客 正文 虚拟机环境配置&#xff1a; VirtaualBox Ubuntu18.04桌面版 问题现象&#xff1a; Ubuntu18.04虚拟机的桌面上提示“有线连接未托管”&#xff0c;虚拟机不能上网&#xf…

云手机在运营社媒方面对比真机有何优势

云手机作为一种虚拟手机环境&#xff0c;通过云端技术实现了将多个手机系统运行在同一台设备上的功能。在运营社交媒体方面&#xff0c;与传统的真机相比&#xff0c;云手机 具有一系列独特的优势&#xff0c;本文将从多个方面进行对比分析。 1、安全性 云手机提供了更高级别的…

一个不会绘画的我遇到AI绘画的时代

AI 绘画的时代 我是没有艺术细胞的&#xff0c;这点我从很小就切实的感受到了&#xff0c;我不会画画&#xff0c;不会唱歌&#xff0c;我便是艺术的荒漠。童年是那么的梦幻&#xff0c;那么的值得渴望&#xff0c;谁不想亲自用自己的画笔来描绘记忆中的过去那&#xff1f;没错…

手机网页视频批量提取工具可导出视频分享链接|爬虫采集下载软件

解放你的抖音视频管理——全新抖音批量下载工具震撼上线&#xff01; 在这个信息爆炸的时代&#xff0c;如何高效地获取、管理和分享视频内容成为了许多用户的迫切需求。为了解决这一难题&#xff0c;我们研发了全新的视频批量下载工具&#xff0c;让你轻松畅享海量音视频资源。…

PAT题解 --- 寻宝图

今天是PTA题库解法讲解的第十天&#xff0c;今天我们要讲解浪漫侧影&#xff0c;题目如下&#xff1a; 题解思路&#xff1a; 要解决这个问题&#xff0c;可以使用深度优先搜索&#xff08;DFS&#xff09;方法来遍历每一个陆地或宝藏格子&#xff0c;标记所有与之相连的格子…

数据降维 | Matlab实现POD本征正交分解数据降维模型

数据降维 | Matlab实现POD本征正交分解数据降维模型 目录 数据降维 | Matlab实现POD本征正交分解数据降维模型基本介绍模型描述程序设计基本介绍 1.Matlab实现POD本征正交分解数据降维模型(完整源码和数据); 2.运行环境matlab2023; 3.POD降维,POD分解(Proper Orthogonal D…

计算机二级Python基础操作题

题目来源&#xff1a;计算机二级Python半个月抱佛脚大法&#xff08;内呈上真题版&#xff09; - 知乎 第4&#xff0c;5&#xff0c;6&#xff0c;7&#xff0c;9&#xff0c;10&#xff0c;11套 1. 基础题1 sinput() print("{:\"^30x}".format(eval(s))) b …

数据库被.[Goodmorningfriends@onionmail.org].faust勒索病毒加密,能恢复吗?

.faust勒索病毒有什么特点及危害&#xff1f; .faust勒索病毒是一种恶意软件&#xff0c;以其复杂的加密技术和勒索行为而闻名。这种病毒的主要目标是通过加密受害者的数据文件&#xff0c;然后勒索赎金以解密这些文件。它通常通过恶意附件、恶意链接或潜在的不安全下载源传播&…

云平台宿主机系统漂移分析

ntp时间同步机制 宿主机上ntp client每隔最小时间间隔64s,最大时间间隔1024s与ntpd server保持时间同步,当ntp client 与ntd server时间偏差为|+-10|s,立马纠正client ntp的时间与 ntp server保持一致。 宿主机时间异常判定 宿主机ntp client 并发去访问五个ntp servers…

letcode::根据二叉树创建字符串

根据二叉树创建字符串 题目描述&#xff1a; 给你二叉树的根节点 root &#xff0c;请你采用前序遍历的方式&#xff0c;将二叉树转化为一个由括号和整数组成的字符串&#xff0c;返回构造出的字符串。 空节点使用一对空括号对 “()” 表示&#xff0c;转化后需要省略所有不影…

【JavaEE初阶系列】——带你了解volatile关键字以及wait()和notify()两方法背后的原理

目录 &#x1f6a9;volatile关键字 &#x1f388;volatile 不保证原子性 &#x1f388;synchronized 也能保证内存可见性 &#x1f388;Volatile与Synchronized比较 &#x1f6a9;wait和notify &#x1f388;wait()方法 &#x1f4bb;wait(参数)方法 &#x1f388;noti…

【Python + Django】静态文件的添加

前言&#xff1a; 前一篇文章我们已经学会了怎么用django写文本页面啦&#xff01;&#xff01;&#xff01; 有一说一&#xff0c;这个静态页面是真的丑。 我们总得用一些花花绿绿的东西把这个丑陋的网站给装饰一下吧&#xff01;&#xff01;&#xff01;&#xff01;&…