这列数据看起来好挤
想要两个自动
- 表头比数据宽就按表头
- 数据比表头宽就按数据
比如:
完美,哈哈哈哈
export function exportExcel(headers = [], data = [], name = 'excel') {
// 创建工作簿
const workbook = new ExcelJS.Workbook()
// 添加工作表
const worksheet = workbook.addWorksheet('sheet1')
// 设置表头
worksheet.columns = headers
const border = {
top: {
style: 'thin',
},
left: {
style: 'thin',
},
bottom: {
style: 'thin',
},
right: {
style: 'thin',
},
}
// 添加数据
data.map((row, index) => {
worksheet.addRow(row)
worksheet.columns.map((column) => {
// 表头的样式
worksheet.getCell(`${column.letter}1`).border = border
worksheet.getCell(`${column.letter}1`).font = {
bold: true,
}
worksheet.getCell(`${column.letter}1`).fill = {
type: 'pattern',
pattern: 'solid',
fgColor: { argb: 'FF8FBC8F' },
}
// 列宽自适应
let width = []
column.values.map((value) => {
if (!value) {
width.push(10)
} else if (/.*[\u4e00-\u9fa5]+.*$/.test(value)) {
width.push(parseFloat(value.toString().length * 2.15))
} else {
width.push(parseFloat(value.toString().length * 1.15))
}
})
column.width = Math.max(...width)
// 行数据的样式
worksheet.getCell(`${column.letter}${index + 2}`).border = border
})
})
// 导出表格
// workbook.xlsx.writeFile('测试' + '.xlsx') // 报错
workbook.xlsx.writeBuffer().then((buffer) => {
const blob = new Blob([buffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
})
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = name + '.xlsx'
link.click()
URL.revokeObjectURL(link.href) // 下载完成释放掉blob对象
})
}
如果想要数据验证,有下拉框的单元格。可以设置 dataValidation
:
if (headers[i].formulae) {
// 设置数据校验
worksheet.getCell(`${column.letter}${index+2}`).dataValidation = {
type: "list",
allowBlank: true,
formulae: headers[i].formulae,
};
};
表头的数据这样传:
传入formulae
字段。格式就是 [一个逗号隔开的字符串]
参考通义千问和郭老师的小迷弟雅思莫了-编写提供,主要是为了帮助您快速解决问题,如下回答,您可以参考下,如有问题,评论区留言。
ExcelJS 是一个用于处理和生成 Excel (.xlsx) 文件的 JavaScript 库,但它并不直接支持列宽自动调整为完全匹配内容宽度的功能。在 ExcelJS 中设置列宽时,你需要手动指定每个列的宽度。
尽管如此,你可以尝试以下方法来尽量模拟这种效果:
获取最大宽度:
getTextWidth
这样的库(或者自定义函数)计算字符串在默认字体、字号下的像素宽度,然后转换成 Excel 的列宽单位(例如,Excel 的列宽最小单位是 0.125 字符宽度)。设置列宽:
worksheet.getColumn(columnNumber).width = maxWidthInChars;
来设置每列的宽度。下面是一个简化的示例逻辑:
// 假设 data 是二维数组,表示表格数据
const data = [
['Header 1', 'Very Long Data Entry'],
// ...
];
// 获取每列最大宽度(这里仅作示意,实际需要实现文本宽度计算)
let columnWidths = {};
data.forEach(row => {
row.forEach((cell, index) => {
if (!columnWidths[index]) {
columnWidths[index] = cell.length;
} else {
columnWidths[index] = Math.max(columnWidths[index], cell.length);
}
});
});
// 设置列宽
Object.entries(columnWidths).forEach(([index, width]) => {
worksheet.getColumn(index + 1).width = width * someFactor; // 考虑到字符宽度与字符数的比例,可能需要乘以某个系数
});
请注意上述代码仅为示例,并未考虑到文本的实际渲染宽度(换行、特殊字符等),若要精确匹配,你可能需要借助更为复杂的文本测量技术或预览生成后的 Excel 文件进行微调。目前 ExcelJS 并不具备原生的“根据内容自动调整列宽”功能。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>exceljs 使用</title>
</head>
<body>
<button onclick="exporting()">导出</button>
<script>
function exporting() {
exportExcel(
// 表头
[{
header: '名次',
key: 'sort',
},
{
header: '班级',
key: 'class',
},
{
header: '姓名',
key: 'name'
},
{
header: '得分',
key: 'score',
},
{
header: '等级',
key: 'level',
formulae: ['"值1,值2,值3"'] // 格式就是这样 https://github.com/exceljs/exceljs/blob/master/README_zh.md#%E6%95%B0%E6%8D%AE%E9%AA%8C%E8%AF%81
},
],
// 数据
[{
sort: 1,
class: '前端三班',
name: 'Buer',
score: 99
},
{
sort: 2,
class: '前端二班',
name: 'Jack',
score: 86
},
{
sort: 3,
class: '前端一班',
name: 'Mary',
score: 58
}
]
)
};
function exportExcel(headers = [], data = [], name = 'excel') {
// 创建工作簿
const workbook = new ExcelJS.Workbook()
// 添加工作表
const worksheet = workbook.addWorksheet('sheet1')
// 设置表头
worksheet.columns = headers
const border = {
top: {
style: 'thin',
},
left: {
style: 'thin',
},
bottom: {
style: 'thin',
},
right: {
style: 'thin',
},
}
// 添加数据
data.map((row, index) => {
worksheet.addRow(row)
worksheet.columns.map((column, i) => {
if (headers[i].formulae) {
// 设置数据校验
worksheet.getCell(`${column.letter}${index+2}`).dataValidation = {
type: "list",
allowBlank: true,
formulae: headers[i].formulae,
};
};
// 表头的样式
worksheet.getCell(`${column.letter}1`).border = border
worksheet.getCell(`${column.letter}1`).font = {
bold: true,
}
worksheet.getCell(`${column.letter}1`).fill = {
type: 'pattern',
pattern: 'solid',
fgColor: {
argb: 'FF8FBC8F'
},
};
// 列宽自适应
let width = []
column.values.map((value) => {
if (!value) {
width.push(10)
} else if (/.*[\u4e00-\u9fa5]+.*$/.test(value)) {
width.push(parseFloat(value.toString().length * 2.15))
} else {
width.push(parseFloat(value.toString().length * 1.15))
}
})
column.width = Math.max(...width)
// 行数据的样式
worksheet.getCell(`${column.letter}${index + 2}`).border = border
})
})
// 导出表格
workbook.xlsx.writeBuffer().then((buffer) => {
const blob = new Blob([buffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
})
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = name + '.xlsx'
link.click()
URL.revokeObjectURL(link.href) // 下载完成释放掉blob对象
})
}
</script>
<script src="https://cdn.jsdelivr.net/npm/exceljs@4.4.0"></script>
</body>
</html>