Vue3实现批量打印二维码与条形码

欢迎阅览本篇文章

这篇文章是我在工作途中对批量生成二维码的一些见解,例如vue-qr(二维码)与jsbarcode(条形码)在vxe-table表格中的使用,二维码与条形码的批量生成与打印(打印时一页一个码)等。注意!本篇文章的所有代码均使用setup语法糖与TypeScript,请确保vue版本在vue3.2以上!或自行更改代码后使用。

npm下载相关依赖

  • npm下载vue-qr(二维码)
npm install vue-qr --save
  • 引入vue-qr
import VueQr from 'vue-qr/src/packages/vue-qr.vue'
  • npm下载jsbarcode(条形码)
npm install jsbarcode --save
  • 引入jsbarcode
import JsBarcode from 'jsbarcode'
  • set up语法糖会自动注册引入依赖,此处不需要手动注册,如需要手动注册,请使用以下代码:
export default {
  name:'', 
  components:{
     VueQr,
     JsBarcode 
  }
}

vxe-table表格

vxe-table表格是一个基于 Vue 的表格组件,除了一般表格支持的增删改查、排序、筛选、对比、树形结构、数据分页等,它还支持虚拟滚动、懒加载、打印导出、虚拟列表、虚拟滚动、模态窗口、自定义模板、渲染器、贼灵活的配置项、扩展接口等,特别是能支持类似excel表格操作方式。总之相当好用,相比起element-ui更能满足开发的需求。

  • 安装vxe-table
npm install xe-utils vxe-table
  • 全局引入
import Vue from 'vue'
import 'xe-utils'
import VXETable from 'vxe-table'
import 'vxe-table/lib/style.css'
 
Vue.use(VXETable)
  • 具体的表格用法,可以查看官网文档,这里不做过多赘述。

生成二维码

  • 依据表格数据生成二维码
<vxe-column field="mycode" align="center" width="120">
                          <template #default="{ row }">
                            <div ref="qrCodeRef" :id="'qrCode_'+row.id" class="hidden-mycode">
                            <vue-qr
                                :size="110"
                                :margin="0"
                                :auto-color="true"
                                :dot-scale="1"
                                :text="getTableText(row)"
                            />
                            </div>
                          </template>
                        </vxe-column>
  • vue-qr相关属性(常用部分)
属性名含义
text编码内容
size尺寸, 长宽一致, 包含外边距
margin二维码图像的外边距, 默认 20px
colorDark实点的颜色
colorLight空白区的颜色
backgroundColor背景色
dotScale数据区域点缩小比例,默认为0.35
autoColor若为 true, 图像将被二值化处理, 未指定阈值则使用默认值
  • getTableText方法,以JSON格式生成二维码数据
 //二维码生成数据
const getTableText = (row) => {
  const { id, id2, id3, id4} = row;
  const convertedRow = {
    id: String(id),
    id2: String(id2),
    id3: String(id3),
    id4: String(id4),
  };
  return JSON.stringify(convertedRow);
};

生成条形码

条形码的生成使用的是JavaScript的JsBarCode,因为就目前来看vue-barcode只支持vue2使用,而支持vue3使用的vue3-barcode又无法进行批量操作,其在做批量操作时,最后一个条形码会覆盖之前的所有条码,因此使用JsBarCode生成条码,以兼容批量操作。

  • 单独创建一个条码组件,名字随意,自己记得就行
<template>
  <div>
    <svg :id="'barcode'+index"></svg>
  </div>
</template>

<script setup>
import {onMounted, nextTick, defineProps, watch} from 'vue'
import JsBarcode from 'jsbarcode'

const props = defineProps({
  // 数据
  // 当前的值
  value: {
    type: String,
    default: ''
  },
  index: {
    type: Number
  }
});
function draw() {
  JsBarcode('#barcode' + props.index, String(props.value), {
    format: "CODE128",
    width: 1.65,
    height: 50,
    displayValue: true,
    fontSize: 15,
    margin: 15
  });
}

onMounted(() => {
  nextTick(() => {
    draw();
  });
});
</script>

<style scoped>

</style>
  • JsBarCode属性(常用部分)
属性名含义
format选择要使用的条形码类型
width设置条之间的宽度
height高度
displayValue是否在条形码下方显示文字
text覆盖显示的文本
fontOptions使文字加粗体或变斜体
font设置文本的字体
textAlign设置文本的水平对齐方式
textPosition设置文本的垂直位置
textMargin设置条形码和文本之间的间距
fontSize设置文本的大小
background设置条形码的背景
lineColor设置条和文本的颜色
margin设置条形码周围的空白边距
  • 监听表格数据,条码的数据不会随着表格的改动而自动变化,当我们对表格进行增删改查时,条码是不会及时更新的,因此需要监听表格的数据变化,随时重新生成条码
watch(() => props.value, () => {
  nextTick(() => {
    draw();
  });
});
  • 调用条码组件,自己的组件写在哪就在哪里调
import Barcode from "@cesec/views/production/produce-plan/Barcode.vue";
  • vxe表格生成条码数据,注意!一般来说不会在条码里塞太多数据,数据太多会造成条码过长,如果要保存很多数据的话,还是请用二维码存储
 <vxe-column field="myBarCode" align="center" width="120">
                        <template #default="{ row }">
                          <div ref="barCodeRef" :id="'barCode_'+row.id" class="hidden-mybarcode">
                            <Barcode :value="row.planningTasksNo" :index="row.id"></Barcode>
                          </div>
                        </template>
                      </vxe-column>

批量打印二维码与条形码

  • 二维码与条形码的打印通常是通过调用浏览器的打印机功能完成的,以下是获取数据的方式:
//打印二维码
const printEvent = () => {
  const $table = vxeTableRef.value;
  const rows = $table.getCheckboxRecords();

  let qrCodes = '';
  rows.forEach((row) => {
    const qrCodeId = 'qrCode_' + row.id;
    const barCodeId = 'barCode_' + row.id;
    const qrCodeElement = document.getElementById(qrCodeId);
    const barCodeElement = document.getElementById(barCodeId);
    const id= row.id;
    const id2= row.id2;
    const id3= row.id3;
    const id4= row.id4;
    const currentTime = new Date().toLocaleDateString('zh-cn',{dateStyle:'long'});
     qrCodes += `
    <div class="my-list-col">
      <div class="centered-content">${qrCodeElement.innerHTML}</div>
    </div>
    <div class="my-list-col">
      <div class="centered-content">${barCodeElement.innerHTML}</div>
    </div>
`;
  });
  
  if ($table) {
    const printContent = document.createElement('div');
    printContent.innerHTML = qrCodes;

    // 创建一个新的隐藏的iframe元素
    const printFrame = document.createElement('iframe');
    printFrame.style.display = 'none';
    document.body.appendChild(printFrame);

    const printDocument = printFrame.contentWindow.document;
    printDocument.open();
    printDocument.write(`
      <html>
        <body>
          ${printContent.innerHTML}
        </body>
      </html>
    `);
    printDocument.close();

    // 在打印窗口中调用打印功能
    printFrame.contentWindow.print();

    // 移除隐藏的iframe元素
    document.body.removeChild(printFrame);
  }
};

单页打印与码样式调整

以上就完成了二维码与条形码的生成与打印,但很多时候我们不只是单纯的打印出来就好,还需要对二维码进行样式优化,就比如

  • 分页设置,一张纸一个二维码
qrCodes += `
  <div class="my-list-row" style="display: flex; justify-content: center;">
    <div class="my-list-col">
      <div class="centered-content">${qrCodeElement.innerHTML}</div>
    </div>
  </div>
  <div class="my-list-row" style="display: flex; justify-content: center;">
    <div class="my-list-col">
      <div class="centered-content">${barCodeElement.innerHTML}</div>
    </div>
  </div>
  <div class="page-break"></div> <!-- 添加分页符 -->
`;
  • 亦或者需要加一些数据与二维码一起输出
qrCodes += `
  <div class="my-list-row" style="display: flex; justify-content: center;">
   <div class="my-list-col">
      <div class="centered-content">${id}</div>
      <div class="centered-content">${id2}</div>
      <div class="centered-content">${id2}</div>
      <div class="centered-content">${id3}</div>
      <div class="centered-content">${id4}</div>
    </div>
    <div class="my-list-col">
      <div class="centered-content">${qrCodeElement.innerHTML}</div>
    </div>
  </div>
  <div class="my-list-row" style="display: flex; justify-content: center;">
    <div class="my-list-col">
      <div class="centered-content">${barCodeElement.innerHTML}</div>
    </div>
  </div>
  <div class="page-break"></div> <!-- 添加分页符 -->
`;
  • 又或者需要对输出时的页面进行指定
printDocument.write(`
      <html>
        <head>
          <title>Print</title>
          <style>
            @media print {
              .page-break { page-break-after: always; } /* 定义分页符样式 */
              .centered-content { text-align: left; } /* 居中对齐内容 */
              @page { A4 } /* 设置页面尺寸为A4 */
            }
          </style>
        </head>
        <body>
          ${printContent.innerHTML}
        </body>
      </html>
    `);
  • 等等等等,你可以在此基础上的加入更多的样式与功能,我再次就不多说了

完整代码

  • 条码组件
<template>
 <div>
   <svg :id="'barcode'+index"></svg>
 </div>
</template>

<script setup>
import {onMounted, nextTick, defineProps, watch} from 'vue'
import JsBarcode from 'jsbarcode'

const props = defineProps({
 // 数据
 // 当前的值
 value: {
   type: String,
   default: ''
 },
 index: {
   type: Number
 }
});
function draw() {
 JsBarcode('#barcode' + props.index, String(props.value), {
   format: "CODE128",//选择要使用的条形码类型
   width: 1.65,//设置条之间的宽度
   height: 50,//高度
   displayValue: true,//是否在条形码下方显示文字
   fontSize: 15,//设置文本的大小
   margin: 15//设置条形码周围的空白边距
 });
}

onMounted(() => {
 nextTick(() => {
   draw();
 });
});


watch(() => props.value, () => {
 nextTick(() => {
   draw();
 });
});

</script>

<style scoped>

</style>
  • vxe表格生成二维码/条形码
<vxe-column field="myBarCode" align="center" width="120">
                       <template #default="{ row }">
                         <div ref="barCodeRef" :id="'barCode_'+row.id" class="hidden-mybarcode">
                           <Barcode :value="row.value" :index="row.id"></Barcode>
                         </div>
                       </template>
                     </vxe-column>
                       <vxe-column field="mycode" align="center" width="120">
                         <template #default="{ row }">
                           <div ref="qrCodeRef" :id="'qrCode_'+row.id" class="hidden-mycode">
                           <vue-qr
                               :size="110"
                               :margin="0"
                               :auto-color="true"
                               :dot-scale="1"
                               :text="getTableText(row)"
                           />
                           </div>
                         </template>
                       </vxe-column>
  • 二维码数据生成方法
//二维码生成数据
const getTableText = (row) => {
 const { id, id2, id3, id4} = row;
 const convertedRow = {
   id: String(id),
   id2: String(id2),
   id3: String(id3),
   id4: String(id4),
 };
 return JSON.stringify(convertedRow);
};
  • 打印二维码与条形码
//打印二维码
const printEvent = () => {
 const $table = producePlanTableRef.value;
 const rows = $table.getCheckboxRecords();

 let qrCodes = '';
 rows.forEach((row) => {
   const qrCodeId = 'qrCode_' + row.id;
   const barCodeId = 'barCode_' + row.id;
   const qrCodeElement = document.getElementById(qrCodeId);
   const barCodeElement = document.getElementById(barCodeId);
   const id= row.id;
   const id2= row.id2;
   const id3= row.id3;
   const id4= row.id4;
   const currentTime = new Date().toLocaleDateString('zh-cn',{dateStyle:'long'});
   qrCodes += `
 <div class="my-list-row" style="display: flex; justify-content: center;">
  <div class="my-list-col">
     <div class="centered-content">${id}</div>
     <div class="centered-content">${id2}</div>
     <div class="centered-content">${id2}</div>
     <div class="centered-content">${id3}</div>
     <div class="centered-content">${id4}</div>
   </div>
   <div class="my-list-col">
     <div class="centered-content">${qrCodeElement.innerHTML}</div>
   </div>
 </div>
 <div class="my-list-row" style="display: flex; justify-content: center;">
   <div class="my-list-col">
     <div class="centered-content">${barCodeElement.innerHTML}</div>
   </div>
 </div>
 <div class="page-break"></div> <!-- 添加分页符 -->
`;
});
 if ($table) {
   const printContent = document.createElement('div');
   printContent.innerHTML = qrCodes;

   // 创建一个新的隐藏的iframe元素
   const printFrame = document.createElement('iframe');
   printFrame.style.display = 'none';
   document.body.appendChild(printFrame);

   const printDocument = printFrame.contentWindow.document;
   printDocument.open();
   printDocument.write(`
     <html>
       <head>
         <title>Print</title>
         <style>
           @media print {
             .page-break { page-break-after: always; } /* 定义分页符样式 */
             .centered-content { text-align: left; } /* 居中对齐内容 */
             @page { A4 } /* 设置页面尺寸为A4 */
           }
         </style>
       </head>
       <body>
         ${printContent.innerHTML}
       </body>
     </html>
   `);
   printDocument.close();

   // 在打印窗口中调用打印功能
   printFrame.contentWindow.print();

   // 移除隐藏的iframe元素
   document.body.removeChild(printFrame);
 }
};
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值