vue3 html2canvas+jspdf 实现小票打印功能

html2canvas把dom生成图片 然后通过jspdf生成pdf去打印

<template>

  <div class="body">
    <div style="width: 100%;display:flex;justify-content: center;">
      <a-button @click="onPrintSubmit" class="printBtn" type="primary" shape="round" size="large">
        确认打印
      </a-button>
    </div>
    <div class="receipt" ref="receipt">
      <div class="shopName">
        {{ printData?.shopName }}
      </div>
      <div class="totalIncome">
        汇总收入
      </div>
      <div class="prinitTime">
        <div class="label"><span>开始时间:</span><span>{{ starTime }}</span></div>
        <div class="label"><span>结束时间:</span><span>{{ endTime }}</span></div>
        <div class="label"><span>制单时间:</span><span>{{ currenTime }}</span></div>
      </div>
      <div class="line"></div>
      <div>
        <div class="section items">
          <div class="table">
            <div class="title">
              <div class="label1">菜品</div>
              <div class="label2">数量</div>
              <div class="label3">实收金额</div>
            </div>
            <div class="column" v-for="item in printData?.singleProductSummaryDataList">
              <div class="label1">{{ item.productName }}</div>
              <div class="label2">{{ item.salesVolume }}</div>
              <div class="label3">{{ item.salesAmount }}</div>
            </div>
          </div>

        </div>
        <div class="prinitTime">
          <div class="label">营业应收总额:{{ printData?.totalReceivables }}</div>
          <div class="label">营业实际收入: {{ printData?.realTotalAmountReceived }}元</div>
        </div>
        <div class="line"></div>
        <div class="section items">
          <div class="table">
            <div class="title">
              <div class="label1"> </div>
              <div class="label2">订单数量</div>
              <div class="label3">总额</div>
            </div>
            <!-- <div class="column">
              <div class="label1">订单原价</div>
              <div class="label2">{{ printData?.orderOriginalPrice }}</div>
              <div class="label3">{{ printData?.orderOriginalPrice }}</div>
            </div> -->
            <div class="column">
              <div class="label1">微信支付</div>
              <div class="label2">{{ printData?.wechatOrderTotal }}</div>
              <div class="label3">{{ printData?.wechatOrderTotalAmount }}</div>
            </div>
            <div class="column">
              <div class="label1">余额支付</div>
              <div class="label2">{{ printData?.personalBalancePayOrderTotal }}</div>
              <div class="label3">{{ printData?.personalBalancePayOrderTotalAmount }}</div>
            </div>
            <div class="column">
              <div class="label1">餐卡支付</div>
              <div class="label2">{{ printData?.mealCardPayOrderTotal }}</div>
              <div class="label3">{{ printData?.mealCardPayOrderTotalAmount }}</div>
            </div>
            <div class="column">
              <div class="label1">优惠券优惠</div>
              <div class="label2">{{ printData?.redPacketOrderTotal }}</div>
              <div class="label3">{{ printData?.redPacketTotalAmount }}</div>
            </div>
            <div class="column">
              <div class="label1">员工优惠</div>
              <div class="label2">{{ printData?.employeeDiscountOrderTotal }}</div>
              <div class="label3">{{ printData?.employeeDiscountOrderTotalAmount }}</div>
            </div>
            <div class="column">
              <div class="label1">退款总额</div>
              <div class="label2"></div>
              <div class="label3">{{ printData?.refundTotalAmount }}</div>
            </div>
          </div>

        </div>

      </div>
    </div>
  </div>
</template>

<script setup>
import { ref,  onMounted } from "vue";
import { getCurrentDateTime, getCurrentYYMMDD } from "/src/utils/utils.js"
import html2canvas from "html2canvas";
import jsPDF from "jspdf";

const receipt = ref(null);

const props = defineProps({
  printData: {
    type: Object,
    default: {},
  },
  starTime: {
    type: Object,
    default: getCurrentYYMMDD() + ' 00:00:00',
  },
  endTime: {
    type: Object,
    default: getCurrentYYMMDD() + ' 23:59:59',
  },
});


const currenTime = ref(null)
onMounted(() => {
  currenTime.value = getCurrentDateTime()
})

const onPrintSubmit = async () => {
  const element = receipt.value;
  const elementWidth = element.offsetWidth;
  const elementHeight = element.offsetHeight;

  const scale = 12; // 缩小比例   我是在小票机上打印的 应该是 缩放比例越小打印的越清晰  当然了  加载的时候就会略慢一下
  const canvasWidth = elementWidth * scale;
  const canvasHeight = elementHeight * scale;

  html2canvas(element, { scale }).then((canvas) => {
    const imgData = canvas.toDataURL("image/png");

    const pdf = new jsPDF({
      orientation: "p",
      unit: "px",
    });

    const pageWidth = pdf.internal.pageSize.getWidth();
    const pageHeight = pdf.internal.pageSize.getHeight();

    // 计算比例,保持图片等比例缩放
    const ratio = Math.min(pageWidth / canvasWidth, pageHeight / canvasHeight);
    const imgWidth = canvasWidth * ratio;
    const imgHeight = canvasHeight * ratio;

    // 居中显示图片
    const x = (pageWidth - imgWidth) / 2;
    const y = (pageHeight - imgHeight) / 2;
    //                                                  X   Y   
    pdf.addImage(imgData, "PNG", 15, 20, imgWidth / 2.8, imgHeight / 2.8);
    //  解释一下为什么这里要/2.8       比如 打印在A4上面 W是21  但是图片是41的话 这时候 你就要自己去等比的缩放了
    pdf.autoPrint();

    const pdfURL = pdf.output("bloburl");
    const printWindow = window.open(pdfURL, "_blank");
    printWindow.focus();
  }).catch((error) => {
    console.error("打印失败:", error);
  });
}
</script>

<style scoped>
.body {

  margin: 0;

}

.printBtn {
  margin: 0 auto;
}

.line {
  margin-top: 6px;
  width: 100%;
  height: 1px;
  border-bottom: 1px dotted #000000;
}

.shopName {

  width: 260px;
  text-align: center;
  font-weight: bold;
  font-size: 20px
}

.totalIncome {
  padding: 0;
  width: 260px;
  margin: 0 auto 0;
  text-align: center;
  font-size: 14px
}


.prinitTime {
  font-size: 16PX;
  margin-top: 4px;
}

.receipt {
  font-family: Microsoft Sans-serif;
  color: #000;


  width: 100%;
  max-height: 700px;

}

.receipt h2 {
  text-align: center;
  margin-bottom: 20px;
}

.receipt .section {
  margin-bottom: 20px;
}

.receipt .section .label {
  font-weight: bold;
}

.receipt .section .value {
  margin-left: 10px;
}

.receipt .total {
  font-weight: bold;
  font-size: 1.2em;
}

.receipt .items .table {
  margin-top: 20px;
  width: 100%;
  border-collapse: collapse;
}

.table .title,
.table .column {
  font-family: Microsoft Sans-serif;
  display: flex;
}

.table .label1 {
  width: 160px;
  font-size: 16px;
}

.table .label2,
.table .label3 {
  width: 90px;
  font-size: 16px;
  text-align: right;
}

/* 打印样式 */
@media print {
  .print-button {
    display: none;
  }

  .receipt {
    width: 100%;
    padding: 0;
    margin: 0;
    border: none;
    font-size: 12px;
    /* 调整字体大小 */
  }

  .receipt .items table th,
  .receipt .items table td {
    padding: 2px;
  }

  .receipt .section {
    margin-bottom: 10px;
  }
}
</style>

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容