基于vue的打印

業(yè)務(wù)需求:財(cái)務(wù)ERP系統(tǒng)會(huì)計(jì)憑證的打印,科目打印需自動(dòng)拼接上輔助核算,如科目有外幣需打印外幣,對(duì)于長(zhǎng)憑證一張A4紙打印2張憑證,每張憑證固定5行。

大致實(shí)現(xiàn)思路:先把需要打印的頁(yè)面用canva畫(huà)轉(zhuǎn)成pdf,傳給后端保存,之后下載PDF預(yù)覽打印結(jié)果。

需要打印的憑證:


打印結(jié)果預(yù)覽:

有外幣:


**實(shí)現(xiàn)步驟:**

1. 安裝2個(gè)依賴 npm install jspdf html2canvas -D

2. 基于jspdf與html2canvas封裝一個(gè)全局打印方法,查詢憑證拼湊憑證數(shù)據(jù)(父組件),打印的模板(子組件)。具體實(shí)現(xiàn)代碼如下:

```

import html2Canvas from 'html2canvas'

import JsPDF from 'jspdf'

import axios from 'axios' //把pdf傳給后臺(tái)

import qs from 'qs'//需要轉(zhuǎn)換 用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

? ? ? ? //一頁(yè)pdf顯示html頁(yè)面生成的canvas高度;

? ? ? ? let pageHeight = contentWidth / 595.28 * 841.89

? ? ? ? //未生成pdf的html頁(yè)面高度

? ? ? ? let leftHeight = contentHeight

? ? ? ? //頁(yè)面偏移

? ? ? ? let position = 0

? ? ? ? //a4紙的尺寸[595.28,841.89],html頁(yè)面生成的canvas在pdf中圖片的寬高

? ? ? ? let imgWidth = 595.28

? ? ? ? let imgHeight = 592.28 / contentWidth * contentHeight

? ? ? ? let pageData = canvas.toDataURL('image/jpeg', 1.0)

? ? ? ? // 三個(gè)參數(shù),第一個(gè)方向,第二個(gè)尺寸,第三個(gè)尺寸格式

? ? ? ? let PDF = new JsPDF('', 'pt', 'a4')

? ? ? ? //有兩個(gè)高度需要區(qū)分,一個(gè)是html頁(yè)面的實(shí)際高度,和生成pdf的頁(yè)面高度(841.89)

? ? ? ? //當(dāng)內(nèi)容未超過(guò)pdf一頁(yè)顯示的范圍,無(wú)需分頁(yè)

? ? ? ? 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

? ? ? ? ? ? //避免添加空白頁(yè)

? ? ? ? ? ? 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)//在新的窗口打開(kāi)

? ? ? ? ? ? // let dom=document.createElement('a');

? ? ? ? ? ? // dom.setAttribute('href',axios.defaults.baseURL+'/file/showpdf/'+response.data.data.uri);

? ? ? ? ? ? // dom.setAttribute('target','_blank');

? ? ? ? ? ? // dom.click();//模擬新的窗口打開(kāi)

? ? ? ? ? })

? ? ? ? ? .catch(function (error) {

? ? ? ? ? });

? ? ? })

? ? }

? }

}

```

3. 調(diào)用function

```

//打印憑證

printVoucher() {

? //日期

? let Voucherdate = new Date(this.pickerOptionsValue);

? let tableData = this.childData; //整個(gè)視圖數(shù)據(jù)

? let trData = this.childData.trData; //列數(shù)據(jù)

? //拼湊數(shù)據(jù)供打印使用,憑證頭,尾信息

? this.voucherHFdata = {

? ? voucherTitle: "記賬憑證", //記賬憑證

? ? billNum: this.billNum, //附件數(shù)

? ? accbookName: this.$store.state.accbookName, //賬套名

? ? date:Voucherdate.getFullYear() + "-" +(Voucherdate.getMonth() + 1) +"-" +Voucherdate.getDate(), //日期

? ? voucherNumber: this.voucherName + "-" + this.voucherNumberValue, //憑證號(hào):大-16

? ? lotal: tableData.DeCr_Total, //合計(jì)

? ? supervisor: "", //主管

? ? cashier: "", //出納

? ? auditor: "", //審核

? ? producer: this.$store.state.voucherProducer //制單

? };

? //需打印的列數(shù)據(jù)過(guò)濾

? // let listData = [];

? trData.forEach((n, i) => {

? ? //科目是否有輔助核算,有輔助核算,拼接上輔助核算eg:1001 庫(kù)存現(xiàn)金_銷(xiāo)售部

? ? 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("_");

? ? //是否有外幣,沒(méi)有外幣顯示空。有外幣匹配過(guò)濾出外幣名稱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, //是否有外幣,沒(méi)有外幣顯示空。有外幣匹配過(guò)濾出外幣名稱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(); //打印調(diào)動(dòng)子子組件的方法***

},

```


**模板:printVoucher.vue**

```

<!-- 打印模板 -->

? ? <print-voucher :voucherHFdata='voucherHFdata' :listData='listData' ref="print"></print-voucher>

<!-- 打印模板 -->

```

```

export default {

? name: "printVoucher",

? props: ["voucherHFdata", "listData"],//父組件的憑證頭尾和列集合數(shù)據(jù)

? 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: "", //是否有外幣,沒(méi)有外幣顯示空。有外幣匹配過(guò)濾出外幣名稱eg:RMB

? ? ? ? ? exchangeRate: "", //匯率

? ? ? ? ? original: "", //原幣

? ? ? ? ? crVal: "", //貸方金額

? ? ? ? ? deVal: "" //借方金額

? ? ? ? });

? ? ? }

? ? ? this.tableData=tr5;

? ? ? this.tableData.forEach(n=>{

? ? ? ? n.forEach(n1=>{

? ? ? ? ? if(n1.showCur===true){

? ? ? ? ? ? this.hascur=true;

? ? ? ? ? }

? ? ? ? })

? ? ? })

? ? }

? }

};

```

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容