diff --git a/package.json b/package.json index 2e764939..5ebe38a9 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "js-beautify": "1.13.0", "js-cookie": "3.0.1", "jsencrypt": "3.0.0-rc.1", + "jspdf": "^3.0.1", "jszip": "^3.10.1", "nprogress": "0.2.0", "print-js": "^1.6.0", diff --git a/src/views/business/businessHandlingRecord/index.vue b/src/views/business/businessHandlingRecord/index.vue index 53d6d1cc..64494d35 100644 --- a/src/views/business/businessHandlingRecord/index.vue +++ b/src/views/business/businessHandlingRecord/index.vue @@ -254,7 +254,6 @@ 打 印 - 取 消 @@ -264,6 +263,9 @@ @@ -321,7 +563,7 @@ export default { .no-print { display: none; } - + .print-content { /* 打印内容的样式 */ } diff --git a/src/views/material/lease/apply/component/homeApply.vue b/src/views/material/lease/apply/component/homeApply.vue index 980a442b..e11faa4f 100644 --- a/src/views/material/lease/apply/component/homeApply.vue +++ b/src/views/material/lease/apply/component/homeApply.vue @@ -326,6 +326,9 @@ import { import vueEasyPrint from "vue-easy-print"; import printJS from 'print-js'; +import html2canvas from 'html2canvas'; +import jsPDF from 'jspdf'; +import request from "@/utils/request"; export default { name: "Home", @@ -428,6 +431,8 @@ export default { this.multiple = !selection.length; }, + + //是否可用勾选框 selectable(row) { if (row.taskStatus == 1) { @@ -559,12 +564,134 @@ export default { //出库检验单打印 printCheck() { - printJS({ - printable: 'checkId', - type: 'html', - targetStyles: ['*'], - maxWidth:'1400' - // 其他配置选项 + const element = document.getElementById('checkId'); + + // 确保元素存在 + if (!element) { + this.$message.error('未找到要打印的元素'); + return; + } + + this.$modal.loading('正在生成单据,请稍候...'); + + // 查找页面中所有图片并预加载 + const images = element.querySelectorAll('img'); + const imagePromises = []; + + // 为每个图片创建加载或错误处理的Promise + images.forEach(img => { + // 如果图片已经加载完成,不需要处理 + if (img.complete) return; + + const promise = new Promise((resolve) => { + const originalSrc = img.src; + + // 图片加载成功 + img.onload = function() { + resolve(); + }; + + // 图片加载失败,使用空白图片替代 + img.onerror = function() { + console.log('图片加载失败,使用空白图片替代:', originalSrc); + img.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; // 透明1x1像素图片 + resolve(); + }; + }); + + imagePromises.push(promise); + }); + + // 等待所有图片加载完成或失败后再生成PDF + Promise.all(imagePromises).then(() => { + // 使用html2canvas将DOM元素转换为canvas + html2canvas(element, { + scale: 2, // 提高清晰度 + useCORS: true, // 允许加载跨域图片 + allowTaint: true, + ignoreElements: (element) => { + // 忽略所有图片加载错误 + return element.nodeName === 'IMG' && !element.complete; + }, + logging: false, // 关闭日志记录 + imageTimeout: 3000, // 图片加载超时时间 + backgroundColor: '#ffffff' + }).then(canvas => { + // 创建PDF文档 + const pdf = new jsPDF('p', 'mm', 'a4'); + + // 获取canvas的宽度和高度 + const imgWidth = 210; // A4纸的宽度(mm) + const pageHeight = 297; // A4纸的高度(mm) + const imgHeight = canvas.height * imgWidth / canvas.width; + + // 将canvas转换为图片 + const imgData = canvas.toDataURL('image/jpeg', 1.0); + + // 添加图片到PDF + pdf.addImage(imgData, 'JPEG', 0, 0, imgWidth, imgHeight); + + // 生成PDF文件名 + const fileName = `出库检验单_${this.checkDataInfo.leaseProject || '未命名'}_${new Date().getTime()}.pdf`; + + // 将PDF转换为Blob对象 + const pdfBlob = pdf.output('blob'); + + // 创建FormData对象用于上传 + const formData = new FormData(); + formData.append('file', pdfBlob, fileName); + formData.append('id', this.idTemp); + + // 上传到服务器 + this.$modal.closeLoading(); + + // 调用上传API - 使用request + request.post('/material/lease_apply_info/uploadCheckPdf', formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }).then(response => { + if (response.code === 200) { + this.$modal.msgSuccess('单据文件已保存到服务器'); + + // 上传成功后执行打印 + printJS({ + printable: 'checkId', + type: 'html', + targetStyles: ['*'], + maxWidth:'1400' + }); + } else { + this.$modal.msgError('保存单据文件失败'); + + // 即使保存失败也执行打印 + printJS({ + printable: 'checkId', + type: 'html', + targetStyles: ['*'], + maxWidth:'1400' + }); + } + }).catch(() => { + this.$modal.msgError('上传单据文件时发生错误'); + + // 即使上传失败也执行打印 + printJS({ + printable: 'checkId', + type: 'html', + targetStyles: ['*'], + maxWidth:'1400' + }); + }); + }).catch(error => { + this.$modal.closeLoading(); + this.$modal.msgError('生成单据时发生错误'); + console.error('生成PDF错误:', error); + }); + }).catch(error => { + this.$modal.closeLoading(); + this.$modal.msgError('处理图片时发生错误'); + console.error('处理图片错误:', error); }); }, @@ -579,20 +706,256 @@ export default { this.getListViewInfo = row.maCodeVoList; }, - //打印 + //打印明细 printView() { - this.$refs.remarksPrintRefView.print(); + const element = document.getElementById('remarksPrintRefView'); + + // 确保元素存在 + if (!element) { + this.$message.error('未找到要打印的元素'); + return; + } + + this.$modal.loading('正在生成单据,请稍候...'); + + // 查找页面中所有图片并预加载 + const images = element.querySelectorAll('img'); + const imagePromises = []; + + // 为每个图片创建加载或错误处理的Promise + images.forEach(img => { + // 如果图片已经加载完成,不需要处理 + if (img.complete) return; + + const promise = new Promise((resolve) => { + const originalSrc = img.src; + + // 图片加载成功 + img.onload = function() { + resolve(); + }; + + // 图片加载失败,使用空白图片替代 + img.onerror = function() { + console.log('图片加载失败,使用空白图片替代:', originalSrc); + img.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; // 透明1x1像素图片 + resolve(); + }; + }); + + imagePromises.push(promise); + }); + + // 等待所有图片加载完成或失败后再生成PDF + Promise.all(imagePromises).then(() => { + // 使用html2canvas将DOM元素转换为canvas + html2canvas(element, { + scale: 2, // 提高清晰度 + useCORS: true, // 允许加载跨域图片 + allowTaint: true, + ignoreElements: (element) => { + // 忽略所有图片加载错误 + return element.nodeName === 'IMG' && !element.complete; + }, + logging: false, // 关闭日志记录 + imageTimeout: 3000, // 图片加载超时时间 + backgroundColor: '#ffffff' + }).then(canvas => { + // 创建PDF文档 + const pdf = new jsPDF('p', 'mm', 'a4'); + + // 获取canvas的宽度和高度 + const imgWidth = 210; // A4纸的宽度(mm) + const pageHeight = 297; // A4纸的高度(mm) + const imgHeight = canvas.height * imgWidth / canvas.width; + + // 将canvas转换为图片 + const imgData = canvas.toDataURL('image/jpeg', 1.0); + + // 添加图片到PDF + pdf.addImage(imgData, 'JPEG', 0, 0, imgWidth, imgHeight); + + // 生成PDF文件名 + const fileName = `领料单编号明细_${new Date().getTime()}.pdf`; + + // 将PDF转换为Blob对象 + const pdfBlob = pdf.output('blob'); + + // 创建FormData对象用于上传 + const formData = new FormData(); + formData.append('file', pdfBlob, fileName); + formData.append('id', this.leaseApplyData.leaseProjectId); + + // 上传到服务器 + this.$modal.closeLoading(); + + // 调用上传API - 使用request + request.post('/material/lease_apply_info/uploadDetailPdf', formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }).then(response => { + if (response.code === 200) { + this.$modal.msgSuccess('单据文件已保存到服务器'); + + // 上传成功后执行打印 + this.$refs.remarksPrintRefView.print(); + } else { + this.$modal.msgError('保存单据文件失败'); + + // 即使保存失败也执行打印 + this.$refs.remarksPrintRefView.print(); + } + }).catch(() => { + this.$modal.msgError('上传单据文件时发生错误'); + + // 即使上传失败也执行打印 + this.$refs.remarksPrintRefView.print(); + }); + }).catch(error => { + this.$modal.closeLoading(); + this.$modal.msgError('生成单据时发生错误'); + console.error('生成单据错误:', error); + }); + }).catch(error => { + this.$modal.closeLoading(); + this.$modal.msgError('处理图片时发生错误'); + console.error('处理图片错误:', error); + }); }, //打印 print() { - // this.$refs.remarksPrintRef.print(); - printJS({ - printable: 'checkIdTwo', - type: 'html', - targetStyles: ['*'], - maxWidth:'1400' - // 其他配置选项 + console.log("正在执行领料单打印操作"); + + const element = document.getElementById('checkIdTwo'); + + // 确保元素存在 + if (!element) { + this.$message.error('未找到要打印的元素'); + return; + } + + this.$modal.loading('正在生成单据,请稍候...'); + + // 查找页面中所有图片并预加载 + const images = element.querySelectorAll('img'); + const imagePromises = []; + + // 为每个图片创建加载或错误处理的Promise + images.forEach(img => { + // 如果图片已经加载完成,不需要处理 + if (img.complete) return; + + const promise = new Promise((resolve) => { + const originalSrc = img.src; + + // 图片加载成功 + img.onload = function() { + resolve(); + }; + + // 图片加载失败,使用空白图片替代 + img.onerror = function() { + console.log('图片加载失败,使用空白图片替代:', originalSrc); + img.src = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; // 透明1x1像素图片 + resolve(); + }; + }); + + imagePromises.push(promise); + }); + + // 等待所有图片加载完成或失败后再生成PDF + Promise.all(imagePromises).then(() => { + // 使用html2canvas将DOM元素转换为canvas + html2canvas(element, { + scale: 2, // 提高清晰度 + useCORS: true, // 允许加载跨域图片 + allowTaint: true, + ignoreElements: (element) => { + // 忽略所有图片加载错误 + return element.nodeName === 'IMG' && !element.complete; + }, + logging: false, // 关闭日志记录 + imageTimeout: 3000, // 图片加载超时时间 + backgroundColor: '#ffffff' + }).then(canvas => { + // 创建PDF文档 + const pdf = new jsPDF('p', 'mm', 'a4'); + + // 获取canvas的宽度和高度 + const imgWidth = 210; // A4纸的宽度(mm) + const pageHeight = 297; // A4纸的高度(mm) + const imgHeight = canvas.height * imgWidth / canvas.width; + + // 将canvas转换为图片 + const imgData = canvas.toDataURL('image/jpeg', 1.0); + + // 添加图片到PDF + pdf.addImage(imgData, 'JPEG', 0, 0, imgWidth, imgHeight); + + // 生成PDF文件名 + const fileName = `领料单_${this.leaseApplyData.code || '未命名'}_${new Date().getTime()}.pdf`; + + // 将PDF转换为Blob对象 + const pdfBlob = pdf.output('blob'); + + // 创建FormData对象用于上传 + const formData = new FormData(); + formData.append('file', pdfBlob, fileName); + formData.append('id', this.leaseApplyData.leaseProjectId); + + // 上传到服务器 + this.$modal.closeLoading(); + + // 调用上传API - 使用request + request.post('/material/lease_apply_info/uploadPdf', formData, { + headers: { + 'Content-Type': 'multipart/form-data' + } + }).then(response => { + if (response.code === 200) { + this.$modal.msgSuccess('单据文件已保存到服务器'); + + // 上传成功后执行打印 + printJS({ + printable: 'checkIdTwo', + type: 'html', + targetStyles: ['*'], + maxWidth:'1400' + }); + } else { + this.$modal.msgError('保存单据文件失败'); + + // 即使保存失败也执行打印 + printJS({ + printable: 'checkIdTwo', + type: 'html', + targetStyles: ['*'], + maxWidth:'1400' + }); + } + }).catch(() => { + this.$modal.msgError('上传单据文件时发生错误'); + + // 即使上传失败也执行打印 + printJS({ + printable: 'checkIdTwo', + type: 'html', + targetStyles: ['*'], + maxWidth:'1400' + }); + }); + }).catch(error => { + this.$modal.closeLoading(); + this.$modal.msgError('生成单据时发生错误'); + console.error('生成单据错误:', error); + }); + }).catch(error => { + this.$modal.closeLoading(); + this.$modal.msgError('处理图片时发生错误'); + console.error('处理图片错误:', error); }); },