Industrial-image-management.../src/views/salary-management/utils/export.ts

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
}