功能优化:实现单据PDF生成功能并上传到服务器

This commit is contained in:
syruan 2025-06-13 16:35:07 +08:00
parent 5caa60fe25
commit aaaeee7b5b
4 changed files with 745 additions and 68 deletions

View File

@ -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",

View File

@ -254,7 +254,6 @@
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="print"> </el-button>
<!-- <el-button type="primary" @click="">查看PDF</el-button> -->
<el-button @click="dialogVisible = false"> </el-button>
</span>
</el-dialog>
@ -264,6 +263,9 @@
<script>
import printJS from 'print-js'
import { getLeaseTaskList, deleteLeaseTask, getLeaseTask, getCodePDF } from '@/api/business/index'
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
import request from "@/utils/request";
export default {
name: 'Index',
@ -420,17 +422,86 @@ export default {
},
//
print() {
const element = document.getElementById('print-content');
//
if (!element) {
this.$message.error('未找到要打印的元素');
return;
}
this.$modal.loading('正在生成单据,请稍候...');
// 使html2canvasDOMcanvas
html2canvas(element, {
scale: 2, //
useCORS: true, //
allowTaint: true,
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.dialogForm.code || '未命名'}_${new Date().getTime()}.pdf`;
// PDFBlob
const pdfBlob = pdf.output('blob');
// FormData
const formData = new FormData();
formData.append('file', pdfBlob, fileName);
formData.append('id', this.dialogForm.leaseProjectId);
//
this.$modal.closeLoading();
// API - 使request
request.post('/material/leaseTask/uploadPdf', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
if (response.code === 200) {
this.$modal.msgSuccess('单据文件已保存到服务器');
//
printJS({
printable: 'print-content',
type: 'html', //
// targetStyles: ['*'], //
scanStyles: false, //
// css: [
// 'https://unpkg.com/element-ui/lib/theme-chalk/index.css' // Element UI
// ],
type: 'html',
scanStyles: false,
maxWidth: '1400'
//
})
});
} else {
this.$modal.msgError('保存单据文件失败');
}
}).catch(() => {
this.$modal.msgError('上传单据文件时发生错误');
// 使
printJS({
printable: 'print-content',
type: 'html',
scanStyles: false,
maxWidth: '1400'
});
});
}).catch(error => {
this.$modal.closeLoading();
this.$modal.msgError('生成单据时发生错误');
console.error('生成单据错误:', error);
});
},
//
async getDialogContent(row) {

View File

@ -178,6 +178,10 @@ import {
getBackApplyInfo,
updatePrintStatus,
} from '@/api/back/index.js'
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
import printJS from 'print-js';
import request from "@/utils/request";
// import { getViewByApply,materialReturnNoteByApply } from "@/api/claimAndRefund/return.js"
export default {
components: { vueEasyPrint },
@ -246,26 +250,151 @@ export default {
cancel() {
this.dialogShowFlag = false;
},
print() {
// this.$refs.printRef.print();
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(() => {
// 使html2canvasDOMcanvas
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.rowObj.code || '未命名'}_${new Date().getTime()}.pdf`;
// PDFBlob
const pdfBlob = pdf.output('blob');
// FormData
const formData = new FormData();
formData.append('file', pdfBlob, fileName);
formData.append('id', this.rowObj.proId);
//
this.$modal.closeLoading();
// API - 使request
request.post('/material/back_apply_info/uploadPdf', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
if (response.code === 200) {
this.$modal.msgSuccess('单据文件已保存到服务器');
//
printJS({
printable: 'checkId',
type: 'html',
targetStyles: ['*'],
maxWidth:'1400'
//
});
console.log(this.rowObj)
//
updatePrintStatus(this.rowObj.id).then(response => {
if (response.code === 200) {
//this.$modal.msgSuccess("");
//
this.$emit('refresh');
}
}).catch(() => {
this.$modal.msgError("打印状态更新失败");
});
} else {
this.$modal.msgError('保存单据文件失败');
}
}).catch(() => {
this.$modal.msgError('上传单据文件时发生错误');
// 使
printJS({
printable: 'checkId',
type: 'html',
targetStyles: ['*'],
maxWidth:'1400'
});
//
updatePrintStatus(this.rowObj.id).then(response => {
if (response.code === 200) {
//
this.$emit('refresh');
}
}).catch(() => {
this.$modal.msgError("打印状态更新失败");
});
});
}).catch(error => {
this.$modal.closeLoading();
this.$modal.msgError('生成单据时发生错误');
console.error('生成单据错误:', error);
});
}).catch(error => {
this.$modal.closeLoading();
this.$modal.msgError('处理图片时发生错误');
console.error('处理图片错误:', error);
});
},
checkDetail(row) {
this.title = '查看'
@ -273,13 +402,126 @@ export default {
this.open = true
},
remarksPrint() {
// this.$refs.remarksPrintRef.print();
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(() => {
// 使html2canvasDOMcanvas
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.rowObj.code || '未命名'}_${new Date().getTime()}.pdf`;
// PDFBlob
const pdfBlob = pdf.output('blob');
// FormData
const formData = new FormData();
formData.append('file', pdfBlob, fileName);
formData.append('id', this.rowObj.proId);
//
this.$modal.closeLoading();
// API - 使request
request.post('/material/back_apply_info/uploadPdf', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(response => {
if (response.code === 200) {
this.$modal.msgSuccess('单据PDF文件已保存到服务器');
//
printJS({
printable: 'checkIdTwo',
type: 'html',
targetStyles: ['*'],
maxWidth:'1400'
//
});
} else {
this.$modal.msgError('保存明细单据文件失败');
}
}).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);
});
},

View File

@ -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() {
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(() => {
// 使html2canvasDOMcanvas
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`;
// PDFBlob
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() {
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(() => {
// 使html2canvasDOMcanvas
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`;
// PDFBlob
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();
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(() => {
// 使html2canvasDOMcanvas
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`;
// PDFBlob
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);
});
},