Angular 17如何导出包含数据及对应图表的Excel文件?
在Angular 17中导出带图表的Excel文件
你当前用ExcelJS实现了数据导出,但ExcelJS本身不支持直接创建Excel原生图表,需要结合额外工具实现。下面提供两种基于你现有技术栈的可行方案:
方案一:使用exceljs-charts扩展库(生成原生Excel图表)
exceljs-charts是ExcelJS的第三方扩展,支持直接在Excel中创建可编辑的原生图表。
步骤:
- 安装依赖:
npm install exceljs-charts
- 修改导出代码:
import { Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import * as ExcelJS from 'exceljs'; import { addChartToSheet } from 'exceljs-charts'; // 导入扩展方法 import { saveAs } from 'file-saver'; @Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet], template: `<button (click)="export()">Export</button>`, styleUrl: './app.component.scss', }) export class AppComponent { data = [ { Month: 'January', Amount: 521 }, { Month: 'February', Amount: 625 }, { Month: 'March', Amount: 12 }, { Month: 'April', Amount: 42 }, { Month: 'May', Amount: 534 }, { Month: 'June', Amount: 708 }, { Month: 'July', Amount: 13 }, { Month: 'August', Amount: 345 }, { Month: 'September', Amount: 645 }, { Month: 'October', Amount: 879 }, { Month: 'November', Amount: 325 }, { Month: 'December', Amount: 630 }, ]; async export() { const workbook = new ExcelJS.Workbook(); const worksheet = workbook.addWorksheet('Sheet 1'); // 写入表头和数据 worksheet.columns = [ { header: 'Month', key: 'Month', width: 15 }, { header: 'Amount', key: 'Amount', width: 15 }, ]; this.data.forEach((monthData) => { worksheet.addRow(monthData); }); // 创建柱状图(绑定A2-B13的数据范围) await addChartToSheet(worksheet, { type: 'column', title: 'Monthly Amount', xAxis: { title: 'Month', labels: { source: 'A2:A13' } }, yAxis: { title: 'Amount' }, series: [{ name: 'Amount', values: 'B2:B13' }], position: { top: 0, left: 300, width: 400, height: 300 } // 图表放置在数据右侧 }); // 导出文件 const buffer = await workbook.xlsx.writeBuffer(); const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', }); saveAs(blob, `Export.xlsx`); } }
方案二:生成Chart.js图表图片插入Excel(浏览器端友好)
如果exceljs-charts存在兼容性问题,可以用Chart.js在浏览器渲染图表,再转成图片插入Excel,适合前端环境。
步骤:
- 安装依赖:
npm install chart.js html2canvas
- 修改组件代码:
import { Component, ViewChild, ElementRef } from '@angular/core'; import { RouterOutlet } from '@angular/router'; import * as ExcelJS from 'exceljs'; import { saveAs } from 'file-saver'; import { Chart, registerables } from 'chart.js'; import html2canvas from 'html2canvas'; // 注册Chart.js组件 Chart.register(...registerables); @Component({ selector: 'app-root', standalone: true, imports: [RouterOutlet], template: ` <button (click)="export()">Export</button> <!-- 隐藏的canvas用于渲染图表 --> <canvas #chartCanvas style="display: none;"></canvas> `, styleUrl: './app.component.scss', }) export class AppComponent { @ViewChild('chartCanvas') chartCanvas!: ElementRef<HTMLCanvasElement>; data = [ { Month: 'January', Amount: 521 }, { Month: 'February', Amount: 625 }, { Month: 'March', Amount: 12 }, { Month: 'April', Amount: 42 }, { Month: 'May', Amount: 534 }, { Month: 'June', Amount: 708 }, { Month: 'July', Amount: 13 }, { Month: 'August', Amount: 345 }, { Month: 'September', Amount: 645 }, { Month: 'October', Amount: 879 }, { Month: 'November', Amount: 325 }, { Month: 'December', Amount: 630 }, ]; async export() { const workbook = new ExcelJS.Workbook(); const worksheet = workbook.addWorksheet('Sheet 1'); // 写入表头和数据 worksheet.columns = [ { header: 'Month', key: 'Month', width: 15 }, { header: 'Amount', key: 'Amount', width: 15 }, ]; this.data.forEach((monthData) => { worksheet.addRow(monthData); }); // 1. 渲染Chart.js柱状图 const ctx = this.chartCanvas.nativeElement.getContext('2d'); if (!ctx) return; new Chart(ctx, { type: 'bar', data: { labels: this.data.map(item => item.Month), datasets: [{ label: 'Amount', data: this.data.map(item => item.Amount), backgroundColor: 'rgba(54, 162, 235, 0.6)', borderColor: 'rgba(54, 162, 235, 1)', borderWidth: 1 }] }, options: { responsive: true, scales: { y: { beginAtZero: true } } } }); // 2. 将图表转为图片 const canvas = this.chartCanvas.nativeElement; const imgBlob = await html2canvas(canvas).then(canvas => canvas.toBlob()); if (!imgBlob) return; // 3. 将图片插入Excel(数据下方第15行开始) const imageId = workbook.addImage({ buffer: await new Response(imgBlob).arrayBuffer(), extension: 'png', }); worksheet.addImage(imageId, { tl: { col: 0, row: 14 }, ext: { width: 600, height: 400 } }); // 导出文件 const buffer = await workbook.xlsx.writeBuffer(); const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', }); saveAs(blob, `Export.xlsx`); } }
注意事项:
- 方案一生成的是Excel原生图表,可在Excel中编辑;方案二插入的是图片,无法编辑图表但兼容性更好。
- 使用方案一时,需确认
exceljs-charts版本与你当前ExcelJS版本兼容。
内容的提问来源于stack exchange,提问作者Nhut Truong
相关产品推荐
相关产品推荐

