Node.js实现导出图片至Excel

实现方式:ExcelJS
官方文档: https://github.com/exceljs/exceljs/blob/master/README_zh.md

安装依赖

npm install exceljs

1、通过ExcelJS来构造工作簿

我们要导出的数据,可以分为两部分,一部分是表头,一部分是数据,我们先不考虑图片的情况,先 创建工作簿,然后根据创建表头, 填充数据

创建工作簿、工作表

import Excel from 'exceljs';

const workbook = new Excel.Workbook();
const worksheet = workbook.addWorksheet('Sheet1');

2、添加表头

Ps: 目前只介绍直接插入数组 不适用键值对 键值对详细见官方文档
直接按顺序 将需要展示的数据插入第一行

 worksheet.addRow(['姓名', '年龄', '图片']);

3、获取行数据

一个小demo 需要导出的数据

const arr= [{
            name: '小黑',
            age: '18',
            picUrl: 'https://img.alicdn.com/bao/uploaded/i4/2214213274944/O1CN01y0sd7D1mOP3iAtHuD-2214213274944.jpg',
        },
        {
            name: '小白',
            age: '18',
            picUrl: 'https://img.alicdn.com/bao/uploaded/i3/2214213274944/O1CN01jHgP4D1mOOxXTwHNs_!!0-item_pic.jpg',
        }];

excel表 从左上第一个表格 坐标位置为0,0 固需要输出一个二维数组

这个时候先不管图片的数据

const excelData = test.map((item, rowIndex) => {
    return Object.keys(item).map((key, index) => {
        if (key !== 'picUrl') {
            return item[key];
        }
        return '';
    });
});
    
   // 输出数据:
   // [['小黑', 18, ''], ['小白', 18, '']]

将获取的数据插入每行

  for (const row of excelData) {
        const rowData = worksheet.addRow(row);
        // 指定行高
        rowData.height = 50;
   }

4、将图片添加到工作簿

将图像添加到工作表是一个分为两个步骤的过程。首先,通过 addImage() 函数将图像添加到工作簿中,该函数还将返回 imageId 值。然后,使用 imageId,可以将图像作为平铺背景或覆盖单元格区域添加到工作表中。

Workbook.addImage 函数支持按文件名或按 Buffer 添加图像。请注意,在两种情况下,都必须指定扩展名。有效的扩展名包括 “jpeg”,“png”,“gif”。

三种实现方式

const imageId1 = workbook.addImage({
  filename: 'path/to/image.jpg',
  extension: 'jpeg',
});

const imageId2 = workbook.addImage({
  buffer: fs.readFileSync('path/to.image.png'),
  extension: 'png',
});

const myBase64Image = "data:image/png;base64,iVBORw0KG...";
const imageId2 = workbook.addImage({  
  base64: myBase64Image,
  extension: 'png'
});

有尝试过直接拿filename来生成 尝试过后无法直接使用 猜测只能使用本地图片 所以这里我们使用base64

url->base64

import https = require('https');

async imgUrlToBase64 (url): Promise<string> {
    let base64Img;
    return new Promise((resolve) => {
        const req = https.get(url, (res) => {
            const chunks = [];
            let size = 0;
            res.on('data', (chunk) => {
                chunks.push(chunk);
                size += chunk.length;
            });
            res.on('end', () => {
                const data = Buffer.concat(chunks, size);
                base64Img = data.toString('base64');
                resolve(base64Img);
            });
        });
        req.on('error', () => {
            resolve('');
        });
        req.end();
    });
}

使用 Workbook.addImage 中的图像 ID,可以将图像嵌入工作表中以覆盖一定范围。从该范围计算出的坐标将覆盖从第一个单元格的左上角到第二个单元格的右下角。
两种方式

// 案例一  在 B2:D6 上插入图片
worksheet.addImage(imageId2, 'B2:D6');
// 案例二 
// A1 的左上角将为 {col:0,row:0}。单元格的分数可以通过使用浮点数来指定,例如 A1 的中点是 {col:0.5,row:0.5}。
worksheet.addImage(id, {
   // 指定在哪个单元格插入
   tl: { col: row.col + 0.15, row: row.row + 0.15 },
   // 指定图像大小
   ext: { width: 50, height: 50 },
 });

Demo:

// 整理所需数据
const picData = [];
const excelData = test.map((item, rowIndex) => {
    return Object.keys(item).map((key, index) => {
        if (key !== 'picUrl') {
            return item[key];
        }
        picData .push({
            col: index,
            row: rowIndex + 1,
            url: item[key],
        });
        return '';
    });
});

for (const row of excelData) {
    const rowData = worksheet.addRow(row);
    rowData.height = 50;
}
for (const row of picData) {
    const base64 = await this.imgUrlToBase64(row.url);
    const id = workbook.addImage({
        base64,
        extension: 'png',
    });
    worksheet.addImage(id, {
        // 指定在哪个单元格插入
        tl: { col: row.col + 0.15, row: row.row + 0.15 },
        // 指定图像大小
        ext: { width: 50, height: 50 },
    });
}

5、写 XLSX

// 写入文件
const workbook = createAndFillWorkbook();
await workbook.xlsx.writeFile(filename);
// 写入流
await workbook.xlsx.write(stream);
// 写入 buffer
const buffer = await workbook.xlsx.writeBuffer();
  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值