diff --git a/src/utils/classCom.ts b/src/utils/classCom.ts index 40b75ec..dc9767a 100644 --- a/src/utils/classCom.ts +++ b/src/utils/classCom.ts @@ -101,34 +101,38 @@ function base64ToBlob(base64: string, mimeType: string) { * @param type 可选,'pdf' | 'excel',不传默认 pdf * @param fileName 可选,excel下载文件名 */ -function printBase64PDF(base64: string, type: 'pdf' | 'excel' = 'pdf', fileName: string = '文件') { - if (type === 'pdf') { - // PDF打印逻辑 - const blob = base64ToBlob(base64, 'application/pdf'); - const pdfUrl = URL.createObjectURL(blob); - const iframe = document.createElement('iframe'); - iframe.style.display = 'none'; - iframe.src = pdfUrl; - document.body.appendChild(iframe); - iframe.onload = () => { - iframe.contentWindow?.print(); - setTimeout(() => { - URL.revokeObjectURL(pdfUrl); - iframe.remove(); // 修复原代码iframe残留dom - }, 1000); - }; - } else if (type === 'excel') { - // excel导出下载逻辑 - const blob = base64ToBlob(base64, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); - const downloadUrl = URL.createObjectURL(blob); - const a = document.createElement('a'); - a.href = downloadUrl; - a.download = encodeURIComponent(fileName + '.xlsx'); - document.body.appendChild(a); - a.click(); - a.remove(); - URL.revokeObjectURL(downloadUrl); - } +function printBase64PDF(base64: string) { + // PDF打印逻辑 + const blob = base64ToBlob(base64, 'application/pdf'); + const pdfUrl = URL.createObjectURL(blob); + const iframe = document.createElement('iframe'); + iframe.style.display = 'none'; + iframe.src = pdfUrl; + document.body.appendChild(iframe); + iframe.onload = () => { + iframe.contentWindow?.print(); + setTimeout(() => { + URL.revokeObjectURL(pdfUrl); + iframe.remove(); // 修复原代码iframe残留dom + }, 1000); + }; +} + +/** + * 后端返回Blob文件流 + * @param pdfBlob 后端接口返回的文件流blob,responseType:blob + */ +function printBlobPDF(pdfBlob: Blob, fileName: string) { + + const pdfUrl = URL.createObjectURL(pdfBlob); + const iframe = document.createElement('iframe'); + iframe.style.display = 'none'; + iframe.src = pdfUrl; + document.body.appendChild(iframe); + iframe.onload = () => { + iframe.contentWindow?.print(); + setTimeout(() => URL.revokeObjectURL(pdfUrl), 1000); // 释放内存 + }; } @@ -209,5 +213,35 @@ function calcMeanWithSymbols(arr) { // 保留2位小数返回 return Math.round(avg * 100) / 100 } +/** + * 导出文件(Excel下载) + * @param blob 文件二进制blob + * @param fileName 文件名 + */ +function exportFile(blob: Blob, fileName: string) { + const a = document.createElement('a') + const url = URL.createObjectURL(blob) + a.href = url + a.download = fileName + document.body.appendChild(a) + a.click() + // 释放内存 + URL.revokeObjectURL(url) + a.remove() +} -export const classCom = { decimalToHexColor, convertHexToNumber, getContrastTextColor, printBase64PDF, printPDF, useAutoSize, getDayDiff, calcMeanWithSymbols } + + + +export const classCom = { + decimalToHexColor, + convertHexToNumber, + getContrastTextColor, + printBase64PDF, + printPDF, + useAutoSize, + getDayDiff, + calcMeanWithSymbols, + exportFile, + printBlobPDF +} diff --git a/src/views/liswork/xtwh/statstemplate/data.vue b/src/views/liswork/xtwh/statstemplate/data.vue index 7778721..ca1df9f 100644 --- a/src/views/liswork/xtwh/statstemplate/data.vue +++ b/src/views/liswork/xtwh/statstemplate/data.vue @@ -130,7 +130,8 @@ - + diff --git a/src/views/statisticalAnalysis/report/index.vue b/src/views/statisticalAnalysis/report/index.vue index e818aad..c93f2f4 100644 --- a/src/views/statisticalAnalysis/report/index.vue +++ b/src/views/statisticalAnalysis/report/index.vue @@ -7,8 +7,8 @@
查询 - 打印 - 导出Excel + 打印 + 导出Excel
@@ -139,7 +139,6 @@ const userStore = useUserStore() const mbStore = useCommonStore(); const route = useRoute(); - const openDetail = ref(false) const mxtableData = ref([]) const queryParams = ref({ @@ -155,7 +154,8 @@ const checkBoxs = ref([]) const originalColumn = ref([]) //原始列 const tableColumns = ref([]); const Template = ref({}) - +const exportLoading = ref(false) +const printLoading = ref(false) const instrGroupOptions = ref([]) const instrGroupFields = ref([ @@ -301,7 +301,6 @@ const getPrintFooterText = (col, idx) => { // 打印 const print = () => { - // 不直接改 originalColumn,拷贝一份,避免影响导出等其他功能 const printColumns = originalColumn.value.map(item => { const matchTabCol = tableColumns.value.find(col => col.prop === item.paramCode) return { ...item, paramSequence: matchTabCol ? matchTabCol.paramSequence : 0 } @@ -312,50 +311,11 @@ const print = () => { Column: printColumns, Template: Template.value } - + printLoading.value = true printTemplate(data).then(res => { - // 后端错误 JSON 判断,避免静默失败 - if (res instanceof Blob && res.type.includes('application/json')) { - const reader = new FileReader() - reader.onload = e => { - const err = JSON.parse(e.target.result) - ElMessage.error(err.msg || '打印失败') - } - reader.readAsText(res) - return - } - - const blob = new Blob([res], { type: 'application/pdf' }) - const pdfUrl = URL.createObjectURL(blob) - - // 不要 display:none,Chrome 对隐藏 iframe 的 PDF 打印有兼容问题;移出屏幕即可 - const iframe = document.createElement('iframe') - iframe.style.position = 'fixed' - iframe.style.right = '0' - iframe.style.bottom = '0' - iframe.style.width = '0' - iframe.style.height = '0' - iframe.style.border = '0' - iframe.src = pdfUrl - document.body.appendChild(iframe) - - iframe.onload = () => { - // 等 PDF 渲染完再打印,避免空白页 - setTimeout(() => { - const win = iframe.contentWindow - if (win) { - win.focus() - win.print() // Chrome/Firefox 阻塞到打印对话框关闭 - } - // print() 阻塞时,这里在对话框关闭后才执行;留 2s 缓冲再清理 - setTimeout(() => { - URL.revokeObjectURL(pdfUrl) - iframe.remove() - }, 2000) - }, 300) - } - }).catch(() => { - ElMessage.error('打印失败') + classCom.printBlobPDF(res) + }).finally(() => { + printLoading.value = false }) } @@ -374,18 +334,13 @@ const exportHandle = () => { Column: originalColumn.value, Template: Template.value }; + exportLoading.value = true; exportTemplate(data).then(res => { - //classCom.printBase64PDF(res.data, 'excel', '统计报表') - // 若依拦截器对 blob 直接透传,res 就是 Blob - const blob = new Blob([res], { - type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - }) - const link = document.createElement('a') - link.href = URL.createObjectURL(blob) - link.download = '导出_' + new Date().getTime() + '.xlsx' - link.click() - URL.revokeObjectURL(link.href) // 释放内存 + classCom.exportFile(res, statsTitle.value) + }).finally(() => { + exportLoading.value = false; }) + } const xmList = ref([])