基于vue的会计凭证打印

业务需求:财务ERP系统会计凭证的打印,科目打印需自动拼接上辅助核算,如科目有外币需打印外币,对于长凭证一张A4纸打印2张凭证,每张凭证固定5行。
需要打印的凭证:

《基于vue的会计凭证打印》

打印效果显示:

《基于vue的会计凭证打印》

《基于vue的会计凭证打印》

有外币:

《基于vue的会计凭证打印》

《基于vue的会计凭证打印》

实现步骤:

  1. 安装2个依赖 npm install jspdf html2canvas -D
  2. 基于jspdf与html2canvas封装一个全局打印方法,查询凭证拼凑凭证数据(父组件),打印的模板(子组件)。具体实现代码如下:
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
import axios from 'axios' //把pdf传给后台
import qs from 'qs'//需要转换 用JOSN.stringify()不行
export default {
  install(Vue, options) {
    Vue.prototype.getPdf = function (dom) {
      html2Canvas(document.querySelector(dom), {
        allowTaint: true
      }).then(function (canvas) {
        let contentWidth = canvas.width
        let contentHeight = canvas.height
        //一页pdf显示html页面生成的canvas高度;
        let pageHeight = contentWidth / 595.28 * 841.89
        //未生成pdf的html页面高度
        let leftHeight = contentHeight
        //页面偏移
        let position = 0
        //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
        let imgWidth = 595.28
        let imgHeight = 592.28 / contentWidth * contentHeight
        let pageData = canvas.toDataURL('image/jpeg', 1.0)
        // 三个参数,第一个方向,第二个尺寸,第三个尺寸格式
        let PDF = new JsPDF('', 'pt', 'a4')
        //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
        //当内容未超过pdf一页显示的范围,无需分页
        if (leftHeight < pageHeight) {
          PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
        } else {
          while (leftHeight > 0) {
            PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
            leftHeight -= pageHeight
            position -= 841.89
            //避免添加空白页
            if (leftHeight > 0) {
              PDF.addPage()
            }
          }
        }
        var instance = axios.create({
          timeout: 10000,
          headers: { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' }
        });
        instance.post(axios.defaults.baseURL + '/file/savepdf', qs.stringify({
          //output输出文件流,PDF.output('datauristring')输出base64文件流。
          file: PDF.output('datauristring')//base64的文件流
        }))
          .then(function (response) {
            window.open(axios.defaults.baseURL + '/file/showpdf/' + response.data.data.uri)//在新的窗口打开
            // let dom=document.createElement('a');
            // dom.setAttribute('href',axios.defaults.baseURL+'/file/showpdf/'+response.data.data.uri);
            // dom.setAttribute('target','_blank');
            // dom.click();//模拟新的窗口打开
          })
          .catch(function (error) {
          });
      })
    }
  }
}

打印printVoucher

//打印凭证
printVoucher() {
  //日期
  let Voucherdate = new Date(this.pickerOptionsValue);
  let tableData = this.childData; //整个视图数据
  let trData = this.childData.trData; //列数据
  //拼凑数据供打印使用,凭证头,尾信息
  this.voucherHFdata = {
    voucherTitle: "记账凭证", //记账凭证
    billNum: this.billNum, //附件数
    accbookName: this.$store.state.accbookName, //账套名
    date:Voucherdate.getFullYear() + "-" +(Voucherdate.getMonth() + 1) +"-" +Voucherdate.getDate(), //日期
    voucherNumber: this.voucherName + "-" + this.voucherNumberValue, //凭证号:大-16
    lotal: tableData.DeCr_Total, //合计
    supervisor: "", //主管
    cashier: "", //出纳
    auditor: "", //审核
    producer: this.$store.state.voucherProducer //制单
  };
  //需打印的列数据过滤
  // let listData = [];
  trData.forEach((n, i) => {
    //科目是否有辅助核算,有辅助核算,拼接上辅助核算eg:1001 库存现金_销售部
    let subjectVal =
      n.subject.val +
      (n.subject.auxData.length > 0 ? "_" : "") +
      n.subject.auxData
        .map(item1 => {
          return (
            item1.options.filter(item2 => {
              if (item1.value === item2.uid) return item2;
            })[0].name || ""
          );
        })
        .join("_");
    //是否有外币,没有外币显示空。有外币匹配过滤出外币名称eg:RMB
    let curName =
      n.currency.currencyOptions
        .filter(item => {
          if (item.value === n.currency.currencyValue) return item;
        })
        .map(item => {
          return item.label;
        })[0] || "";
    this.listData[i] = {
      abstract: n.abstract.val, //摘要
      subject: subjectVal, //科目是否有辅助核算,有辅助核算,拼接上辅助核算
      currencyName: curName, //是否有外币,没有外币显示空。有外币匹配过滤出外币名称eg:RMB
      showCur: n.currency.show,//false不显示
      exchangeRate: n.currency.exchangeRate, //汇率
      original: n.currency.original, //原币
      deVal: n.DeCr.De_val, //借方金额
      crVal: n.DeCr.Cr_val//贷方金额
    };
  });
  this.$refs.print.printvoucher(); //打印调动子子组件的方法***
},

模板:printVoucher.vue

<!-- 打印模板 -->
    <print-voucher :voucherHFdata='voucherHFdata' :listData='listData' ref="print"></print-voucher>
<!-- 打印模板 -->
export default {
  name: "printVoucher",

  props: ["voucherHFdata", "listData"],//父组件的凭证头尾和列集合数据
  data() {
    return {
      // htmlTitle: "voucher"
      tableData:[],
      hascur:false,//是否有外币,操作2种模板
    };
  },
  mounted() {},
  methods: {
    printvoucher() {
      this.voucher5tr(
      //解决异步
        setTimeout(()=>{
          this.getPdf("#printVoucher");
        },1000)
      );
    },

    //每5列切成一张凭证
   voucher5tr() {
      let tr5 = []; //[[{},{},{},{},{}]]一维变多维
      let tr = this.listData;
      let index = 0;
      tr.forEach((n, i) => {
        if (!tr5[index]) {
          tr5[index] = [];
        }
        tr5[index].push(n);
        if (tr5[index].length === 5) {
          index++;
        }
      });
      let last = tr5[tr5.length - 1];
      for (let i = 0,l = 5 - last.length; i < l; i++) {
        last.push({
          abstract: "", //摘要
          showCur:false,//外币不显示
          subject: "", //科目是否有辅助核算,有辅助核算,拼接上辅助核算
          currencyName: "", //是否有外币,没有外币显示空。有外币匹配过滤出外币名称eg:RMB
          exchangeRate: "", //汇率
          original: "", //原币
          crVal: "", //贷方金额
          deVal: "" //借方金额
        });
      }
      this.tableData=tr5;
      this.tableData.forEach(n=>{
        n.forEach(n1=>{
          if(n1.showCur===true){
            this.hascur=true;
          }
        })
      })
    }
  }
};
    原文作者:清减半夏时光
    原文地址: https://segmentfault.com/a/1190000014289780
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞