【web应用】若依框架中,使用Echarts导出报表为PDF文件

发布于:2025-07-13 ⋅ 阅读:(19) ⋅ 点赞:(0)


前言

若依框架前端中,要使用一些文本、数据、图表制作报表,然后导出,那么这个功能如何实现呢?

一、Echarts准备工作

1、查看是否安装了Echarts

查看是否安装了Echarts,方法是,终端运行:

npm list echarts

以下代表已安装成功:
在这里插入图片描述

如果没安装则执行安装依赖包:

npm install echarts --save

2、Echarts导入script 中

import * as echarts from 'echarts'

3、使用Echarts创建图表


const numbers = ref(['加载中', '加载中'])

onMounted(() => {
  setTimeout(() => {
    numbers.value = ['10', '30'] 
    
    const present = parseInt(numbers.value[0]);
    const total = parseInt(numbers.value[1]);
    const absent = total - present;

    // 初始化图表
    const chartDom = document.getElementById('attendanceChart');
    const myChart = echarts.init(chartDom);

    // 图表配置
    const option = {
      // 提示框配置
      tooltip: {
        trigger: 'item',  // 触发类型为数据项触发
        formatter: '{a} <br/>{b}: {c} ({d}%)'  // 提示框格式化字符串
        // {a} 系列名称, {b} 数据名称, {c} 数值, {d} 百分比
      },

      // 图例配置
      legend: {
        top: '0%',    // 图例距离容器顶部的距离
        left: 'center', // 图例水平居中
        textStyle: {   // 图例文字样式
          color: '#A6CAF4', // 文字颜色
          fontSize: 14     // 文字大小
        }
      },

      // 系列列表(一个图表可以包含多个系列)
      series: [
        {
          name: '你好',  // 系列名称
          type: 'pie',      // 图表类型为饼图
          radius: '100%',    // 饼图半径(单个值表示饼图,数组表示环图)
          top: '20%', // 饼图距离容器顶部的距离

          // 数据数组
          data: [
            {
              value: present,  
              name: '我好',    // 数据项名称
              itemStyle: {     // 数据项样式
                color: '#91CC75' // 出勤部分颜色(绿色)
              }
            },
            {
              value: absent,   // 数据值
              name: '未出勤',  // 数据项名称
              itemStyle: {     // 数据项样式
                color: '#409EF0' 
              }
            }
          ],

          // 平时不显示外侧标签和引导线
          label: {
            show: false
          },
          labelLine: {
            show: false
          },


          // 鼠标悬停时显示标签(类似图例效果)
          emphasis: {
            label: {
              show: true,
              position: 'inside', // 悬停时标签显示在内侧
              formatter: '{b}: {d}%', // 显示名称和百分比
              color: '#ffff', // 文字颜色
              fontSize: 14
            },
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            }
          }

        }
      ]
    };

    // 使用配置项显示图表
    myChart.setOption(option);

    // 组件卸载时清理
    onBeforeUnmount(() => {
      // 如果图表实例存在,则销毁
      if (myChart) {
        myChart.dispose();  // 销毁图表实例,释放资源
      }

    });

  }, 300) // 延迟模拟数据加载
})

二、报表制作打印html2canvas和jsPDF准备工作

1、安装html2canvas和jsPDF依赖包

npm install  html2canvas jspdf

2、html2canvas和jsPDF引用到script中

import html2canvas from 'html2canvas';
import { jsPDF } from 'jspdf'; // jspdf需解构导入

3、制作并打印报表

1、按钮

<div>
<!-- 添加导出按钮 -->
      <button @click="exportTextAndChartAsPDF" class="export-btn">导出报表</button>
</div>

2、按钮调用

const personnelData = [
  { name: '张三', date: '2023-10-01', status: '出勤' },
  { name: '李四', date: '2023-10-01', status: '缺勤' },
  { name: '王五', date: '2023-10-02', status: '迟到' },
];

const exportTextAndChartAsPDF = async () => {
  const pdf = new jsPDF('p', 'mm', 'a4'); // 纵向 A4 纸
  const lineHeight = 10; // 行高
  let startY = 40; // 初始 Y 坐标

  // 1. 添加标题
  pdf.setFontSize(16).setTextColor(0, 0, 0);
  pdf.text('人数报表', 105, 15, { align: 'center' });

  // 2. 添加表格标题行
  pdf.setFontSize(12);
  pdf.text('姓名', 20, 30);
  pdf.text('日期', 80, 30);
  pdf.text('状态', 140, 30);

  // 3. 添加数据行
  personnelData.forEach((item, index) => {
    const currentY = startY + index * lineHeight;
    pdf.text(item.name, 20, currentY);
    pdf.text(item.date, 80, currentY);
    pdf.text(item.status, 140, currentY);
  });

  // 4. 截取饼图并添加到 PDF
  const chartContainer = document.getElementById('attendanceChart')?.parentNode; // 获取饼图容器(确保存在)
  if (chartContainer) {
    // 截图饼图区域
    const canvas = await html2canvas(chartContainer, {
      scale: 2, // 提高分辨率
      logging: false,
      useCORS: true, // 允许跨域图片
      backgroundColor: '#FFFFFF', // 背景设为白色
    });

    // 计算饼图在 PDF 中的位置(放在表格下方)
    const imgProps = { width: 80, height: 80 }; // 自定义饼图大小(mm)
    const imgX = 60; // X 坐标(居中偏左)
    const imgY = startY + personnelData.length * lineHeight + 20; // Y 坐标(表格下方留 20mm 间距)

    // 添加饼图到 PDF
    pdf.addImage(
        canvas.toDataURL('image/png'),
        'PNG',
        imgX,
        imgY,
        imgProps.width,
        imgProps.height
    );
  }

  // 5. 保存 PDF
  pdf.save('报表导出.pdf');
};

3、按钮样式

/* 添加导出按钮样式 */
.export-btn {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 10;
  padding: 5px 10px;
  background-color: #409EFF;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.export-btn:hover {
  background-color: #66b1ff;
}

三、导出结果

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到