ZetCode

ExcelJS 教程

最后修改于 2023 年 10 月 18 日

在本文中,我们将演示如何使用 ExcelJS 库在 JavaScript 中处理 Excel 文件。

ExcelJS

ExcelJS 是一个 JavaScript 库,用于读取、操作和写入 XLSX 格式的电子表格数据。

$ npm i exceljs

我们使用 npm i exceljs 命令安装 ExcelJS。

Excel xlsx

在本文中,我们处理 xlsx 文件。xlsx 是 Microsoft Excel 使用的开放 XML 电子表格文件格式的文件扩展名。 xlsm 文件支持宏。 xltm 是启用宏的模板文件。 xls 格式是专有的二进制格式,而 xlsx 基于 Office Open XML 格式。

ExcelJS 单元格

在第一个例子中,我们处理单元格。我们使用 getCell 函数获取对单元格的引用。

app.js
const Excel = require('exceljs');

const wb = new Excel.Workbook();
const ws = wb.addWorksheet('My Sheet');

ws.addRows([
    [1, 2, 3, 4, 5],
    [6, 7, 8, 9, 10],
    [11, 12, 13, 14, 15],
    [16, 17, 18, 19, 20]]
);

const v0 = ws.getCell('A1').value;
console.log(v0);

const v1 = ws.getCell(1, 1).value;
console.log(v1);

const v2 = ws.getRow(2).getCell(2).value;
console.log(v2);

在这个例子中,我们向工作表中添加数据,然后读取它们。

const Excel = require('exceljs');

导入 ExcelJS 库。

const wb = new Excel.Workbook();

生成一个新的工作簿。

const ws = wb.addWorksheet('My Sheet');

addWorksheet 将一个新的工作表添加到工作簿。

ws.addRows([
    [1, 2, 3, 4, 5],
    [6, 7, 8, 9, 10],
    [11, 12, 13, 14, 15],
    [16, 17, 18, 19, 20]]
);

addRows 函数将数据行添加到工作表。

const v0 = ws.getCell('A1').value;
console.log(v0);

我们通过 'A1' 地址引用左上角的单元格;典型的 Excel 符号。我们使用 value 属性获取单元格的值。

const v1 = ws.getCell(1, 1).value;
console.log(v1);

另一种方法是将行号和列号传递给 getCell 函数。

const v2 = ws.getRow(2).getCell(2).value;
console.log(v2);

第三种方法是链式调用 getRowgetCell

$ node app.js 
1
1
7

ExcelJS 写入文件

我们使用 writeFile 方法将数据写入文件。

app.js
const Excel = require('exceljs');

const fileName = 'simple.xlsx';

const wb = new Excel.Workbook();
const ws = wb.addWorksheet('My Sheet');

ws.getCell('A1').value = 'John Doe';
ws.getCell('B1').value = 'gardener';
ws.getCell('C1').value = new Date().toLocaleString();

const r3 = ws.getRow(3);
r3.values = [1, 2, 3, 4, 5, 6];

wb.xlsx
  .writeFile(fileName)
  .then(() => {
    console.log('file created');
  })
  .catch(err => {
    console.log(err.message);
  });

该示例向工作表中添加一些数据,并将其写入 simple.xslx 文件。

ws.getCell('A1').value = 'John Doe';
ws.getCell('B1').value = 'gardener';
ws.getCell('C1').value = new Date().toLocaleString();

我们将数据写入三个单元格。

const r3 = ws.getRow(3);
r3.values = [1, 2, 3, 4, 5, 6];

此外,我们向第三行添加一个值数组。

wb.xlsx
    .writeFile(fileName)
    .then(() => {
      console.log('file created');
    })
    .catch(err => {
      console.log(err.message);
    });

使用 writeFile 函数将工作表写入文件。

ExcelJS 读取文件

在下面的例子中,我们从现有的 xlsx 文件中读取。我们假设前两列中存在一些数据。

app.js
const ExcelJS = require('exceljs');

const wb = new ExcelJS.Workbook();

const fileName = 'items.xlsx';

wb.xlsx.readFile(fileName).then(() => {
    
    const ws = wb.getWorksheet('Sheet1');

    const c1 = ws.getColumn(1);
    
    c1.eachCell(c => {

        console.log(c.value);
    });

    const c2 = ws.getColumn(2);
    
    c2.eachCell(c => {

        console.log(c.value);
    });
}).catch(err => {
    console.log(err.message);
});

该示例从工作表的两列中读取数据。

wb.xlsx.readFile(fileName).then(() => {

要读取工作表数据,我们使用 readFile 函数。

const ws = wb.getWorksheet('Sheet1');

我们使用 getWorksheet 函数获取工作表。

const c1 = ws.getColumn(1);

我们使用 getColumn 获取第一列。

c1.eachCell(c => {

    console.log(c.value);
});

我们使用 eachCell 函数遍历当前的单元格。

ExcelJS 列

在下一个例子中,我们处理列。

app.js
const Excel = require('exceljs');

const wb = new Excel.Workbook();
const ws = wb.addWorksheet('My Sheet');

const headers = [
    { header: 'First name', key: 'fn', width: 15 },
    { header: 'Last name', key: 'ln', width: 15 },
    { header: 'Occupation', key: 'occ', width: 15 },
    { header: 'Salary', key: 'sl', width: 15 },
]

ws.columns = headers;

ws.addRow(['John', 'Doe', 'gardener', 1230]);
ws.addRow(['Roger', 'Roe', 'driver', 980]);
ws.addRow(['Lucy', 'Mallory', 'teacher', 780]);
ws.addRow(['Peter', 'Smith', 'programmer', 2300]);

ws.getColumn('fn').eachCell((cell, rn) => {

    console.log(cell.value);
});

console.log('--------------');

ws.getColumn('B').eachCell((cell, rn) => {

    console.log(cell.value);
});

console.log('--------------');

ws.getColumn(3).eachCell((cell, rn) => {

    console.log(cell.value);
});

console.log('--------------');

console.log(`There are ${ws.actualColumnCount} columns`);

我们定义列标题并遍历列单元格。

const headers = [
    { header: 'First name', key: 'fn', width: 15 },
    { header: 'Last name', key: 'ln', width: 15 },
    { header: 'Occupation', key: 'occ', width: 15 },
    { header: 'Salary', key: 'sl', width: 15 },
]

ws.columns = headers;

通过 columns 属性,我们添加列标题并定义列键和宽度。

ws.addRow(['John', 'Doe', 'gardener', 1230]);
ws.addRow(['Roger', 'Roe', 'driver', 980]);
...

我们使用 addRow 添加一些行数据。

ws.getColumn('fn').eachCell((cell, rn) => {

    console.log(cell.value);
});

我们通过键名引用第一列。eachCell 用于迭代数据。

ws.getColumn('B').eachCell((cell, rn) => {

    console.log(cell.value);
});

在这里,我们通过分配的字母获取列。

ws.getColumn(3).eachCell((cell, rn) => {

    console.log(cell.value);
});

最后,我们通过索引值引用第三列。

console.log(`There are ${ws.actualColumnCount} columns`);

我们使用 actualColumnCount 属性获取包含数据的列数。

$ node app.js 
First name
John
Roger
Lucy
Peter
--------------
Last name
Doe
Roe
Mallory
Smith
--------------
Occupation
gardener
driver
teacher
programmer
--------------
There are 4 columns

ExcelJS 行

在第一个例子中,我们处理行。

app.js
const Excel = require('exceljs');

const wb = new Excel.Workbook();
const ws = wb.addWorksheet('My Sheet');

const headers = [
    { header: 'First name', key: 'fn', width: 15 },
    { header: 'Last name', key: 'ln', width: 15 },
    { header: 'Occupation', key: 'occ', width: 15 },
    { header: 'Salary', key: 'sl', width: 15 },
]

ws.columns = headers;

ws.addRow(['John', 'Doe', 'gardener', 1230]);
ws.addRow({ 'fn': 'Roger', 'ln': 'Roe', 'occ': 'driver', 'sl': 980 });
ws.addRows(
    ['Lucy', 'Mallory', 'teacher', 780],
    ['Peter', 'Smith', 'programmer', 2300]);

console.log(`There are ${ws.actualRowCount} rows`);

let rows = ws.getRows(1, 4).values();

for (let row of rows) {

    row.eachCell((cell, cn) => {
        console.log(cell.value);
    });
}

我们使用 addRowaddRows 函数添加数据,并使用 getRows 检索数据行。

ws.addRow(['John', 'Doe', 'gardener', 1230]);

我们使用 addRow 添加一个值数组。

ws.addRow({ 'fn': 'Roger', 'ln': 'Roe', 'occ': 'driver', 'sl': 980 });

在这里,我们使用键/值对添加数据,其中每个键是列键名。

ws.addRows(
    ['Lucy', 'Mallory', 'teacher', 780],
    ['Peter', 'Smith', 'programmer', 2300]);

可以使用 addRows 添加多行。

console.log(`There are ${ws.actualRowCount} rows`);

actualRowCount 属性返回具有值的行数。

let rows = ws.getRows(1, 4).values();

我们从第 1..4 行获取值。

for (let row of rows) {

    row.eachCell((cell, cn) => {
        console.log(cell.value);
    });
}

我们遍历行及其单元格。

$ node app.js 
There are 3 rows
First name
Last name
Occupation
Salary
John
Doe
gardener
1230
Roger
Roe
driver
980

ExcelJS 加载 CSV

ExcelJS 允许从 CSV 文件中读取数据。

cars.csv
id,name,price
1,Audi,52642
2,Mercedes,57127
3,Skoda,9000
4,Volvo,29000
5,Bentley,350000
6,Citroen,21000
7,Hummer,41400
8,Volkswagen,21600
9,Toyota,26700

我们有一些简单的 CSV 数据。

app.js
const Excel = require('exceljs');

const fileName = 'cars.xlsx'
const data = 'cars.csv';

const wb = new Excel.Workbook();

wb.csv.readFile(data).then((ws) => {

    console.log(
        `Sheet ${ws.id} - ${ws.name}, Dims=${JSON.stringify(
            ws.dimensions
        )}`);

    for (let i = 1; i <= ws.actualRowCount; i++) {
        for (let j = 1; j <= ws.actualColumnCount; j++) {
            const val = ws.getRow(i).getCell(j);
            process.stdout.write(`${val} `);
        }
        console.log();
    }
}).then(() => {
    writeData();
});

function writeData() {

    wb.xlsx
        .writeFile(fileName)
        .then(() => {
            console.log('Done.');
        })
        .catch(err => {
            console.log(err.message);
        });
}

在这个例子中,我们从 cars.csv 文件中读取数据,将其打印到控制台并将其写入 xlsx 文件。

wb.csv.readFile(data).then((ws) => {

我们使用 csv 属性的 readFile 函数读取 CSV 数据。

for (let i = 1; i <= ws.actualRowCount; i++) {
    for (let j = 1; j <= ws.actualColumnCount; j++) {
        const val = ws.getRow(i).getCell(j);
        process.stdout.write(`${val} `);
    }
    console.log();
}

我们使用两个 for 循环遍历数据。

}).then(() => {
    writeData();
});

当读取完成后,我们调用 writeData 函数。

function writeData() {

    wb.xlsx
        .writeFile(fileName)
        .then(() => {
            console.log('Done.');
        })
        .catch(err => {
            console.log(err.message);
        });
}

writeData 函数中,我们将工作表数据写入 xlsx 文件。

ExcelJS 单元格对齐

在下一个例子中,我们展示如何在单元格中对齐数据。我们可以水平和垂直地对齐内容。

app.js
const Excel = require('exceljs');

const fileName = 'align.xlsx';

const wb = new Excel.Workbook();
const ws = wb.addWorksheet('My Sheet');

const headers = [
    { header: 'First name', key: 'fn', width: 15 },
    { header: 'Last name', key: 'ln', width: 15 },
    { header: 'Occupation', key: 'occ', width: 15 },
    { header: 'Salary', key: 'sl', width: 15 },
]

ws.columns = headers;

ws.addRow(['John', 'Doe', 'gardener', 1230]);
ws.addRow(['Roger', 'Roe', 'driver', 980]);
ws.addRow(['Lucy', 'Mallory', 'teacher', 780]);
ws.addRow(['Peter', 'Smith', 'programmer', 2300]);

ws.getColumn('A').style.alignment = { vertical: 'middle', horizontal: 'left' };
ws.getColumn('B').style.alignment = { vertical: 'middle', horizontal: 'left' };
ws.getColumn('C').style.alignment = { vertical: 'middle', horizontal: 'left' };
ws.getColumn('D').style.alignment = { vertical: 'middle', horizontal: 'right' };

ws.getRow(1).style.alignment = {vertical: 'middle', horizontal: 'center'};

wb.xlsx
    .writeFile(fileName)
    .then(() => {
        console.log('file created');
    })
    .catch(err => {
        console.log(err.message);
    });

要对齐内容,我们使用 stylealignment 属性。

ExcelJS 超链接

在下一个例子中,我们创建一个超链接。

app.js
const Excel = require('exceljs');

const fileName = 'hyperlink.xlsx';

const wb = new Excel.Workbook();
const ws = wb.addWorksheet('My Sheet');

ws.getCell('A1').value = {
    hyperlink: 'http://webcode.me',
    text: 'WebCode',
    tooltip: 'http://webcode.me',
};

ws.getCell('A1').font = { underline: true, color: 'blue' };

wb.xlsx
    .writeFile(fileName)
    .then(() => {
        console.log('Done.');
    })
    .catch(err => {
        console.log(err.message);
    });

要创建超链接,我们使用单元格值属性的 hyperlink 属性。我们使用 font 属性使文本带下划线。

ExcelJS 合并单元格

我们可以使用 mergeCells 函数合并单元格。

app.js
const Excel = require('exceljs');

const fileName = 'merged.xlsx';

const wb = new Excel.Workbook();
const ws = wb.addWorksheet('My Sheet');

ws.getCell('A1').value = 'old falcon';
ws.getCell('A1').style.alignment = { horizontal: 'center', vertical: 'middle' };

ws.mergeCells('A1:C4');

wb.xlsx
    .writeFile(fileName)
    .then(() => {
        console.log('file created');
    })
    .catch(err => {
        console.log(err.message);
    });

该示例合并单元格 A1 到 C4。

ExcelJS 公式

要将公式添加到单元格,我们可以使用 formula 属性。

app.js
const Excel = require('exceljs');

const fileName = 'formula.xlsx';

const wb = new Excel.Workbook();
const ws = wb.addWorksheet('My Sheet');

ws.getCell('A1').value = 1;
ws.getCell('A2').value = 2;
ws.getCell('A3').value = 3;
ws.getCell('A4').value = 4;
ws.getCell('A5').value = 5;
ws.getCell('A6').value = 6;

let a7 = ws.getCell('A7');
a7.value = { formula: 'SUM(A1:A6)' };
a7.style.font = { bold: true };

writeFile(wb);

async function writeFile(wb) {
    await wb.xlsx.writeFile(fileName);
}

该示例将 SUM 公式插入到 A7 单元格中。

来源

Excel.js Github 页面

在本文中,我们使用 ExcelJS 库处理了 Excel 文件。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

查看 所有 JavaScript 教程。