IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> vue 打印功能 -> 正文阅读

[游戏开发]vue 打印功能

需求:
请求到后端数据,渲染成表格,通过打印机打印出来
在这里插入图片描述
在这里插入图片描述

代码实现:
list.vue

<template>
  <div>
    <div class="printBox">
      <div>
        <el-button type="primary" @click="printBtn" size="small">打印</el-button>
      </div>
      <div ref="printContent">
        <div class="receiptListBox">
          <div class="time">
            预计到货日期:{{detailInfo.arrivalDate}}
          </div>
          <div class="typeNum">
            商品种类:{{detailInfo.totalSguQty}} 发货总数:{{detailInfo.totalGoodsQty}}
          </div>
          <!-- 表格: tableData表体数组 propsList表头 -->
          <print-table 
            v-if="detailInfo.orderGoodsSummaryVoList && detailInfo.orderGoodsSummaryVoList.length > 0"
            class="print-table" 
            :pages="false"
            :tableData="detailInfo.orderGoodsSummaryVoList"
            :propsList="propsList"
          />
        </div>
        <div class="curTime">
          打印时间:{{currentTime}}
        </div>
      </div>
    </div>
  </div>
</template>

<script>

const activityUrl = {
  // 合伙人-收货单详情
  receiveOrderSummaryDetail: '/bazaar/a/o/copartner/summaryOrder/receiveOrderSummaryDetail',
  // 合伙人-播种单
  selectSowOrder: '/bazaar/a/o/copartner/summaryOrder/selectSowOrder',
}

import Storage from "@/utils/localStorage"
import PrintTable from '@/components/Common/Print/PrintTable'
import winPrinter from '@/utils/winPrinter';
import {dateFormat} from '@/utils/utils'

export default {
  name: 'receiptDetail',
  data() {
    return {
      detailInfo: {},
      searchInfo: {},
      propsList: [
        {
          name: '序号',
          props: 'index',
          align: 'center'
        },
        {
          name: '商品编码',
          props: 'goodsNo',
          align: 'center'
        },
        {
          name: '商品名称',
          props: 'goodsName',
          align: 'center'
        },
        {
          name: '商品规格',
          props: 'spec',
          align: 'center'
        },
        {
          name: '存储温度',
          props: 'storageTypeName',
          align: 'center'
        },
        {
          name: '应收件数',
          props: 'totalQuantity',
          align: 'center'
        },
        {
          name: '发货件数',
          props: 'totalPickQty',
          align: 'center'
        },
        {
          name: '缺货件数',
          props: 'totalLackQty',
          align: 'center'
        }
      ],
      currentTime: dateFormat('yyyy-MM-dd HH:mm', new Date().getTime()), // 当前时间
    }
  },
  components: {
    'print-table': PrintTable
  },
  created() {
   let pathArr = this.$route.path.split('/')
    let pageId = pathArr[2]
    if (Storage.get('jumpReport') && Storage.get('jumpReport') != 'undefined') {
      let obj = Storage.get('jumpReport')
      for (let key in obj) {
        let keyArr = key.split('/')
        let _pageId = keyArr[1]
        if (_pageId == pageId) {
          let searchInfo = obj[key]['/report/48317/detail']
          this.searchInfo = searchInfo
          this.getDetail()
        }
     }
    }
    
  },
  methods: {
    printBtn() {
      this.currentTime = dateFormat('yyyy-MM-dd HH:mm', new Date().getTime())
      winPrinter(this.$refs.printContent)
    },
   
    getDetail(_param) {
      this.$loading.show()
      let params = { arrivalDate: this.searchInfo.arrivalDate }
      this.$http
        .post(activityUrl.receiveOrderSummaryDetail, params)
        .then((res) => {
          this.$loading.hide()
          if (res.code === 0) {
            // 获取表格数据
            if (res.data) {
              this.detailInfo = res.data
            } else {
              this.detailInfo = {}
            }
            return
          }
          throw new Error(res.msg)
        })
        .catch((e) => {
          this.$loading.hide()
          this.$notify.error({
            title: '提示',
            message: e.msg
          })
        })
    },
  }
}
</script>

PrintTable.vue

<template>
  <table
    style="border: 1px solid #000 ; border-collapse:collapse"
    width="96%"
    cellspacing="0"
    cellpadding="0"
    v-html="tableHtmlData">
  </table>
</template>

<script>
import {fixedNum} from '@/utils/utils'
export default {
  name: 'PrintTable',
  props: {
    /*
    * 此处的tableData 是一个表格的数据, 多个表格要V-for 此组件
    * 格式:[{name:'葡萄',count:'1','payment':'¥12'}]
    * tableData
    *  */
    tableData: {
      type: Array,
      default: []
    },
    /*
    * 格式:[{name:'数量',props:'count'}]
    * data中props的属性
    *  */
    propsList: {
      type: Array,
      default: []
    },
    extraData: {
      type: Array,
      default: () => []
    },
    pages: {
      type: Boolean,
      default: true
    },
    showSequenceNum: {
      type: Boolean,
      default: false
    }
  },
  created () {
    this.tableHtmlData = this._getTableHtml(this.tableData, this.propsList)
  },
  watch: {
    tableData (newValue, oldValue) {
      if (newValue === oldValue) {
        return
      }
      this.tableHtmlData = this._getTableHtml(newValue, this.propsList)
    },
    propsList (newValue, oldValue) {
      if (newValue === oldValue) {
        return
      }
      this.tableHtmlData = this._getTableHtml(this.tableData, newValue)
    },
    pages(newValue, oldValue) {
      if (newValue === oldValue) {
        return
      }
      this.tableHtmlData = this._getTableHtml(this.tableData, this.propsList)
    }
  },
  computed: {},
  data () {
    return {
      tableHtmlData: ''
    }
  },
  methods: {
    /**
     *根据propsList创建出一个table 的内部Dom的innerHtml --> string
     * */
    _getTableHtml (data, propsList) {
      // data 数据
      // propsList 表头
      if (this.showSequenceNum) {
        let hasOrder = propsList.find((item) => {
          return item.name === '序号'
        })
        if (hasOrder == null) {
          propsList.splice(0, 0, {name: '序号', props: 'index'})
        }
      }
      // 表头
      let tableHtmlStr = '<thead><tr>'
      for (let item of propsList) {
        tableHtmlStr += `<th style="border: 1px solid #000"><font size="3">${item.name}</font></th>`
      }
      tableHtmlStr += '</tr></thead>'
      // 表体
      for (let dataIndex = 0; dataIndex < data.length; dataIndex++) {
        let item = data[dataIndex]
        item.index = dataIndex + 1
        let tempLabel = '<tr>'
        for (let i = 0; i < propsList.length; i++) {
          let tempItem = ''
          if (item.hasOwnProperty(propsList[i].props)) {
            if (/^([0-9]{1,}[.][0-9]*)$/.test(item[propsList[i].props])) {
              tempItem = fixedNum(item[propsList[i].props], 4)
            } else {
              tempItem = item[propsList[i].props]
            }
          }
          // 宽
          let width = ''
          if (propsList[i].hasOwnProperty('width')) {
            width = `width: ${propsList[i].width}`
          }
          // 对齐方式
          let align = propsList[i].hasOwnProperty('align') ? propsList[i].align : 'left'
          if (i === propsList.length - 1) {
            tempLabel += `<td style="border: 1px solid #000;text-align: ${align};${width}"><font size="3">${tempItem}<font></td></tr>`
          } else {
            tempLabel += `<td style="border: 1px solid #000;text-align: ${align};${width}"><font size="3">${tempItem}</font></td>`
          }
        }
        tableHtmlStr += tempLabel
      }
      let extraLable = ''
      let colspanLength = propsList.length
      if (this.extraData.length > 0) {
        for (let i = 0; i < this.extraData.length; i++) {
          extraLable += `<tr><td colspan="${colspanLength}" style="border: 1px solid #000;text-align: left;"><font size="3"><span>${this.extraData[i].name}:</span><span style="margin-left: 20px">${this.extraData[i].data}</span><font></td></tr>`
        }
        tableHtmlStr += extraLable
      }
      if (this.pages) {
        tableHtmlStr += `<tfoot><td tdata="pageNO" colspan=2 format="##" align="left"><p align="center">第<font color="#0000FF">##</font>页</p></td>
      <td colspan="${colspanLength - 1}"  tdata="pageCount" format="##" align="left">
        <p align="left">共<font color="#0000FF">##</font>页</p></td></tfoot>`
      }
      return tableHtmlStr
    }
  }
}
</script>

winPrinter.js

// 打印类属性、方法定义
const Print = function(dom, options) {
  if (!(this instanceof Print)) return new Print(dom, options);

  this.options = this.extend(
    {
      noPrint: '.no-print'
    },
    options
  );

  if (typeof dom === 'string') {
    this.dom = document.querySelector(dom);
  } else {
    this.isDOM(dom);

    this.dom = this.isDOM(dom) ? dom : dom.$el;
  }

  this.init();
};

Print.prototype = {
  init: function() {
    var content = this.getStyle() + this.getHtml();

    this.writeIframe(content);
  },

  extend: function(obj, obj2) {
    for (var k in obj2) {
      obj[k] = obj2[k];
    }

    return obj;
  },

  getStyle: function() {
    let str = '';
    let styles = document.querySelectorAll('style,link');

    for (var i = 0; i < styles.length; i++) {
      str += styles[i].outerHTML;
    }

    str += '<style>' + (this.options.noPrint ? this.options.noPrint : '.no-print') + '{display:none;}</style>';
    str += '<style>html,body,div{height: auto!important;}</style>';

    return str;
  },

  getHtml: function() {
    var inputs = document.querySelectorAll('input');

    var textareas = document.querySelectorAll('textarea');

    var selects = document.querySelectorAll('select');

    for (var k = 0; k < inputs.length; k++) {
      if (inputs[k].type == 'checkbox' || inputs[k].type == 'radio') {
        if (inputs[k].checked == true) {
          inputs[k].setAttribute('checked', 'checked');
        } else {
          inputs[k].removeAttribute('checked');
        }
      } else if (inputs[k].type == 'text') {
        inputs[k].setAttribute('value', inputs[k].value);
      } else {
        inputs[k].setAttribute('value', inputs[k].value);
      }
    }

    for (var k2 = 0; k2 < textareas.length; k2++) {
      if (textareas[k2].type == 'textarea') {
        textareas[k2].innerHTML = textareas[k2].value;
      }
    }

    for (var k3 = 0; k3 < selects.length; k3++) {
      if (selects[k3].type == 'select-one') {
        var child = selects[k3].children;

        for (var i in child) {
          if (child[i].tagName == 'OPTION') {
            if (child[i].selected == true) {
              child[i].setAttribute('selected', 'selected');
            } else {
              child[i].removeAttribute('selected');
            }
          }
        }
      }
    }

    return this.dom.outerHTML;
  },

  writeIframe: function(content) {
    let w;
    let doc;
    let iframe = document.createElement('iframe');
    let f = document.body.appendChild(iframe);

    iframe.id = 'myIframe'; //iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";

    iframe.setAttribute('style', 'position:absolute;width:0;height:0;top:-10px;left:-10px;');

    w = f.contentWindow || f.contentDocument;

    doc = f.contentDocument || f.contentWindow.document;

    doc.open();

    doc.write(content);

    doc.close();

    var _this = this;

    iframe.onload = function() {
      _this.toPrint(w);

      setTimeout(function() {
        document.body.removeChild(iframe);
      }, 100);
    };
  },

  toPrint: function(frameWindow) {
    try {
      setTimeout(function() {
        frameWindow.focus();

        try {
          if (!frameWindow.document.execCommand('print', false, null)) {
            frameWindow.print();
          }
        } catch (e) {
          frameWindow.print();
        }

        frameWindow.close();
      }, 10);
    } catch (err) {
      console.log('err', err);
    }
  },

  isDOM:
      typeof HTMLElement === 'object'
        ? function(obj) {
          return obj instanceof HTMLElement;
        }
        : function(obj) {
          return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';
        }
};

export default Print;

utils.js

/**
 * 推荐使用此方法格式化日期
 * @description: 将时间戳转换成制定格式的日期
 * @param {fmt} 要转化成的时间格式 yyyy/MM/dd HH:mm:ss 任意变化
 * @param {_timestamp} 时间戳 默认3位长度 10位长度会乘以1000
 * @return: 格式化之后的时间
 */
export function dateFormat (fmt, _timestamp) {
  if(_timestamp.toString().length === 10) {
    _timestamp = _timestamp * 1000
  }
  let date = new Date(_timestamp)
  let ret;
  let opt = {
    "y+": date.getFullYear().toString(),
    "M+": (date.getMonth() + 1).toString(),
    "d+": date.getDate().toString(),
    "H+": date.getHours().toString(),
    "m+": date.getMinutes().toString(),
    "s+": date.getSeconds().toString()
  };
  for (let k in opt) {
    ret = new RegExp("(" + k + ")").exec(fmt);
    if (ret) {
      fmt = fmt.replace(ret[1], (ret[1].length === 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
    };
  };
  return fmt;
}
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:59:49  更:2022-03-30 18:59:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:43:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码