heli-mes/mes-ui/mes-ui-admin-vue3/src/views/heli/partpurchasecheck/print.vue

230 lines
6.8 KiB
Vue
Raw Normal View History

2025-10-17 23:47:27 +08:00
<template>
<el-dialog v-model="dialogVisible" title="" width="900px" append-to-body>
<div class="print-wrap">
<div class="header header-grid">
<div class="cell company">杭州合立模具有限公司</div>
<div class="cell title">委外加工清单及送货单</div>
<div class="cell audit">审核</div>
<div class="cell handler">委外加工经手人</div>
<div class="cell receiver">收货人</div>
</div>
<table class="sheet" border="1" cellspacing="0" cellpadding="0">
<!-- 固定列宽总计 100% -->
<colgroup>
<col style="width: 4%" />
<col style="width: 8%" />
<col style="width: 9%" />
<col style="width: 11%" />
<col style="width: 9%" />
<col style="width: 14%" />
<col style="width: 6%" />
<col style="width: 12%" />
<col style="width: 6%" />
<col style="width: 6%" />
<col style="width: 7%" />
<col style="width: 8%" />
</colgroup>
<thead>
<tr>
<th>编号</th>
<th>日期</th>
<th>客户名</th>
<th>模具名</th>
<th>件号</th>
<th>零件名称</th>
<th>材料</th>
<th>规格</th>
<th>数量</th>
<th>单价</th>
<th>总价格</th>
<th>要求日期</th>
</tr>
</thead>
<tbody>
<tr v-for="row in rows" :key="row['编号']">
<td>{{ row['编号'] }}</td>
<td>{{ fmtDate(row['日期']) }}</td>
<td class="text-left">{{ row['客户名'] }}</td>
<td class="text-left">{{ row['模具名'] }}</td>
<td class="text-left">{{ row['件号'] }}</td>
<td class="text-left">{{ row['零件名称'] }}</td>
<td>{{ row['材料'] }}</td>
<td class="spec text-left">{{ row['规格'] }}</td>
<td class="num">{{ row['数量'] }}</td>
<td class="num">{{ row['单价'] }}</td>
<td class="num">{{ row['总价格'] }}</td>
<td>{{ fmtDate(row['要求日期']) }}</td>
</tr>
</tbody>
<tfoot>
<tr class="sum-row">
<td colspan="8" class="sum-label">合计</td>
<td class="num sum-value">{{ sumQuantity }}</td>
<td></td>
<td class="num sum-value">{{ sumTotal }}</td>
<td></td>
</tr>
</tfoot>
</table>
<div class="footer-sign sign-row">
<div>合立经手人{{ duEmpName }}</div>
<div>审核人</div>
<div>委外加工经手人</div>
</div>
</div>
<template #footer>
<el-button @click="dialogVisible = false">关闭</el-button>
<el-button type="primary" @click="onPrint">打印</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import dayjs from 'dayjs'
const dialogVisible = ref(false)
const rows = ref<Record<string, any>[]>([])
const nowDate = dayjs().format('YYYY-MM-DD')
const duEmpName = computed(() => (rows.value[0] ? rows.value[0]['合立经手人'] ?? '' : ''))
const sumQuantity = computed(() =>
rows.value.reduce((acc, cur) => acc + Number(cur['数量'] || 0), 0)
)
const sumTotal = computed(() =>
rows.value.reduce((acc, cur) => acc + Number(cur['总价格'] || 0), 0)
)
const fmtDate = (v: any) => (v ? dayjs(v).format('YYYY-MM-DD') : '')
const open = (data: Record<string, any>[]) => {
rows.value = Array.isArray(data) ? data : []
dialogVisible.value = true
}
defineExpose({ open })
// onPrint()
const onPrint = () => {
const printNode = document.querySelector('.print-wrap') as HTMLElement
if (!printNode) return
const iframe = document.createElement('iframe')
iframe.setAttribute('style', 'width:0;height:0;position:absolute;left:-9999px;top:-9999px;')
document.body.appendChild(iframe)
const doc = iframe.contentWindow!.document
doc.open()
doc.title = ''
doc.write(`
<style>
/* 自定义纸张尺寸222mm 宽 × 140mm 高 */
@page { size: 222mm 140mm; margin: 6mm; }
body { font-family: Arial, "Microsoft YaHei", sans-serif; color:#000; }
/* 打印区域尺寸以纸张减去页边距为准 */
.print-wrap { width: calc(222mm - 12mm); min-height: calc(140mm - 12mm); }
.header.header-grid {
display: grid;
grid-template-columns: 2fr 1fr 1fr 2fr 1fr;
align-items: center;
column-gap: 12px;
margin-bottom: 8px;
}
.header.header-grid .company { font-size: 12px; text-align: left; }
.header.header-grid .title,
.header.header-grid .audit,
.header.header-grid .handler,
.header.header-grid .receiver { font-size: 12px; text-align: right; }
.sheet { width:100%; border-collapse:collapse; font-size:12px; table-layout: fixed; }
.sheet th, .sheet td { border:1px solid #333; padding:6px 4px; text-align:center; line-height:1.3; vertical-align: middle; }
.sheet thead th { background:#f5f7fa; font-weight:600; }
.sheet .text-left { text-align:left; padding-left:6px; }
.sheet .spec { word-break: break-word; white-space: normal; }
.sheet .num { text-align:right; padding-right:6px; }
.sheet tfoot .sum-label, .sheet tfoot .sum-value { font-weight:700; }
.sheet tfoot .sum-row td { border-top: 2px solid #000; }
.sign-row { display:flex; justify-content:space-between; margin-top:12px; font-size:12px; }
</style>
`)
doc.write(printNode.outerHTML)
doc.close()
iframe.contentWindow!.focus()
iframe.contentWindow!.print()
setTimeout(() => document.body.removeChild(iframe), 500)
}
</script>
<style scoped lang="less">
.print-wrap {
/* 预览时也按目标纸张尺寸展示,便于校对 */
width: 222mm;
min-height: 140mm;
background: #fff;
}
.header.header-grid {
display: grid;
grid-template-columns: 2fr 1fr 1fr 2fr 1fr;
align-items: center;
column-gap: 12px;
}
.header.header-grid .company {
}
.header.header-grid .title {
text-align: center;
}
.header.header-grid .audit,
.header.header-grid .handler,
.header.header-grid .receiver {
font-size: 12px;
text-align: right;
}
.sheet {
margin-top: 8px;
table-layout: fixed;
border-collapse: collapse;
font-size: 12px;
width: 100%;
th,
td {
border: 1px solid #333;
padding: 6px 4px;
text-align: center;
line-height: 1.3;
vertical-align: middle;
}
thead th {
background: #f5f7fa;
font-weight: 600;
}
.text-left {
text-align: left;
padding-left: 6px;
}
.spec {
word-break: break-word;
white-space: normal;
}
.num {
text-align: right;
padding-right: 6px;
}
tfoot .sum-row td {
border-top: 2px solid #000;
}
}
.footer-sign.sign-row {
display: flex;
justify-content: space-between;
margin-top: 12px;
}
</style>