256 lines
7.5 KiB
TypeScript
256 lines
7.5 KiB
TypeScript
import * as XLSX from 'xlsx'
|
|
import type { SalaryRecord } from '../types'
|
|
|
|
// 导出工资单到Excel
|
|
export const exportSalaryToExcel = (records: SalaryRecord[], filename: string) => {
|
|
// 创建工作簿
|
|
const workbook = XLSX.utils.book_new()
|
|
|
|
// 主表数据
|
|
const mainData = records.map((record) => ({
|
|
员工姓名: record.employeeName,
|
|
员工类型: getEmployeeTypeText(record.employeeType),
|
|
身份证号: record.idCard,
|
|
联系电话: record.phone,
|
|
银行卡号: record.bankCard,
|
|
开户银行: record.bankName,
|
|
项目名称: record.projectName,
|
|
项目周期: record.projectPeriod,
|
|
工作天数: record.workDays,
|
|
海上作业天数: record.offshoreDays,
|
|
基本工资: record.baseSalary,
|
|
绩效奖金: record.performanceBonus,
|
|
各类补助: record.allowances,
|
|
应发总额: record.totalPayable,
|
|
扣款金额: record.deductions,
|
|
实发金额: record.netPay,
|
|
状态: getStatusText(record.status),
|
|
创建时间: record.createdAt,
|
|
}))
|
|
|
|
// 创建主表
|
|
const mainSheet = XLSX.utils.json_to_sheet(mainData)
|
|
XLSX.utils.book_append_sheet(workbook, mainSheet, '工资汇总')
|
|
|
|
// 绩效明细表
|
|
const performanceData: any[] = []
|
|
records.forEach((record) => {
|
|
record.performanceItems.forEach((item) => {
|
|
performanceData.push({
|
|
员工姓名: record.employeeName,
|
|
项目名称: record.projectName,
|
|
评价项: item.name,
|
|
权重: item.weight,
|
|
得分: item.score,
|
|
满分: item.maxScore,
|
|
金额: (item.score / item.maxScore * item.amount).toFixed(2),
|
|
})
|
|
})
|
|
})
|
|
|
|
if (performanceData.length > 0) {
|
|
const performanceSheet = XLSX.utils.json_to_sheet(performanceData)
|
|
XLSX.utils.book_append_sheet(workbook, performanceSheet, '绩效明细')
|
|
}
|
|
|
|
// 补助明细表
|
|
const allowanceData: any[] = []
|
|
records.forEach((record) => {
|
|
record.allowanceItems.forEach((item) => {
|
|
allowanceData.push({
|
|
员工姓名: record.employeeName,
|
|
项目名称: record.projectName,
|
|
补助类型: item.name,
|
|
标准: item.amount,
|
|
单位: getUnitText(item.unit),
|
|
数量: item.quantity,
|
|
小计: item.total,
|
|
})
|
|
})
|
|
})
|
|
|
|
if (allowanceData.length > 0) {
|
|
const allowanceSheet = XLSX.utils.json_to_sheet(allowanceData)
|
|
XLSX.utils.book_append_sheet(workbook, allowanceSheet, '补助明细')
|
|
}
|
|
|
|
// 导出文件
|
|
XLSX.writeFile(workbook, filename)
|
|
}
|
|
|
|
// 导出单个工资单详情
|
|
export const exportSingleSalaryToExcel = (record: SalaryRecord) => {
|
|
const workbook = XLSX.utils.book_new()
|
|
|
|
// 基本信息
|
|
const basicInfo = [{
|
|
项目: '员工姓名',
|
|
值: record.employeeName,
|
|
}, {
|
|
项目: '员工类型',
|
|
值: getEmployeeTypeText(record.employeeType),
|
|
}, {
|
|
项目: '身份证号',
|
|
值: record.idCard,
|
|
}, {
|
|
项目: '联系电话',
|
|
值: record.phone,
|
|
}, {
|
|
项目: '银行卡号',
|
|
值: record.bankCard,
|
|
}, {
|
|
项目: '开户银行',
|
|
值: record.bankName,
|
|
}, {
|
|
项目: '项目名称',
|
|
值: record.projectName,
|
|
}, {
|
|
项目: '项目周期',
|
|
值: record.projectPeriod,
|
|
}, {
|
|
项目: '工作天数',
|
|
值: record.workDays,
|
|
}, {
|
|
项目: '海上作业天数',
|
|
值: record.offshoreDays,
|
|
}]
|
|
|
|
const basicSheet = XLSX.utils.json_to_sheet(basicInfo)
|
|
XLSX.utils.book_append_sheet(workbook, basicSheet, '基本信息')
|
|
|
|
// 薪酬汇总
|
|
const salarySummary = [{
|
|
项目: '基本工资',
|
|
金额: record.baseSalary,
|
|
}, {
|
|
项目: '绩效奖金',
|
|
金额: record.performanceBonus,
|
|
}, {
|
|
项目: '各类补助',
|
|
金额: record.allowances,
|
|
}, {
|
|
项目: '应发总额',
|
|
金额: record.totalPayable,
|
|
}, {
|
|
项目: '扣款金额',
|
|
金额: record.deductions,
|
|
}, {
|
|
项目: '实发金额',
|
|
金额: record.netPay,
|
|
}]
|
|
|
|
const salarySheet = XLSX.utils.json_to_sheet(salarySummary)
|
|
XLSX.utils.book_append_sheet(workbook, salarySheet, '薪酬汇总')
|
|
|
|
// 绩效明细
|
|
if (record.performanceItems.length > 0) {
|
|
const performanceSheet = XLSX.utils.json_to_sheet(record.performanceItems.map((item) => ({
|
|
评价项: item.name,
|
|
权重: item.weight,
|
|
得分: item.score,
|
|
满分: item.maxScore,
|
|
金额: (item.score / item.maxScore * item.amount).toFixed(2),
|
|
})))
|
|
XLSX.utils.book_append_sheet(workbook, performanceSheet, '绩效明细')
|
|
}
|
|
|
|
// 补助明细
|
|
if (record.allowanceItems.length > 0) {
|
|
const allowanceSheet = XLSX.utils.json_to_sheet(record.allowanceItems.map((item) => ({
|
|
补助类型: item.name,
|
|
标准: item.amount,
|
|
单位: getUnitText(item.unit),
|
|
数量: item.quantity,
|
|
小计: item.total,
|
|
})))
|
|
XLSX.utils.book_append_sheet(workbook, allowanceSheet, '补助明细')
|
|
}
|
|
|
|
// 导出文件
|
|
const filename = `${record.employeeName}_工资单_${record.projectPeriod}.xlsx`
|
|
XLSX.writeFile(workbook, filename)
|
|
}
|
|
|
|
// 导出实习报酬申领表格式
|
|
export const exportInternCompensationForm = (record: SalaryRecord) => {
|
|
const workbook = XLSX.utils.book_new()
|
|
|
|
// 实习生基本信息
|
|
const basicInfo = [
|
|
['实习生基本信息', '', '', '', ''],
|
|
['类别', '填写内容', '', '备注', ''],
|
|
['姓名', record.employeeName, '', '', ''],
|
|
['身份证号', record.idCard, '', '', ''],
|
|
['联系电话', record.phone, '', '', ''],
|
|
['银行卡号', record.bankCard, '', '', ''],
|
|
['开户银行', record.bankName, '', '', ''],
|
|
['', '', '', '', ''],
|
|
['实习项目及项目实习相关信息', '', '', '', ''],
|
|
['序号', '项目名称', '在项目时间', '出外业施工作业时间(天)', '备注(时间段)'],
|
|
['1', record.projectName, record.workDays, record.workDays - record.offshoreDays, record.projectPeriod],
|
|
['', '', '', '', ''],
|
|
['薪酬、绩效、补助(一)', '', '', '', ''],
|
|
['项目类别', '计算标准(元/天)或(元/台)', '计酬天数统计(日)', '应发金额', '备注'],
|
|
['基本工资', record.baseSalaryStandard, record.workDays, record.baseSalary, ''],
|
|
['施工绩效', 100, record.workDays - record.offshoreDays, record.performanceBonus, ''],
|
|
['海上作业绩效补助', 30, record.offshoreDays, record.offshoreDays * 30, ''],
|
|
['务餐补助', 45, record.workDays, record.allowances, ''],
|
|
['合计应发金额', '', '', record.totalPayable, ''],
|
|
]
|
|
|
|
const sheet = XLSX.utils.aoa_to_sheet(basicInfo)
|
|
|
|
// 设置列宽
|
|
const cols = [
|
|
{ wch: 20 },
|
|
{ wch: 20 },
|
|
{ wch: 15 },
|
|
{ wch: 25 },
|
|
{ wch: 20 },
|
|
]
|
|
sheet['!cols'] = cols
|
|
|
|
// 合并单元格
|
|
sheet['!merges'] = [
|
|
{ s: { r: 0, c: 0 }, e: { r: 0, c: 4 } },
|
|
{ s: { r: 8, c: 0 }, e: { r: 8, c: 4 } },
|
|
{ s: { r: 12, c: 0 }, e: { r: 12, c: 4 } },
|
|
]
|
|
|
|
XLSX.utils.book_append_sheet(workbook, sheet, '实习报酬申领表')
|
|
|
|
// 导出文件
|
|
const filename = `${record.employeeName}_实习报酬申领表_${record.projectPeriod}.xlsx`
|
|
XLSX.writeFile(workbook, filename)
|
|
}
|
|
|
|
// 辅助函数
|
|
function getEmployeeTypeText(type: string) {
|
|
const typeMap = {
|
|
intern: '实习生',
|
|
fulltime: '正式员工',
|
|
parttime: '兼职员工',
|
|
}
|
|
return typeMap[type as keyof typeof typeMap] || type
|
|
}
|
|
|
|
function getStatusText(status: string) {
|
|
const statusMap = {
|
|
draft: '草稿',
|
|
pending: '待审批',
|
|
approved: '已批准',
|
|
rejected: '已拒绝',
|
|
paid: '已发放',
|
|
}
|
|
return statusMap[status as keyof typeof statusMap] || status
|
|
}
|
|
|
|
function getUnitText(unit: string) {
|
|
const unitMap = {
|
|
day: '天',
|
|
project: '项目',
|
|
fixed: '固定',
|
|
}
|
|
return unitMap[unit as keyof typeof unitMap] || unit
|
|
}
|