计划工序管理-物料单下载 2.1

zhc4dev
zhc077 2 years ago
parent 3be5a51fef
commit ff86415e10
  1. 63
      ant-design-vue-jeecg/package.json
  2. 90
      ant-design-vue-jeecg/src/mixins/htmlToPdf.js
  3. 90
      ant-design-vue-jeecg/src/utils/htmlToPdf.js
  4. 4
      ant-design-vue-jeecg/src/views/productplan/ProductplanManage.vue
  5. 28
      ant-design-vue-jeecg/src/views/productplan/TestPdf.vue
  6. 116
      ant-design-vue-jeecg/src/views/productplan/ZyPlanWuLiaoDataDetail.vue

@ -10,50 +10,54 @@
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"ant-design-vue": "^1.7.2",
"@antv/data-set": "^0.11.4", "@antv/data-set": "^0.11.4",
"viser-vue": "^2.4.8", "@jeecg/antd-online-mini": "^3.4.3-beta2",
"@jiaminghi/data-view": "^2.10.0",
"@tinymce/tinymce-vue": "2.1.0",
"@toast-ui/editor": "^2.1.2",
"ant-design-vue": "^1.7.2",
"area-data": "^5.0.6",
"axios": "^0.18.0", "axios": "^0.18.0",
"china-area-data": "^5.0.1",
"clipboard": "^2.0.4",
"codemirror": "^5.46.0",
"cron-parser": "^2.10.0",
"dayjs": "^1.8.0", "dayjs": "^1.8.0",
"dircountdown": "^1.1.0",
"dom-align": "1.12.0",
"echarts": "^5.3.0",
"element-ui": "^2.15.6",
"enquire.js": "^2.1.6", "enquire.js": "^2.1.6",
"html2canvas": "^1.4.1",
"jquery": "^3.6.0",
"js-cookie": "^2.2.0", "js-cookie": "^2.2.0",
"jspdf": "^2.5.1",
"lodash.get": "^4.4.2", "lodash.get": "^4.4.2",
"lodash.pick": "^4.4.0", "lodash.pick": "^4.4.0",
"md5": "^2.2.1", "md5": "^2.2.1",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"qiankun": "^2.5.1",
"qs": "^6.10.3",
"tinymce": "5.4.1",
"viser-vue": "^2.4.8",
"vue": "^2.6.10", "vue": "^2.6.10",
"vue-area-linkage": "^5.1.0",
"vue-cropper": "^0.5.4", "vue-cropper": "^0.5.4",
"vue-i18n": "^8.7.0", "vue-i18n": "^8.7.0",
"vue-loader": "^15.7.0", "vue-loader": "^15.7.0",
"vue-ls": "^3.2.0", "vue-ls": "^3.2.0",
"vue-router": "^3.0.1",
"vuex": "^3.1.0",
"vue-print-nb-jeecg": "^1.0.10",
"clipboard": "^2.0.4",
"vue-photo-preview": "^1.1.3", "vue-photo-preview": "^1.1.3",
"vue-print-nb-jeecg": "^1.0.10",
"vue-router": "^3.0.1",
"vue-splitpane": "^1.0.4", "vue-splitpane": "^1.0.4",
"vuedraggable": "^2.20.0", "vuedraggable": "^2.20.0",
"codemirror": "^5.46.0", "vuex": "^3.1.0",
"@tinymce/tinymce-vue": "2.1.0",
"tinymce": "5.4.1",
"@toast-ui/editor": "^2.1.2",
"vue-area-linkage": "^5.1.0",
"china-area-data": "^5.0.1",
"dom-align": "1.12.0",
"xe-utils": "2.4.8",
"vxe-table": "2.9.13", "vxe-table": "2.9.13",
"vxe-table-plugin-antd": "1.8.10", "vxe-table-plugin-antd": "1.8.10",
"cron-parser": "^2.10.0", "xe-utils": "2.4.8",
"qiankun": "^2.5.1",
"xss": "^1.0.13", "xss": "^1.0.13",
"html2canvas": "~1.0.0-rc.4",
"@jiaminghi/data-view": "^2.10.0", "jspdf": "^2.5.1"
"area-data": "^5.0.6",
"dircountdown": "^1.1.0",
"echarts": "^5.3.0",
"element-ui": "^2.15.6",
"jquery": "^3.6.0",
"qs": "^6.10.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/polyfill": "^7.2.5", "@babel/polyfill": "^7.2.5",
@ -62,13 +66,15 @@
"@vue/cli-service": "^3.3.0", "@vue/cli-service": "^3.3.0",
"@vue/eslint-config-standard": "^4.0.0", "@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "7.2.3", "babel-eslint": "7.2.3",
"compression-webpack-plugin": "^3.1.0",
"eslint": "^5.16.0", "eslint": "^5.16.0",
"eslint-plugin-vue": "^5.1.0", "eslint-plugin-vue": "^5.1.0",
"html-webpack-plugin": "^4.2.0",
"less": "^3.9.0", "less": "^3.9.0",
"less-loader": "^4.1.0", "less-loader": "^4.1.0",
"vue-template-compiler": "^2.6.10", "vue-template-compiler": "^2.6.10",
"html-webpack-plugin": "^4.2.0", "html2canvas": "~1.0.0-rc.4",
"compression-webpack-plugin": "^3.1.0" "jspdf": "^2.5.1"
}, },
"eslintConfig": { "eslintConfig": {
"root": true, "root": true,
@ -106,7 +112,10 @@
"vue/html-closing-bracket-newline": 0, "vue/html-closing-bracket-newline": 0,
"vue/no-parsing-error": 0, "vue/no-parsing-error": 0,
"no-tabs": 0, "no-tabs": 0,
"indent": ["off", 2], "indent": [
"off",
2
],
"no-console": 0, "no-console": 0,
"space-before-function-paren": 0 "space-before-function-paren": 0
} }

@ -0,0 +1,90 @@
import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';
/**
* @param ele 要生成 pdf 的DOM元素容器
* @param padfName PDF文件生成后的文件名字
* */
function downloadPDF(ele, pdfName){
let eleW = ele.offsetWidth;// 获得该容器的宽
let eleH = ele.offsetHeight;// 获得该容器的高
let eleOffsetTop = ele.offsetTop; // 获得该容器到文档顶部的距离
let eleOffsetLeft = ele.offsetLeft; // 获得该容器到文档最左的距离
var canvas = document.createElement("canvas");
var abs = 0;
let win_in = document.documentElement.clientWidth || document.body.clientWidth; // 获得当前可视窗口的宽度(不包含滚动条)
let win_out = window.innerWidth; // 获得当前窗口的宽度(包含滚动条)
if(win_out>win_in){
// abs = (win_o - win_i)/2; // 获得滚动条长度的一半
abs = (win_out - win_in)/2; // 获得滚动条宽度的一半
// console.log(a, '新abs');
}
canvas.width = eleW * 2; // 将画布宽&&高放大两倍
canvas.height = eleH * 2;
var context = canvas.getContext("2d");
context.scale(2, 2);
context.translate(-eleOffsetLeft -abs, -eleOffsetTop);
// 这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此
// translate的时候,要把这个差值去掉
// html2canvas(element).then( (canvas)=>{ //报错
// html2canvas(element[0]).then( (canvas)=>{
html2canvas( ele, {
dpi: 300,
// allowTaint: true, //允许 canvas 污染, allowTaint参数要去掉,否则是无法通过toDataURL导出canvas数据的
useCORS:true //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。
} ).then( (canvas)=>{
var contentWidth = canvas.width;
var contentHeight = canvas.height;
//一页pdf显示html页面生成的canvas高度;
var pageHeight = contentWidth / 592.28 * 841.89;
//未生成pdf的html页面高度
var leftHeight = contentHeight;
//页面偏移
var position = 0;
//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
var imgWidth = 595.28;
var imgHeight = 595.28/contentWidth * contentHeight;
var pageData = canvas.toDataURL('image/jpeg', 1.0);
var pdf = new JsPDF('', 'pt', 'a4');
//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
//当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < pageHeight) {
//在pdf.addImage(pageData, 'JPEG', 左,上,宽度,高度)设置在pdf中显示;
pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
// pdf.addImage(pageData, 'JPEG', 20, 40, imgWidth, imgHeight);
} else { // 分页
while(leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
leftHeight -= pageHeight;
position -= 841.89;
//避免添加空白页
if(leftHeight > 0) {
pdf.addPage();
}
}
}
//可动态生成
pdf.save(pdfName);
})
}
export default {
downloadPDF
}

@ -0,0 +1,90 @@
import html2canvas from 'html2canvas';
import JsPDF from 'jspdf';
/**
* @param ele 要生成 pdf 的DOM元素容器
* @param padfName PDF文件生成后的文件名字
* */
export function downloadPDF(ele, pdfName){
let eleW = ele.offsetWidth;// 获得该容器的宽
let eleH = ele.offsetHeight;// 获得该容器的高
let eleOffsetTop = ele.offsetTop; // 获得该容器到文档顶部的距离
let eleOffsetLeft = ele.offsetLeft; // 获得该容器到文档最左的距离
var canvas = document.createElement("canvas");
var abs = 0;
let win_in = document.documentElement.clientWidth || document.body.clientWidth; // 获得当前可视窗口的宽度(不包含滚动条)
let win_out = window.innerWidth; // 获得当前窗口的宽度(包含滚动条)
if(win_out>win_in){
// abs = (win_o - win_i)/2; // 获得滚动条长度的一半
abs = (win_out - win_in)/2; // 获得滚动条宽度的一半
// console.log(a, '新abs');
}
canvas.width = eleW * 2; // 将画布宽&&高放大两倍
canvas.height = eleH * 2;
var context = canvas.getContext("2d");
context.scale(2, 2);
context.translate(-eleOffsetLeft -abs, -eleOffsetTop);
// 这里默认横向没有滚动条的情况,因为offset.left(),有无滚动条的时候存在差值,因此
// translate的时候,要把这个差值去掉
// html2canvas(element).then( (canvas)=>{ //报错
// html2canvas(element[0]).then( (canvas)=>{
html2canvas( ele, {
dpi: 300,
// allowTaint: true, //允许 canvas 污染, allowTaint参数要去掉,否则是无法通过toDataURL导出canvas数据的
useCORS:true //允许canvas画布内 可以跨域请求外部链接图片, 允许跨域请求。
} ).then( (canvas)=>{
var contentWidth = canvas.width;
var contentHeight = canvas.height;
//一页pdf显示html页面生成的canvas高度;
var pageHeight = contentWidth / 592.28 * 841.89;
//未生成pdf的html页面高度
var leftHeight = contentHeight;
//页面偏移
var position = 0;
//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
var imgWidth = 595.28;
var imgHeight = 595.28/contentWidth * contentHeight;
var pageData = canvas.toDataURL('image/jpeg', 1.0);
var pdf = new JsPDF('', 'pt', 'a4');
//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
//当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < pageHeight) {
//在pdf.addImage(pageData, 'JPEG', 左,上,宽度,高度)设置在pdf中显示;
pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
// pdf.addImage(pageData, 'JPEG', 20, 40, imgWidth, imgHeight);
} else { // 分页
while(leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight);
leftHeight -= pageHeight;
position -= 841.89;
//避免添加空白页
if(leftHeight > 0) {
pdf.addPage();
}
}
}
//可动态生成
pdf.save(pdfName);
})
}
// export {
// downloadPDF
// }

@ -51,11 +51,11 @@
<a-button type="primary" icon="plus-circle" @click="autoFilling()">自动排位</a-button> <a-button type="primary" icon="plus-circle" @click="autoFilling()">自动排位</a-button>
<a-button type="primary" icon="plus-circle" @click="createMaterialBill()">生成物料单 <a-button type="primary" icon="plus-circle" @click="createMaterialBill()">生成物料单
</a-button> </a-button>
<a-button type="primary" icon="unordered-list" @click="viewMaterialBill()">查看物料单 <a-button type="primary" icon="unordered-list" @click="viewMaterialBill">查看物料单
</a-button> </a-button>
<a-button type="primary" icon="redo" @click="sendToRepository()">发送到仓库 <a-button type="primary" icon="redo" @click="sendToRepository()">发送到仓库
</a-button> </a-button>
<a-button type="primary" icon="download" @click="handleExportXls('计划工序')">导出</a-button> <!-- <a-button type="primary" icon="download" @click="handleExportXls('计划工序')">导出</a-button>-->
<a-button type="primary" icon="rollback" @click="fanHui()">返回</a-button> <a-button type="primary" icon="rollback" @click="fanHui()">返回</a-button>
</template> </template>
<template v-slot:action="props"> <template v-slot:action="props">

@ -0,0 +1,28 @@
<!--<template>-->
<!-- <div class="pdf-demo">-->
<!-- <button @click="handleDown">jsPDF方式下载</button>-->
<!-- &lt;!&ndash; <button @click="handleWindowPrint( '#demo', '电子合同' )">浏览器方式下载</button>&ndash;&gt;-->
<!-- <div id="demo">-->
<!-- #demo 中的内容导出成 PDF-->
<!-- </div>-->
<!-- </div>-->
<!--</template>-->
<!--<script>-->
<!--import htmlToPdf from 'yourPath /htmlToPdf';-->
<!--export default {-->
<!-- methods: {-->
<!-- handleDown() {-->
<!-- //PDF-->
<!-- htmlToPdf.downloadPDF(document.querySelector('#demo'), '我的PDF');-->
<!-- },-->
<!-- }-->
<!--}-->
<!--</script>-->

@ -1,66 +1,65 @@
<template> <template>
<a-card :bordered="false"> <a-card :bordered="false">
<p style="font-size: 30px;color:#333; padding-left: 30% ">{{ planInfo.productCode }}生产计划物料单</p>
<template>
<div>
<el-descriptions border :column='4'>
<el-descriptions-item label="工单编号 ">{{ planInfo.productCode }}</el-descriptions-item>
<el-descriptions-item label="生产企业">{{ planInfo.productOrg }}</el-descriptions-item>
<!-- <el-descriptions-item label="企业负责人 ">admin</el-descriptions-item>-->
<el-descriptions-item label="车间 ">{{ planInfo.workshop }}</el-descriptions-item>
<!-- <el-descriptions-item label="车间负责人 ">admin</el-descriptions-item>-->
<el-descriptions-item label="班组">{{ planInfo.team }}</el-descriptions-item>
<el-descriptions-item label="班组长">{{ planInfo.teamLade }}</el-descriptions-item>
<!-- <el-descriptions-item label="产品类型">{{ planInfo.productType }}</el-descriptions-item>-->
<!-- <el-descriptions-item label="产品编号">{{ planInfo.productNo }}</el-descriptions-item>-->
<!-- <el-descriptions-item label="产品名称">{{ planInfo.productName }}</el-descriptions-item>-->
<el-descriptions-item label="开始时间">{{ planInfo.workTime }}</el-descriptions-item>
<el-descriptions-item label="生产时长(天)">{{ planInfo.duration }}</el-descriptions-item>
<el-descriptions-item label="生产状态">{{ planInfo.status }}</el-descriptions-item>
<el-descriptions-item label="加急">{{ planInfo.speedUp }}</el-descriptions-item>
<!-- <el-descriptions-item label="销售企业">{{ planInfo.salesEnterprise }}</el-descriptions-item>-->
<!-- <el-descriptions-item label="订货期">{{ planInfo.orderTime }}</el-descriptions-item>-->
<!-- <el-descriptions-item label="制定人">100</el-descriptions-item>-->
<!-- <el-descriptions-item label="制定时间">100</el-descriptions-item>-->
<el-descriptions-item label="审核人">{{ planInfo.auditBy }}</el-descriptions-item>
<el-descriptions-item label="审核时间">{{ planInfo.auditTimr }}</el-descriptions-item>
</el-descriptions>
</div>
</template>
<!-- 查询区域-END -->
<div class="table-operator"> <div class="table-operator">
<a-button type="primary" icon="download" @click="handleExportXls('计划面料')">导出</a-button> <a-button type="primary" icon="download" @click="handleDown">导出物料单</a-button>
<a-button type="primary" @click="fanHui()">返回</a-button> <a-button type="primary" @click="fanHui()">返回</a-button>
</div> </div>
<!-- table区域-begin --> <br>
<div> <div id="demo">
<template>
<div>
<p style="font-size: 30px;color:#333; padding-left: 30% ">{{ planInfo.productCode }}生产计划物料单</p>
<el-descriptions border :column='4'>
<el-descriptions-item label="工单编号 ">{{ planInfo.productCode }}</el-descriptions-item>
<el-descriptions-item label="生产企业">{{ planInfo.productOrg }}</el-descriptions-item>
<!-- <el-descriptions-item label="企业负责人 ">admin</el-descriptions-item>-->
<el-descriptions-item label="车间 ">{{ planInfo.workshop }}</el-descriptions-item>
<!-- <el-descriptions-item label="车间负责人 ">admin</el-descriptions-item>-->
<el-descriptions-item label="班组">{{ planInfo.team }}</el-descriptions-item>
<el-descriptions-item label="班组长">{{ planInfo.teamLade }}</el-descriptions-item>
<!-- <el-descriptions-item label="产品类型">{{ planInfo.productType }}</el-descriptions-item>-->
<!-- <el-descriptions-item label="产品编号">{{ planInfo.productNo }}</el-descriptions-item>-->
<!-- <el-descriptions-item label="产品名称">{{ planInfo.productName }}</el-descriptions-item>-->
<el-descriptions-item label="开始时间">{{ planInfo.workTime }}</el-descriptions-item>
<el-descriptions-item label="生产时长(天)">{{ planInfo.duration }}</el-descriptions-item>
<el-descriptions-item label="生产状态">{{ planInfo.status }}</el-descriptions-item>
<el-descriptions-item label="加急">{{ planInfo.speedUp }}</el-descriptions-item>
<!-- <el-descriptions-item label="销售企业">{{ planInfo.salesEnterprise }}</el-descriptions-item>-->
<!-- <el-descriptions-item label="订货期">{{ planInfo.orderTime }}</el-descriptions-item>-->
<!-- <el-descriptions-item label="制定人">100</el-descriptions-item>-->
<!-- <el-descriptions-item label="制定时间">100</el-descriptions-item>-->
<el-descriptions-item label="审核人">{{ planInfo.auditBy }}</el-descriptions-item>
<el-descriptions-item label="审核时间">{{ planInfo.auditTimr }}</el-descriptions-item>
</el-descriptions>
</div>
</template>
<a-spin :spinning="confirmLoading"> <!-- table区域-begin -->
<h3 style="width: 98%;;margin:20px auto 0">计划面料清单</h3> <div>
<a-table style="width: 98%;font-size:14px;margin:10px auto 0" :columns="columns1" :data-source="data1" bordered <a-spin :spinning="confirmLoading">
rowKey="id" :pagination="false"> <h3 style="width: 90%;;margin:20px auto 0">计划面料清单</h3>
</a-table> <a-table style="width: 90%;font-size:14px;margin:10px auto 0" :columns="columns1" :data-source="data1"
bordered
<h3 style="width: 98%;;margin:20px auto 0">计划辅料清单</h3> rowKey="id" size="small" :pagination="false">
<a-table style="width: 98%;font-size:14px;margin:10px auto 0" :columns="columns2" :data-source="data2" </a-table>
rowKey="id"
bordered :pagination="false">
</a-table>
<h3 style="width: 98%;;margin:20px auto 0">工序面料清单</h3>
<a-table style="width: 98%;font-size:14px;margin:10px auto 0" :columns="columns3" :data-source="data3"
rowKey="id" bordered :pagination="false">
</a-table> <h3 style="width: 90%;;margin:20px auto 0">计划辅料清单</h3>
<a-table style="width: 90%;font-size:14px;margin:10px auto 0" :columns="columns2" :data-source="data2"
rowKey="id" size="small"
bordered :pagination="false">
</a-table>
<h3 style="width: 98%;;margin:20px auto 0">工序辅料清单</h3> <h3 style="width: 90%;;margin:20px auto 0">工序面料清单</h3>
<a-table style="width: 98%;font-size:14px;margin:10px auto 0" :columns="columns4" :data-source="data4" <a-table style="width: 90%;font-size:14px;margin:10px auto 0" :columns="columns3" :data-source="data3"
rowKey="id" bordered :pagination="false"> rowKey="id" size="small" bordered :pagination="false">
</a-table> </a-table>
</a-spin>
<!-- </a-modal>-->
<h3 style="width: 90%;;margin:20px auto 0">工序辅料清单</h3>
<a-table style="width: 90%;font-size:14px;margin:10px auto 0" :columns="columns4" :data-source="data4"
rowKey="id" size="small" bordered :pagination="false">
</a-table>
</a-spin>
</div>
</div> </div>
</a-card> </a-card>
</template> </template>
@ -70,6 +69,8 @@ import {getAction} from "@api/manage";
import {mixinDevice} from '@/utils/mixin' import {mixinDevice} from '@/utils/mixin'
import {JeecgListMixin} from '@/mixins/JeecgListMixin' import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import {filterObj} from "@/utils/util"; import {filterObj} from "@/utils/util";
import {downloadPDF} from '@/utils/htmlToPdf';
const columns1 = [ const columns1 = [
// { // {
// title: 'ID', // title: 'ID',
@ -194,6 +195,11 @@ export default {
this.getWuLiaoDetail(this.planId); this.getWuLiaoDetail(this.planId);
}, },
methods: { methods: {
handleDown() {
downloadPDF(document.querySelector('#demo'), this.planInfo.productCode + "生产计划物料单.pdf");
},
fanHui(record) { fanHui(record) {
this.$router.push({ this.$router.push({
path: '/productplan/ProductplanManage', path: '/productplan/ProductplanManage',
@ -202,7 +208,7 @@ export default {
}, },
}); });
}, },
getQueryParams(){ getQueryParams() {
var param = Object.assign({}, this.queryParam); var param = Object.assign({}, this.queryParam);
// delete param.createTimeRange; // // delete param.createTimeRange; //
return filterObj(param); return filterObj(param);

Loading…
Cancel
Save