You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Node.js在Excel、PDF中生成图表?Excel嵌入图表失败求助

问题描述

我用Chart.js在Canvas上绘制了折线图,再尝试通过ExcelJS将图表图片嵌入Excel并下载,但目前只能单独下载Excel文件和图表图片,图表并未成功嵌入Excel内。希望得到指导实现Excel嵌入图表的效果,同时想了解如何用Node.js在PDF中生成图表。

代码如下:

JavaScript 折线图生成代码

function TyLyReport() {
    var lineChartData = {
        labels : ["Jan","Feb","Mar"],
        datasets : [
            {
                label: 'Dataset 1',
                borderColor: 'rgba(75, 192, 192, 1)',
                backgroundColor: 'rgba(75, 192, 192, 0.2)',
                data : [1000, 2000, 2500],
                fill: false
            },
            {
                label: 'Dataset 2',
                borderColor: '#FF4848',
                backgroundColor: 'rgba(255, 72, 72, 0.2)',
                data : [1016, 1800, 2900],
                fill: false
            }
        ]
    };

    var ctx = document.getElementById("canvas").getContext("2d");
    window.myLine = new Chart(ctx, {
        type: 'line',
        data: lineChartData,
        options: {
            responsive : true,
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            }
        }
    });

    // Export chart image to Excel
    exportToExcel();
}
// Function to export chart image to Excel
function exportToExcel() {
    var canvas = document.getElementById("canvas");
    var image = canvas.toDataURL("image/png");

    var workbook = new ExcelJS.Workbook();
    var worksheet = workbook.addWorksheet('Chart Image');
    var imageId = workbook.addImage({
        base64: image,
        extension: 'png',
    });
    worksheet.addImage(imageId, 'A1');

    workbook.xlsx.writeBuffer().then(function(buffer) {
        saveAs(new Blob([buffer]), 'chart_image.xlsx');
    });
}

// Call the TyLyReport function when the window loads
window.onload = TyLyReport;

解决方案

一、修复Excel嵌入图表问题

你的代码核心问题是:canvas.toDataURL()返回的字符串带data:image/png;base64,前缀,但ExcelJS的addImage只需要纯base64编码内容,不能带前缀。修改exportToExcel函数即可解决:

function exportToExcel() {
    var canvas = document.getElementById("canvas");
    // 去掉dataURL的前缀,保留纯base64部分
    var imageBase64 = canvas.toDataURL("image/png").replace(/^data:image\/png;base64,/, "");

    var workbook = new ExcelJS.Workbook();
    var worksheet = workbook.addWorksheet('Chart Image');
    var imageId = workbook.addImage({
        base64: imageBase64,
        extension: 'png',
    });
    // 可选:指定图片位置和大小,让显示更合理
    worksheet.addImage(imageId, {
        tl: { col: 0, row: 0 },
        br: { col: 5, row: 15 }
    });

    workbook.xlsx.writeBuffer().then(function(buffer) {
        saveAs(new Blob([buffer]), 'chart_image.xlsx');
    });
}

额外注意点:

  • 确保页面已引入FileSaver.js(saveAs函数的来源),如果没有,添加:<script src="https://cdn.jsdelivr.net/npm/file-saver@2.0.5/dist/FileSaver.min.js"></script>
  • 复杂图表可能需要等待渲染完成再导出,可延迟执行:
    // 在TyLyReport里替换exportToExcel();为:
    setTimeout(() => exportToExcel(), 100);
    

二、Node.js中生成带图表的PDF

Node环境下需要用Node版Canvas配合Chart.js,再通过PDF工具生成文件,步骤如下:

1. 安装依赖

npm install canvas chart.js pdfkit

2. 示例代码

const { createCanvas } = require('canvas');
const Chart = require('chart.js/auto');
const PDFDocument = require('pdfkit');
const fs = require('fs');

// 创建Canvas实例
const canvas = createCanvas(800, 600);
const ctx = canvas.getContext('2d');

// 生成折线图
const lineChartData = {
    labels: ["Jan", "Feb", "Mar"],
    datasets: [
        {
            label: 'Dataset 1',
            borderColor: 'rgba(75, 192, 192, 1)',
            backgroundColor: 'rgba(75, 192, 192, 0.2)',
            data: [1000, 2000, 2500],
            fill: false
        },
        {
            label: 'Dataset 2',
            borderColor: '#FF4848',
            backgroundColor: 'rgba(255, 72, 72, 0.2)',
            data: [1016, 1800, 2900],
            fill: false
        }
    ]
};

new Chart(ctx, {
    type: 'line',
    data: lineChartData,
    options: {
        responsive: true,
        scales: {
            y: {
                beginAtZero: true
            }
        }
    }
});

// 生成PDF并写入文件
const doc = new PDFDocument();
doc.pipe(fs.createWriteStream('chart.pdf'));
// 将Canvas图片添加到PDF,指定位置和宽度
doc.image(canvas.toBuffer('image/png'), 50, 50, { width: 700 });
doc.end();

说明:

  • canvas包需要系统依赖支持(比如Linux下需安装libcairo2-dev等,具体看npm文档)
  • 可通过pdfkit的API添加文本、表格等内容,实现更复杂的PDF布局

内容的提问来源于stack exchange,提问作者CodeBox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 14:43:26