ExcelJS如何动态生成表格数据、加粗表头并在A1单元格插入图片
React + ExcelJS 导出Excel实现方案
针对动态表头填充、表头加粗、A1单元格插入图片三个需求,直接调整原有代码逻辑即可,核心修改点如下:
- 把workbook、worksheet的初始化逻辑移到导出函数内部,避免多次导出时实例缓存导致的数据残留问题
- 自动读取传入JSON数组的首行键名生成列配置,无需硬编码表头,直接传入全量数据完成行填充
- 拿到表头行对象遍历设置单元格加粗样式
- 加载图片资源添加到工作簿,锚定到A1单元格完成插入,可自定义调整行高列宽适配图片尺寸
完整实现代码
import React, { useContext } from 'react'; import ExcelJS from 'exceljs'; import AlertContext from '../../AlertContext'; import { errorAlert } from '../Alert'; // 示例:导入本地logo图片,根据实际项目路径替换 import logoImg from '../../assets/logo.png'; const useFileExportToExcel = <T extends object>() => { const { setAlert } = useContext(AlertContext); return async (dataTableRows: T[], fileName: string) => { try { // 初始化工作簿、工作表 const workbook = new ExcelJS.Workbook(); const worksheet = workbook.addWorksheet('sheet1'); // 1. 动态生成表头配置:空数据兜底 let columns: ExcelJS.Column[] = []; if (dataTableRows.length > 0) { columns = Object.keys(dataTableRows[0]).map(key => ({ header: key, // 可根据业务需求做表头中文映射,比如维护一个key到中文名的对象 key: key, width: 20 // 统一设置默认列宽,可按需调整 })); } worksheet.columns = columns; // 因为A1要插入图片,把表头行偏移到第2行,避免图片遮挡表头,不需要可删除下方spliceRows逻辑 if (columns.length > 0) { worksheet.spliceRows(1, 0, []); } // 2. 动态填充表格数据 worksheet.addRows(dataTableRows); // 3. 设置表头加粗样式:如果删除了表头偏移逻辑,这里改成getRow(1)即可 const headerRow = worksheet.getRow(2); headerRow.eachCell(cell => { cell.font = { bold: true, size: 12 }; // 可选:设置表头背景色 // cell.fill = { // type: 'pattern', // pattern: 'solid', // fgColor: { argb: 'FFf0f0f0' } // } }); // 4. A1单元格插入图片 // 加载图片资源转ArrayBuffer const imgRes = await fetch(logoImg); const imgBuffer = await imgRes.arrayBuffer(); const imgId = workbook.addImage({ buffer: imgBuffer, extension: 'png', // 根据实际图片格式修改,支持jpg/png/gif等 }); // 插入图片锚定到A1单元格,自定义宽高 worksheet.addImage(imgId, { tl: { col: 0, row: 0 }, // 锚定左上角A1位置(col/row从0开始计数) ext: { width: 120, height: 60 } // 图片显示宽高,单位像素 }); // 调整第一行行高适配图片 worksheet.getRow(1).height = 65; // 导出文件逻辑 const data = await workbook.xlsx.writeBuffer(); const blob = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', }); const a = window.document.createElement('a'); const downloadUrl = window.URL.createObjectURL(blob); a.href = downloadUrl; a.download = `${fileName}.xlsx`; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(downloadUrl); } catch (err) { setAlert(errorAlert('导出过程中出现错误')); } }; }; export default useFileExportToExcel;
使用说明
- 表头中文映射:如果需要把JSON的英文键显示为中文表头,只需维护一个键名映射对象,在生成columns配置时把
header属性替换为映射后的中文名即可 - 图片位置调整:如果不需要图片独占A1位置、要让表头和图片同处第一行,删除代码里表头偏移的
spliceRows逻辑,将获取表头行的代码改为worksheet.getRow(1)即可,图片会浮动在A1单元格位置 - 格式处理:时间、数字等特殊格式可在
addRows之前遍历dataTableRows做统一值转换,也可拿到对应单元格后设置numFmt属性定义Excel原生格式
常见问题提示
- 线上图片跨域:如果插入的是存放在CDN的线上图片,需要确保CDN配置了跨域访问允许,否则fetch加载图片时会报错
- 空数据处理:如果传入的
dataTableRows为空数组,可根据业务需求添加自定义提示文本到工作表- 样式扩展:除了加粗外,还可给单元格设置边框、对齐方式、背景色等样式,直接在遍历单元格时追加对应属性即可
内容的提问来源于stack exchange,提问作者Lizi
相关产品推荐
相关产品推荐

