要用到的2个包:
exceljs文档
FileSaver文档(用于保存文件下载)
基本导出案例:
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('My Sheet');
// 设置列
worksheet.columns = [
{ header: 'Id', key: 'id', width: 10 },
{ header: 'Name', key: 'name', width: 32 },
{ header: 'D.O.B.', key: 'DOB', width: 10 }
];
// 插入数据
worksheet.addRow({ id: 1, name: 'John Doe', DOB: '2022-06-18' });
worksheet.addRow({ id: 2, name: 'Jane Doe', DOB: '2022-06-18' });
// 写入文件
const buffer = await workbook.xlsx.writeBuffer();
FileSaver.saveAs(new Blob([buffer]), `${formatMessage({ id: 'menu.LeaveManagement.WorkforceManagement' }) + '-' + filterDate}.xlsx`)
具体的灵活操作可以参考exceljs文档
如下图,导出后用户只能进行选择单元格值的功能,在文档中搜索 “数据验证”
image.png
image.png
具体案例
有不懂的可以复制属性在文档中搜索
// 导出
const exportExcel = async (selectedRows: any[]) => {
const workbook = new ExcelJS.Workbook(); // 新建文档
const worksheet = workbook.addWorksheet('Sheet1', { //新建工作表
views: [{ state: 'frozen', xSplit: 4, ySplit: 0 }], // 冻结视图:xSplit:冻结多少列
properties: { defaultColWidth: 18 } // 默认列宽
});
// 列数据
let _columns = [...columns, ...dateColumns];
_columns = _columns.filter(item => (!item.hideInTable && item.dataIndex != 'index')).map(item => ({
header: item.title,
key: item.dataIndex
}));
worksheet.columns = [{ // 第一列增加可选班次对象,导入时对照出id用
header: '可选班次对象',
key: 'workShiftObj',
hidden: true
}, ..._columns];
// 批量通过考勤组织id查询考勤班次
let attendanceIds = selectedRows.map(item => item.attendance_org_id);
attendanceIds = [...new Set(attendanceIds)]; // 去重
const { data: workShifts } = await getWorkscheduleByIds(attendanceIds);
// [{
// attendance_org_id: "***"
// id: "***"
// name: "B"
// tenant_id: "***"
// type: 1
// }]
// 数据
let _selectedRows = JSON.parse(JSON.stringify(selectedRows));
for (let i = 0; i < _selectedRows.length; i++) {
for (let key in _selectedRows[i]) {
if (_selectedRows[i][key].attendance_work_shift_name) {
_selectedRows[i][key] = _selectedRows[i][key].attendance_work_shift_name;
}
}
// 给第一列可选班次对象赋值
_selectedRows[i].workShiftObj = workShifts.find((item: { attendance_org_id: string; }) => item.attendance_org_id == _selectedRows[i].attendance_org_id); // 考勤组织Id一致
}
worksheet.addRows(_selectedRows); // 添加行数据
// 遍历工作表中具有值的所有行
worksheet.eachRow(function (row, rowNumber) {
// 连续遍历所有非空单元格
row.eachCell(function (cell, colNumber) {
// console.log('Cell ' + rowNumber + '-' + colNumber + ' = ' + cell.value);
if (rowNumber > 1 && colNumber > 4) { // 标题不给范围 前3个列不给范围
cell.dataValidation = {
type: 'list',
allowBlank: true, // 允许为空
showErrorMessage: true,
errorStyle: 'error',
formulae: [`"${workShifts.map((item: { name: string; }) => item.name).join(',')}"`]
// formulae: ['"One,Two,Three,Four"']
};
cell.protection = { locked: false }; // 锁定后 这些列可编辑,不设置的话整个文档都不可编辑了
}
});
});
// 锁定文档,防止用户操作不该操作的列
await worksheet.protect('the/pass_word/danger', {
selectLockedCells: false
});
// 写入文件导出
const buffer = await workbook.xlsx.writeBuffer();
FileSaver.saveAs(new Blob([buffer]), `${formatMessage({ id: 'menu.LeaveManagement.WorkforceManagement' }) + '-' + filterDate}.xlsx`)
};
导入
async function importExcel(file: Buffer) {
const workbook = new ExcelJS.Workbook(); // new一下
await workbook.xlsx.load(file); // 读文件
const worksheet = workbook.getWorksheet(1); // 读sheet1
const row2: any = worksheet.getRow(2); // 读第二行数据
row2.values.forEach((item: any) => { // 处理第2行的数据
});
worksheet.eachRow(function (row, rowNumber) { // 遍历行
row.eachCell(function (cell, colNumber) { // 遍历每一行的列
cell.value // 列值
});
});
}
ExcelJS只能读取buffer类型,所以需要用到文件转buffer
转buffer方法:
function getBuffer(file: File) {
let reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onload = function (e: any) {
try {
let res = e.target.result; // ArrayBuffer
let buf = Buffer.from(res); // Buffer
importExcel(buf);
} catch { }
}
}
网友评论