ReportTable.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import React, { useMemo, useState } from 'react';
  2. import { Button, Modal, Table, Tooltip } from 'antd';
  3. import * as XLSX from 'xlsx';
  4. const ReportTable = ({ data, month }) => {
  5. const [visible, setVisible] = useState(false);
  6. const [item, setItem] = useState({});
  7. // 将 data 对象解析为表格的 dataSource
  8. const dataSource = useMemo(() => {
  9. if (!data) return [];
  10. // return data
  11. return data.filter(
  12. item => item.unsubmittedReports.length > 0 || item.lateSubmissions.length > 0
  13. );
  14. }, [data]);
  15. const exportToExcel = () => {
  16. const worksData1 = dataSource
  17. .filter(item => item.unsubmittedReports.length > 0 || item.lateSubmissions.length > 0)
  18. .map(item => ({
  19. 工号: item.userId,
  20. 姓名: item.name,
  21. 迟交次数: item.lateSubmissions.length,
  22. 漏交次数: item.unsubmittedReports.length,
  23. 请假次数: item.takingLeaveReports.length,
  24. }));
  25. const worksheet1 = XLSX.utils.json_to_sheet(worksData1);
  26. const worksData2 = dataSource.map(item => ({
  27. 工号: item.userId,
  28. 姓名: item.name,
  29. 迟交: item.lateSubmissions.join(','),
  30. 漏交: item.unsubmittedReports.join(','),
  31. 请假: item.takingLeaveReports.join(','),
  32. 离职时间: item.resignationDate,
  33. 入职时间: item.hiredDate,
  34. }));
  35. const worksheet2 = XLSX.utils.json_to_sheet(worksData2);
  36. const workbook = XLSX.utils.book_new();
  37. XLSX.utils.book_append_sheet(workbook, worksheet1, '总览');
  38. XLSX.utils.book_append_sheet(workbook, worksheet2, '详情');
  39. const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
  40. const data = new Blob([excelBuffer], {
  41. type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  42. });
  43. const url = URL.createObjectURL(data);
  44. const link = document.createElement('a');
  45. link.href = url;
  46. link.setAttribute('download', `${month}月考勤数据.xlsx`);
  47. document.body.appendChild(link);
  48. link.click();
  49. document.body.removeChild(link);
  50. };
  51. // 表格列配置
  52. const columns = [
  53. {
  54. title: '工号',
  55. dataIndex: 'userId',
  56. key: 'userId',
  57. },
  58. {
  59. title: '名称',
  60. dataIndex: 'name',
  61. key: 'name',
  62. },
  63. {
  64. title: '漏交',
  65. dataIndex: 'unsubmittedReports',
  66. key: 'unsubmittedReports',
  67. render: unsubmittedReports => (
  68. <Tooltip title={unsubmittedReports.join(',')}>
  69. <a>{unsubmittedReports.length}</a>
  70. </Tooltip>
  71. ),
  72. },
  73. {
  74. title: '迟交',
  75. dataIndex: 'lateSubmissions',
  76. key: 'lateSubmissions',
  77. render: lateSubmissions => (
  78. <Tooltip title={lateSubmissions.join(',')}>
  79. <a>{lateSubmissions.length}</a>
  80. </Tooltip>
  81. ),
  82. },
  83. {
  84. title: '请假',
  85. dataIndex: 'takingLeaveReports',
  86. key: 'takingLeaveReports',
  87. render: takingLeaveReports => (
  88. <Tooltip title={takingLeaveReports.join(',')}>
  89. <a>{takingLeaveReports.length}</a>
  90. </Tooltip>
  91. ),
  92. },
  93. {
  94. title: '离职日期',
  95. dataIndex: 'resignationDate',
  96. key: 'resignationDate',
  97. },
  98. {
  99. title: '入职日期',
  100. dataIndex: 'hiredDate',
  101. key: 'hiredDate',
  102. },
  103. {
  104. title: '操作',
  105. render: item => <a onClick={() => showModal(item)}>日志提交时间</a>,
  106. },
  107. ];
  108. const showModal = item => {
  109. setItem(item);
  110. setVisible(true);
  111. };
  112. return (
  113. <>
  114. <Table
  115. dataSource={dataSource}
  116. footer={() => (
  117. <Button onClick={exportToExcel} type="primary">
  118. 导出报表
  119. </Button>
  120. )}
  121. columns={columns}
  122. />
  123. <Modal
  124. title="日志提交记录"
  125. visible={visible}
  126. onCancel={() => setVisible(false)}
  127. footer={null}
  128. >
  129. {item.dates?.map((item, index) => (
  130. <div style={{ margin: '5px 0' }} key={index}>
  131. {item.format('YYYY-MM-DD HH:mm:ss')}
  132. </div>
  133. ))}
  134. </Modal>
  135. </>
  136. );
  137. };
  138. export default ReportTable;