You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
4.0 KiB
183 lines
4.0 KiB
<template> |
|
<div> |
|
<el-dialog v-model="visible" :title="props.title" :width="props.width"> |
|
<template v-if="visible"> |
|
<div class="printCode" ref="printNodeRef"> |
|
<div v-html="props.html"></div> |
|
</div> |
|
</template> |
|
|
|
<div class="flex-c-c mt10"> |
|
<el-button @click="handleClose" icon="CircleClose"> 关 闭 </el-button> |
|
<el-button type="primary" v-if="props.isShowExport" @click="handleExport" icon="Download"> |
|
导 出 |
|
</el-button> |
|
<el-button type="primary" @click="() => printTemplate('notHaveTem')" icon="Printer"> |
|
打 印 |
|
</el-button> |
|
<el-button type="primary" @click="() => printTemplate('haveTem')" icon="Printer"> |
|
打 印(自定义模板) |
|
</el-button> |
|
</div> |
|
</el-dialog> |
|
</div> |
|
</template> |
|
|
|
<script setup lang="ts"> |
|
import { defineProps, computed, ref } from 'vue'; |
|
import print from '@/utils/print'; |
|
import { ElMessage, ElMessageBox } from 'element-plus'; |
|
import { getObjType } from '@/utils/util'; |
|
import * as XLSX from 'xlsx'; |
|
|
|
const props = defineProps({ |
|
html: { |
|
type: String, |
|
default: '', |
|
}, |
|
modelValue: { |
|
type: Boolean, |
|
default: false, |
|
}, |
|
width: { |
|
type: String, |
|
default: '780px', |
|
}, |
|
title: { |
|
type: String, |
|
default: '二维码', |
|
}, |
|
isShowExport: { |
|
type: Boolean, |
|
default: true, |
|
}, |
|
printFn: { |
|
type: Function, |
|
default: null, |
|
}, |
|
}); |
|
|
|
const $emit = defineEmits(['update:modelValue']); |
|
|
|
const visible = computed({ |
|
get: () => props.modelValue, |
|
set: val => { |
|
$emit('update:modelValue', val); |
|
}, |
|
}); |
|
|
|
const handleClose = () => { |
|
visible.value = false; |
|
}; |
|
|
|
const printNodeRef = ref(); |
|
|
|
/** 生成Excel */ |
|
const createExcel = () => { |
|
// const table = this.$refs.tableRef; |
|
|
|
/* 将表格转换为 Workbook 对象 */ |
|
const wb = XLSX.utils.table_to_book(printNodeRef.value); |
|
|
|
console.log('wb :>> ', wb); |
|
|
|
wb.Sheets.Sheet1; |
|
|
|
//单元格外侧框线 |
|
const borderAll = { |
|
top: { |
|
style: 'thin', |
|
}, |
|
bottom: { |
|
style: 'thin', |
|
}, |
|
left: { |
|
style: 'thin', |
|
}, |
|
right: { |
|
style: 'thin', |
|
}, |
|
}; |
|
|
|
for (const key in wb.Sheets.Sheet1) { |
|
const item = wb.Sheets.Sheet1[key]; |
|
|
|
const type = getObjType(item); |
|
|
|
console.log('type :>> ', type); |
|
|
|
if (type !== 'object') continue; |
|
|
|
item.s = { |
|
border: borderAll, |
|
font: { |
|
// name: "微软雅黑", |
|
// sz: 16, |
|
color: { rgb: '000000' }, |
|
bold: true, |
|
italic: false, |
|
underline: false, |
|
}, |
|
fill: { |
|
fgColor: { rgb: 'C5D9F1' }, |
|
}, |
|
alignment: { |
|
horizontal: 'center', |
|
vertical: 'center', |
|
wrapText: false, // 自动换行 |
|
}, |
|
}; |
|
|
|
item.t = 's'; |
|
} |
|
|
|
/* 导出 Workbook 到 Excel 文件 */ |
|
XLSX.writeFile(wb, 'data.xlsx'); |
|
}; |
|
|
|
/** 导出 */ |
|
const handleExport = () => { |
|
if (!printNodeRef.value) return ElMessage.warning('数据暂未请求完成, 请稍等'); |
|
|
|
ElMessageBox.confirm('确认导出?', '', { |
|
confirmButtonText: '确认', |
|
cancelButtonText: '关闭', |
|
type: 'warning', |
|
}).then(() => { |
|
// 确认导出 |
|
createExcel(); |
|
}); |
|
}; |
|
|
|
/** 模板打印 */ |
|
const printTemplate = (type: 'haveTem' | 'notHaveTem') => { |
|
const printNode = document.querySelectorAll('.printCode > div > div'); |
|
|
|
const cloneNodeList = []; |
|
|
|
for (let i = 0; i < printNode.length; i++) { |
|
cloneNodeList.push(printNode[i].cloneNode(true)); |
|
} |
|
|
|
for (let i = 0; i < cloneNodeList.length; i++) { |
|
const element = cloneNodeList[i]; |
|
|
|
for (let j = 0; j < element.childNodes.length; j++) { |
|
const child = element.childNodes[j]; |
|
if (child.className !== 'image-container') continue; |
|
child.style.setProperty('--isShow', type === 'haveTem' ? 'flex' : 'none'); |
|
child.style.setProperty('--aa', type === 'haveTem' ? '#000' : '#fff'); |
|
break; |
|
} |
|
} |
|
|
|
print(cloneNodeList); |
|
}; |
|
</script> |
|
|
|
<style scoped lang="scss"> |
|
.printCode { |
|
max-height: 80vh; |
|
overflow-y: scroll; |
|
} |
|
</style>
|
|
|