vue3 实现excel二进制文件,调用打印机打印

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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值