基於vue的會計憑證打印

業務需求:財務ERP系統會計憑證的打印,科目打印需自動拼接上輔助覈算,如科目有外幣需打印外幣,對於長憑證一張A4紙打印2張憑證,每張憑證固定5行。
須要打印的憑證:html

圖片描述

打印效果顯示:vue

圖片描述

圖片描述

有外幣:ios

圖片描述

圖片描述

實現步驟:npm

  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) {
          });
      })
    }
  }
}

打印printVouchercanvas

//打印憑證
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.vueaxios

<!-- 打印模板 -->
    <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;
          }
        })
      })
    }
  }
};
相關文章
相關標籤/搜索