add
This commit is contained in:
parent
feae80d0f8
commit
4a111e05f9
|
@ -56,6 +56,7 @@ export default function StaffTable() {
|
||||||
const [defaultFileName] = useState(`员工数据_${new Date().toISOString().slice(0, 10)}`);
|
const [defaultFileName] = useState(`员工数据_${new Date().toISOString().slice(0, 10)}`);
|
||||||
const [paginationEnabled, setPaginationEnabled] = useState(true);
|
const [paginationEnabled, setPaginationEnabled] = useState(true);
|
||||||
const [importVisible, setImportVisible] = useState(false);
|
const [importVisible, setImportVisible] = useState(false);
|
||||||
|
const [selectedRows, setSelectedRows] = useState<any[]>([]);
|
||||||
|
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
setFileNameVisible(true);
|
setFileNameVisible(true);
|
||||||
|
@ -165,9 +166,9 @@ export default function StaffTable() {
|
||||||
field: 'type',
|
field: 'type',
|
||||||
headerName: '人员类型',
|
headerName: '人员类型',
|
||||||
},
|
},
|
||||||
{ field: 'officerId', headerName: '警号'},
|
{ field: 'officerId', headerName: '警号' },
|
||||||
{ field: 'phoneNumber', headerName: '手机号' },
|
{ field: 'phoneNumber', headerName: '手机号' },
|
||||||
{ field: 'age', headerName: '年龄'},
|
{ field: 'age', headerName: '年龄' },
|
||||||
{
|
{
|
||||||
field: 'sex', headerName: '性别',
|
field: 'sex', headerName: '性别',
|
||||||
cellRenderer: (params: any) => {
|
cellRenderer: (params: any) => {
|
||||||
|
@ -182,13 +183,13 @@ export default function StaffTable() {
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
{ field: 'bloodType', headerName: '血型',},
|
{ field: 'bloodType', headerName: '血型', },
|
||||||
{
|
{
|
||||||
field: 'birthplace',
|
field: 'birthplace',
|
||||||
headerName: '籍贯',
|
headerName: '籍贯',
|
||||||
valueFormatter: (params) => params.value ? getAreaName(params.value.split('/')) : '',
|
valueFormatter: (params) => params.value ? getAreaName(params.value.split('/')) : '',
|
||||||
},
|
},
|
||||||
{ field: 'source', headerName: '来源'},
|
{ field: 'source', headerName: '来源' },
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -349,17 +350,79 @@ export default function StaffTable() {
|
||||||
const handleExportTemplate = () => {
|
const handleExportTemplate = () => {
|
||||||
const headerNames = extractHeaders(columnDefs);
|
const headerNames = extractHeaders(columnDefs);
|
||||||
|
|
||||||
// 创建一个空白行对象,键为列名,值为空字符串
|
// 创建示例数据行
|
||||||
const emptyRow = headerNames.reduce((obj, header) => {
|
let exampleRow: Record<string, string> = {};
|
||||||
|
|
||||||
|
// 检查是否有选中行
|
||||||
|
if (selectedRows.length > 0) {
|
||||||
|
// 使用第一条选中的记录作为模板数据
|
||||||
|
const templateData = selectedRows[0];
|
||||||
|
|
||||||
|
// 使用选中的员工数据填充示例行
|
||||||
|
exampleRow = headerNames.reduce((obj, header) => {
|
||||||
|
// 查找表头对应的字段名
|
||||||
|
let fieldName = '';
|
||||||
|
let found = false;
|
||||||
|
|
||||||
|
// 遍历列定义,查找匹配的字段
|
||||||
|
columnDefs.forEach(colDef => {
|
||||||
|
if ('children' in colDef && colDef.children) {
|
||||||
|
colDef.children.forEach(childCol => {
|
||||||
|
if ('field' in childCol && childCol.headerName === header) {
|
||||||
|
fieldName = childCol.field;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if ('field' in colDef && colDef.headerName === header) {
|
||||||
|
fieldName = colDef.field;
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 如果找到了字段名,从模板数据中获取值
|
||||||
|
if (found && fieldName && templateData[fieldName] !== undefined) {
|
||||||
|
// 根据字段类型处理值
|
||||||
|
switch (fieldName) {
|
||||||
|
// 日期类型字段 - 格式化为字符串
|
||||||
|
case 'hireDate':
|
||||||
|
case 'seniority':
|
||||||
|
case 'rankDate':
|
||||||
|
case 'currentPositionDate':
|
||||||
|
obj[header] = templateData[fieldName] ?
|
||||||
|
new Date(templateData[fieldName]).toISOString().split('T')[0] :
|
||||||
|
'';
|
||||||
|
break;
|
||||||
|
// 布尔类型字段 - 转为"是"或"否"
|
||||||
|
case 'sex':
|
||||||
|
obj[header] = templateData[fieldName] === true ? '男' :
|
||||||
|
templateData[fieldName] === false ? '女' : '';
|
||||||
|
break;
|
||||||
|
case 'enabled':
|
||||||
|
case 'isReentry':
|
||||||
|
case 'isExtended':
|
||||||
|
case 'isGraduated':
|
||||||
|
case 'hasTrain':
|
||||||
|
case 'hasCert':
|
||||||
|
obj[header] = templateData[fieldName] ? '是' : '否';
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 其他字段 - 直接使用值
|
||||||
|
default:
|
||||||
|
obj[header] = templateData[fieldName] !== null &&
|
||||||
|
templateData[fieldName] !== undefined ?
|
||||||
|
String(templateData[fieldName]) : '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 如果没有找到对应的值,设为空字符串
|
||||||
obj[header] = '';
|
obj[header] = '';
|
||||||
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}, {} as Record<string, string>);
|
}, {} as Record<string, string>);
|
||||||
|
} else {
|
||||||
// 创建示例数据行
|
// 如果没有选中行,使用默认示例数据
|
||||||
const exampleRow = headerNames.reduce((obj, header) => {
|
exampleRow = headerNames.reduce((obj, header) => {
|
||||||
// 根据不同的表头设置不同的示例值
|
// 根据不同的表头设置不同的示例值
|
||||||
switch(header) {
|
switch (header) {
|
||||||
// 基本信息示例
|
|
||||||
case '姓名': obj[header] = '张三'; break;
|
case '姓名': obj[header] = '张三'; break;
|
||||||
case '身份证号': obj[header] = '110101199001011234'; break;
|
case '身份证号': obj[header] = '110101199001011234'; break;
|
||||||
case '人员类型': obj[header] = '在职'; break;
|
case '人员类型': obj[header] = '在职'; break;
|
||||||
|
@ -367,70 +430,46 @@ export default function StaffTable() {
|
||||||
case '手机号': obj[header] = '13800138000'; break;
|
case '手机号': obj[header] = '13800138000'; break;
|
||||||
case '年龄': obj[header] = '30'; break;
|
case '年龄': obj[header] = '30'; break;
|
||||||
case '性别': obj[header] = '男'; break;
|
case '性别': obj[header] = '男'; break;
|
||||||
case '血型': obj[header] = 'A型'; break;
|
// ... 其他默认示例值保持不变
|
||||||
case '籍贯': obj[header] = '北京市海淀区'; break;
|
default: obj[header] = ''; break;
|
||||||
case '来源': obj[header] = '社会招聘'; break;
|
|
||||||
|
|
||||||
// 政治信息示例
|
|
||||||
case '政治面貌': obj[header] = '党员'; break;
|
|
||||||
case '党内职务': obj[header] = '支部书记'; break;
|
|
||||||
|
|
||||||
// 职务信息示例
|
|
||||||
case '所属部门': obj[header] = '技术部'; break;
|
|
||||||
case '衔职级别': obj[header] = '三级警司'; break;
|
|
||||||
case '衔职时间': obj[header] = '2020-01-01'; break;
|
|
||||||
case '代理职务': obj[header] = '技术组长'; break;
|
|
||||||
case '岗位': obj[header] = '技术开发'; break;
|
|
||||||
|
|
||||||
// 入职信息示例
|
|
||||||
case '入职时间': obj[header] = '2015-07-01'; break;
|
|
||||||
case '工龄认定时间': obj[header] = '2015-07-01'; break;
|
|
||||||
case '来源类型': obj[header] = '招聘'; break;
|
|
||||||
case '是否二次入职': obj[header] = '否'; break;
|
|
||||||
case '是否延期服役': obj[header] = '否'; break;
|
|
||||||
case '现岗位开始时间': obj[header] = '2018-05-01'; break;
|
|
||||||
|
|
||||||
// 教育背景示例
|
|
||||||
case '学历': obj[header] = '本科'; break;
|
|
||||||
case '学历形式': obj[header] = '全日制'; break;
|
|
||||||
case '是否毕业': obj[header] = '是'; break;
|
|
||||||
case '专业': obj[header] = '计算机科学与技术'; break;
|
|
||||||
case '外语能力': obj[header] = '英语四级'; break;
|
|
||||||
|
|
||||||
// 培训信息示例
|
|
||||||
case '培训类型': obj[header] = '专业技能'; break;
|
|
||||||
case '培训机构': obj[header] = '公安大学'; break;
|
|
||||||
case '培训专业': obj[header] = '网络安全'; break;
|
|
||||||
case '是否参加培训': obj[header] = '是'; break;
|
|
||||||
|
|
||||||
// 鉴定信息示例
|
|
||||||
case '鉴定等级': obj[header] = '高级'; break;
|
|
||||||
case '鉴定工种': obj[header] = '信息安全'; break;
|
|
||||||
case '是否参加鉴定': obj[header] = '是'; break;
|
|
||||||
|
|
||||||
// 工作信息示例
|
|
||||||
case '操作维护装备': obj[header] = '服务器,网络设备,安全设备'; break;
|
|
||||||
case '演训任务经历': obj[header] = '2019年网络安全演习,2020年数据恢复演练'; break;
|
|
||||||
case '奖励信息': obj[header] = '2018年度优秀员工,2020年技术创新奖'; break;
|
|
||||||
case '处分信息': obj[header] = ''; break;
|
|
||||||
|
|
||||||
default: obj[header] = `示例${header}`; break;
|
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}, {} as Record<string, string>);
|
}, {} as Record<string, string>);
|
||||||
|
}
|
||||||
|
|
||||||
// 创建工作簿和工作表,包含示例行和空白行
|
// 创建空白行供用户填写
|
||||||
|
const emptyRow = headerNames.reduce((obj, header) => {
|
||||||
|
obj[header] = '';
|
||||||
|
return obj;
|
||||||
|
}, {} as Record<string, string>);
|
||||||
|
|
||||||
|
// 创建工作簿和工作表
|
||||||
const wb = utils.book_new();
|
const wb = utils.book_new();
|
||||||
const ws = utils.json_to_sheet([exampleRow, emptyRow], { header: headerNames });
|
const ws = utils.json_to_sheet([exampleRow], { header: headerNames });
|
||||||
|
|
||||||
// 设置列宽
|
// 设置列宽
|
||||||
const colWidth = headerNames.map(() => ({ wch: 20 }));
|
const colWidth = headerNames.map(() => ({ wch: 20 }));
|
||||||
ws['!cols'] = colWidth;
|
ws['!cols'] = colWidth;
|
||||||
|
|
||||||
// 添加一些样式表示示例数据行
|
// 在第二行添加提示文字
|
||||||
// XLSX.js 不直接支持样式,但我们可以添加注释
|
const rowIdx = 2; // 第二行索引
|
||||||
const note = { t: 's', v: '以上为示例数据,请在下方行填写实际数据' };
|
const cellRef = utils.encode_cell({ r: rowIdx, c: 0 }); // A3单元格
|
||||||
ws['A3'] = note;
|
|
||||||
|
const tipText = selectedRows.length > 0
|
||||||
|
? '以上为选中人员数据,请在下方行填写实际数据'
|
||||||
|
: '以上为示例数据,请在下方行填写实际数据';
|
||||||
|
|
||||||
|
ws[cellRef] = { t: 's', v: tipText };
|
||||||
|
|
||||||
|
// 手动添加空白行
|
||||||
|
utils.sheet_add_json(ws, [emptyRow], { skipHeader: true, origin: rowIdx + 1 });
|
||||||
|
|
||||||
|
// 合并提示文字单元格
|
||||||
|
if (!ws['!merges']) ws['!merges'] = [];
|
||||||
|
ws['!merges'].push({
|
||||||
|
s: { r: rowIdx, c: 0 }, // 起始单元格 A3
|
||||||
|
e: { r: rowIdx, c: Math.min(5, headerNames.length - 1) } // 结束单元格,跨越多列
|
||||||
|
});
|
||||||
|
|
||||||
utils.book_append_sheet(wb, ws, "员工模板");
|
utils.book_append_sheet(wb, ws, "员工模板");
|
||||||
writeFile(wb, `员工数据模板_${new Date().toISOString().slice(0, 10)}.xlsx`);
|
writeFile(wb, `员工数据模板_${new Date().toISOString().slice(0, 10)}.xlsx`);
|
||||||
|
@ -712,7 +751,7 @@ export default function StaffTable() {
|
||||||
) : (
|
) : (
|
||||||
<AgGridReact
|
<AgGridReact
|
||||||
modules={[SetFilterModule, ClientSideRowModelModule]}
|
modules={[SetFilterModule, ClientSideRowModelModule]}
|
||||||
onGridReady={(params) => setGridApi(params.api)} // 添加gridApi回调
|
onGridReady={(params) => setGridApi(params.api)}
|
||||||
rowData={staffs}
|
rowData={staffs}
|
||||||
columnDefs={columnDefs}
|
columnDefs={columnDefs}
|
||||||
defaultColDef={{
|
defaultColDef={{
|
||||||
|
@ -725,6 +764,10 @@ export default function StaffTable() {
|
||||||
pagination={paginationEnabled}
|
pagination={paginationEnabled}
|
||||||
paginationAutoPageSize={true}
|
paginationAutoPageSize={true}
|
||||||
cacheQuickFilter={true}
|
cacheQuickFilter={true}
|
||||||
|
rowSelection="single"
|
||||||
|
onSelectionChanged={(event) => {
|
||||||
|
setSelectedRows(event.api.getSelectedRows());
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue