vue3 调用后端返回excel(.xlsx)二进制文件,调用打印机打印
1.先安装依赖
npm install xlsx html2canvas
2.代码
<template>
<div>
<el-button type="primary" @click="fetchAndPrintExcel" style="margin: 10px;">打印Excel</el-button>
<div ref="previewContainer" class="preview-container"></div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import * as XLSX from 'xlsx';
import html2canvas from 'html2canvas';
import { exportPrintPreview } from '#/api/purchase/purchasePrint';
import { ElButton,ElMessage} from 'element-plus';
// 定义DOM引用和状态
const previewContainer = ref<HTMLDivElement>();
const isLoading = ref(false);
// 调用后端接口获取Excel二进制文件
const fetchExcelFile = async (): Promise<ArrayBuffer> => {
try {
//调用后端接口
const response = await exportPrintPreview({"code":"xxx"})
return await response.arrayBuffer();
} catch (error) {
console.error('获取Excel文件失败:', error);
throw error;
}
};
// 解析Excel并渲染到页面
const renderExcelToHtml = async (excelData: ArrayBuffer) => {
if (!previewContainer.value) return;
try {
const workbook = XLSX.read(excelData);
const firstSheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[firstSheetName];
// 转换为HTML
const html = XLSX.utils.sheet_to_html(worksheet, {
// 优化表格显示
editable: false,
header: '',
footer: ''
});
previewContainer.value.innerHTML = html;
// 等待DOM更新
await new Promise(resolve => setTimeout(resolve, 100));
} catch (error) {
console.error('Excel解析失败:', error);
throw error;
}
};
// 打印功能
const printContent = async () => {
if (!previewContainer.value) return;
try {
// 使用html2canvas将内容转为图片
const canvas = await html2canvas(previewContainer.value, {
scale: 2,
logging: false,
useCORS: true,
allowTaint: true
});
// 创建打印窗口
const printWindow = window.open('', '_blank');
if (!printWindow) {
throw new Error('无法打开打印窗口');
}
// 构建打印内容
printWindow.document.write(`
<!DOCTYPE html>
<html>
<head>
<title>Excel打印预览</title>
<style>
body { margin: 0; padding: 0; }
img { max-width: 100%; height: auto; }
@media print {
@page { size: auto; margin: 0mm; }
body { padding: 0; margin: 0; }
}
</style>
</head>
<body>
<img src="${canvas.toDataURL('image/png')}" />
<script>
// 图片加载完成后自动打印
window.onload = function() {
setTimeout(function() {
window.print();
window.onafterprint = function() {
window.close();
};
}, 500);
};
<\/script>
</body>
</html>
`);
printWindow.document.close();
} catch (error) {
console.error('打印失败:', error);
throw error;
}
};
// 主流程:获取Excel -> 渲染 -> 打印
const fetchAndPrintExcel = async () => {
isLoading.value = true;
try {
const excelData = await fetchExcelFile();
await renderExcelToHtml(excelData);
await printContent();
} catch (error) {
console.error('打印流程出错:', error);
ElMessage.error('打印过程中出现错误,请重试或联系管理员')
} finally {
isLoading.value = false;
}
};
</script>
<style scoped>
.preview-container {
position: absolute;
left: -9999px; /* 隐藏预览容器 */
width: 210mm; /* A4纸宽度 */
}
/* 深度选择器处理动态生成的表格 */
:deep(table) {
border-collapse: collapse;
width: 100%;
}
:deep(th),
:deep(td) {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
</style>