import { cloneDeep, isNumber } from 'lodash' import ExcelJS from 'exceljs' import { exportWordDocx, getBase64Sync } from './exportWord' import { baseURL } from './http' import { resJiLianFu } from './history' import { arrangeImages, calcTablePages, getExcelColumnLetter, ITEMPLATE, numberToChinese, removeHtmlTags } from './exportWordUtils' import { myTableTransferSize } from '@/components/MyTable' import dayjs from 'dayjs' import { D7CEHCK_COLLECTION_RESULT_OPTIONS } from '@/pages/D_storeManage/D7check/constants' import { exportTempExcel, getImageBase64Extension } from './exportExcelUtils' import { selectObj } from './select' import { MEDIA_TYPES } from '@/pages/C_goodsManage/C21wealth/constants' export enum EXPORT_WORD_ENUM { /** 借用藏品点交凭证 */ BORROW = 1, /** 藏品馆内提退凭单 */ HALL_PUT_BACK = 2, /** 分库藏品提退出入库记录单 */ SUB_PUT_BACK = 3, /** 分库藏品入库记录单 */ SUB_PUT_IN = 4, /** 入馆凭证 */ VOUCHER = 5, /** 藏品图片及相关数字化信息使用申请单 */ FORM_FOR_DIGITAL = 6, /** 藏品档案 */ COLLECTION_ARCHIVES = 7, /** 拟征集藏品清单 */ COLLECTION_LIST = 8, /** 文物鉴定书 */ CERTIFICATE = 9, /** 入藏凭证 */ STORAGE_VOUCHER = 10, /** 藏品卡片 */ COLLECTION_CARD = 11, /** 藏品注销凭证 */ CANCEL_VOUCHER = 12, /** 藏品移库 */ COLLECTION_RELOCATION = 13, /** 藏品盘点记录单 */ COLLECTION_INVENTORY = 14, /** 馆内人员进库申请单 */ INSIDER_FORM = 15, /** 文物库房外来人员出入库审批表 */ OUTSIDER_FORM = 16, /** 文物修复单 */ RELIC_REPAIR_LIST = 17, /** 事故处理凭证 */ ACCIDENT_HANDLING_CERTIFICATE = 18, /** 藏品现状登记 */ COLLECTION_CURRENT_STATUS = 19, /** 馆内展览借用藏品登记台账 */ REGISTER_LEDGER = 20, /** 藏品总账 */ COLLECTION_LEDGER = 21, /** 藏品提退出入库登记流水账 */ COLLECTION_LOG = 22 } export const EXPORT_TEMPLATE_MAP: Record = { [EXPORT_WORD_ENUM.COLLECTION_LOG]: { fileName: '藏品提退出入库登记流水账', options: { sheetHeader: [ '序号', '藏品总登记号', '分类号', '点交凭证单号', '藏品名称', '计件数量', '文物现状', ['出库记录', '提用人', '点交人', '出库时间'], ['退库记录', '退还人', '点收人', '退库时间'], '备注' ], sheetFilter: [ 'index', 'num', 'numType', 'orderNum', 'name', 'pcs', 'preserveState', 'ckUser1', 'ckUser2', 'ckDate', 'tkUser1', 'tkUser2', 'tkDate', 'snapRtf' ], columnWidths: [5, 14, 8, 10, 15, 10, 10, 10, 10, 14, 10, 10, 14, 10] } }, [EXPORT_WORD_ENUM.COLLECTION_LEDGER]: { fileName: '藏品总账', options: { sheetHeader: [ ['登记日期', '年', '月', '日'], '藏品总登记号', '分类号', '藏品名称', '时代', ['计件', '单位', '件数'], '尺寸、重量', '质地', '完残情况', '来源', '采集地点', ['入馆日期', '年', '月', '日'], '入馆凭证号', '注销凭证号', '级别', '备注' ], sheetFilter: [ 'year', 'month', 'day', 'num', 'numType', 'name', 'dictAge', 'pcsUnit', '_pcs', 'size', 'dictTexture', 'dictTorn', 'source', '', 'year2', 'month2', 'day2', 'inHouseNum', '', 'dictLevel', 'rtf' ], columnWidths: [5, 5, 5, 10, 5, 10, 10, 5, 5, 10, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10] } }, [EXPORT_WORD_ENUM.COLLECTION_CURRENT_STATUS]: { fileName: '藏品现状登记', templateName: '16.docx' }, [EXPORT_WORD_ENUM.ACCIDENT_HANDLING_CERTIFICATE]: { fileName: '藏品事故处理凭证', templateName: '15.docx' }, [EXPORT_WORD_ENUM.RELIC_REPAIR_LIST]: { fileName: '义乌市博物馆文物修复单', templateName: '14.docx', // 每个字段单行最大字符数 perLine: { name: 9, dictLevel: 24, txt2: 4 }, row: { // 首页最大行数 maxRowFirstPage: 3, // 尾页最大行数 maxRowLastPage: 6, // 每页最大行数 maxRowPage: 8, // 首页单行最大字符行数 maxFirstCharLine: 20, // 尾页单行最大字符行数 maxLastCharLine: 18, // 每页最大字符行数 maxCharLine: 26, // 表格每行最小字符行数 minRowCharLine: 3 } }, [EXPORT_WORD_ENUM.OUTSIDER_FORM]: { fileName: '文物库房外来人员出入库审批表', templateName: '13.docx' }, [EXPORT_WORD_ENUM.INSIDER_FORM]: { fileName: '馆内人员进库申请单', templateName: '12.docx' }, [EXPORT_WORD_ENUM.COLLECTION_INVENTORY]: { fileName: '义乌市博物馆分库藏品盘点记录单', templateName: '11.docx' }, [EXPORT_WORD_ENUM.COLLECTION_RELOCATION]: { fileName: '义乌博物馆分库藏品移库记录单', templateName: '10.docx' }, [EXPORT_WORD_ENUM.CANCEL_VOUCHER]: { fileName: '馆藏品注销凭证', options: { sheetHeader: [ '藏品总账号', '藏品分类号', '名称', '年代', '数量', '尺寸、重量', '完残情况', '登记账页码数', '注销后去向', '注销原因', '备注' ], sheetFilter: [ 'num', 'numType', 'name', 'dictAge', 'pcs', 'size', 'torn', '', 'txt1', 'txt2', 'txt3' ], columnWidths: [10, 10, 10, 15, 10, 15, 15, 12, 15, 15, 15] } }, [EXPORT_WORD_ENUM.REGISTER_LEDGER]: { fileName: '义乌市博物馆馆内展览借用藏品登记台账', options: { sheetHeader: [ '序号', '年度', '借用部门', '展览名称', '借用文物 实际数量(合计)', ['借用藏品基本情况', '藏品总登记号', '藏品名称'], '出借时间', ['出借经手人', '甲方', '乙方'], '藏品提用审批单号', '馆内提退凭证号', '预计归还日期', '归还时间', ['归还经手人', '甲方', '乙方'], '记录人', '备注' ], sheetFilter: [ 'index', 'year', 'sonUnit', 'typeName', 'pcs', 'num', 'name', 'lendDate', 'lenderA', 'lenderb', 'sonNum', 'sonNum2', 'expectedReturnDate', 'returnDate', 'handlerA', 'handlerB', 'recorder', 'remark' ], columnWidths: [5, 5, 12, 15, 12, 10, 15, 12, 10, 10, 15, 15, 15, 15, 10, 10, 10, 15] } }, [EXPORT_WORD_ENUM.CERTIFICATE]: { fileName: '义乌市博物馆馆藏文物鉴定书', options: { sheetHeader: [ '编号', '总登记号', '分类号', '文物名称', '图片', '数量', '质地', '时代', '尺寸(cm)或重量(g)', '现状概述', '鉴定等级', '备注' ], sheetFilter: [ 'index', 'num', 'numType', 'name', 'thumb', 'pcs', 'dictTexture', 'dictAge', 'size', 'dictTorn', 'dictLevel', 'intro' ], columnWidths: [5, 12, 7, 15, 10, 7, 15, 35, 20, 10, 10, 20] } }, [EXPORT_WORD_ENUM.COLLECTION_LIST]: { fileName: '拟征集藏品清单', options: { sheetHeader: ['序号', '藏品名称', '初定年代', '报价(万元)', '原持有人', '征集方式'], sheetFilter: ['index', 'name', 'dictAgeFirst', 'offer', 'holder', 'source'], columnWidths: [5, 15, 40, 15, 10, 10] } }, [EXPORT_WORD_ENUM.BORROW]: { fileName: '义乌市博物馆借用藏品点交凭证', templateName: '1.docx', // 每个字段单行最大字符数 perLine: { num: 9, name: 14, rtf: 11, dictAge: 6, dictTexture3: 6 }, row: { // 首页最大行数 maxRowFirstPage: 1, // 尾页最大行数 maxRowLastPage: 2, // 每页最大行数 maxRowPage: 5, // 首页单行最大字符行数 maxFirstCharLine: 9, // 尾页单行最大字符行数 maxLastCharLine: 11, // 每页最大字符行数 maxCharLine: 27, // 表格每行最小字符行数 minRowCharLine: 4 } }, [EXPORT_WORD_ENUM.HALL_PUT_BACK]: { fileName: '义乌市博物馆藏品馆内提退凭单', templateName: '2.docx', // 每个字段单行最大字符数 perLine: { num: 9, name: 24, pcsUnit: 4, rtf: 6 }, row: { // 首页最大行数 maxRowFirstPage: 3, // 尾页最大行数 maxRowLastPage: 6, // 每页最大行数 maxRowPage: 8, // 首页单行最大字符行数 maxFirstCharLine: 20, // 尾页单行最大字符行数 maxLastCharLine: 18, // 每页最大字符行数 maxCharLine: 26, // 表格每行最小字符行数 minRowCharLine: 3 } }, [EXPORT_WORD_ENUM.SUB_PUT_BACK]: { fileName: '义乌市博物馆分库藏品提退出入库记录单', templateName: '3.docx' }, [EXPORT_WORD_ENUM.SUB_PUT_IN]: { fileName: '义乌市博物馆分库藏品入库记录单', templateName: '4.docx' }, [EXPORT_WORD_ENUM.VOUCHER]: { fileName: '义乌市博物馆入馆凭证', templateName: '5.docx' }, [EXPORT_WORD_ENUM.FORM_FOR_DIGITAL]: { fileName: '义乌市博物馆藏品图片及相关数字化信息使用申请单', templateName: '6.docx' }, [EXPORT_WORD_ENUM.COLLECTION_ARCHIVES]: { fileName: '藏品档案样本电子版', templateName: '7.docx' }, [EXPORT_WORD_ENUM.STORAGE_VOUCHER]: { fileName: '义乌市博物馆入藏凭证', templateName: '8.docx' }, [EXPORT_WORD_ENUM.COLLECTION_CARD]: { fileName: '藏品卡片', templateName: '9.docx' } } /** * 根据业务类型导出数据 */ export const exportWordHandler = async (type: EXPORT_WORD_ENUM, data: Record) => { let temp = cloneDeep(data) let page = 1 let excelHandler: (worksheet: ExcelJS.Worksheet) => void = () => {} const date = dayjs() const item = EXPORT_TEMPLATE_MAP[type] temp.sizeUnit && (temp.sizeUnit = resJiLianFu(temp.sizeUnit)) temp.qualityUnit && (temp.qualityUnit = resJiLianFu(temp.qualityUnit)) temp.dictAge && (temp.dictAge = resJiLianFu(temp.dictAge)) temp.pcsUnit && (temp.pcsUnit = resJiLianFu(temp.pcsUnit)) temp.goods = (Array.isArray(temp.snaps) && temp.snaps.length ? temp.snaps.map((i: any) => JSON.parse(i.snap || '')) : temp.collects) ?? [] if (temp.goods.length) { for (let i = 0; i < temp.goods.length; i++) { const good = temp.goods[i] good.index = i + 1 good.rtf && (good.rtf = removeHtmlTags(JSON.parse(good.rtf).txtArr[0].txt)) // excel 需要判断表格中是否需要图片 if (!item.templateName ? item.options?.sheetFilter.includes('thumb') : good.thumb) { try { // good.thumb = await getBase64Sync( // 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100' // ) good.thumb = await getBase64Sync(baseURL + good.thumb) } catch (err) { console.log('thumb conversion to base64 faild:', err) good.thumb = '' } } good.dictAge && (good.dictAge = resJiLianFu(good.dictAge)) good.pcsUnit && (good.pcsUnit = resJiLianFu(good.pcsUnit)) if (good.pcs) { good._pcs = good.pcs good.pcs = good.pcs + good.pcsUnit } good.accountType && (good.accountType = selectObj['入藏去向'].find(i => i.value === good.accountType)?.label) good.dictTexture3 && (good.dictTexture = resJiLianFu(good.dictTexture3)) good.dictTorn && (good.dictTorn = resJiLianFu(good.dictTorn)) good.source && (good.source = resJiLianFu(good.source)) good.dictAgeFirst && (good.dictAgeFirst = resJiLianFu(good.dictAgeFirst)) good.qualityUnit && (good.qualityUnit = resJiLianFu(good.qualityUnit)) if (good.sizeUnit || good.quality) { const arr: string[] = [] if (good.sizeUnit) arr.push(myTableTransferSize(good)) if (good.quality) arr.push('重' + good.quality + good.qualityUnit) good.size = arr.join('、') } } } else { temp.goods = [] } if (item.perLine) { // @ts-ignore page = calcTablePages(temp.goods, item) } // 处理业务数据 switch (type) { case EXPORT_WORD_ENUM.BORROW: temp = { ...temp, group: numberToChinese(temp.goods.length), num: numberToChinese(temp.goods.reduce((sum: number, i: any) => sum + (i._pcs || 0), 0)), page: numberToChinese(page), borrowDate: dayjs(temp.createTime).format('YYYY年MM月DD日') } break case EXPORT_WORD_ENUM.HALL_PUT_BACK: temp = { ...temp, year: date.format('YYYY'), group: numberToChinese(temp.goods.length), page: numberToChinese(page) } break case EXPORT_WORD_ENUM.SUB_PUT_BACK: temp = { ...temp, year: date.format('YYYY'), month: date.format('MM'), day: date.format('DD') } break case EXPORT_WORD_ENUM.COLLECTION_INVENTORY: temp = { ...temp, sonNum2: dayjs(temp.date).format('YYYY') + temp.num } temp.goods.forEach((i: any) => { i.checker = i.cusForm[`${i.id}-checker`] i.remark = i.cusForm[`${i.id}-remark`] i.cusForm[`${i.id}-statusCheck`] && (i.statusCheck = D7CEHCK_COLLECTION_RESULT_OPTIONS.find( ii => ii.value === i.cusForm[`${i.id}-statusCheck`] )?.label) }) break case EXPORT_WORD_ENUM.VOUCHER: case EXPORT_WORD_ENUM.STORAGE_VOUCHER: const _date = dayjs(temp.date) temp = { ...temp, year: _date.format('YYYY'), month: _date.format('MM'), day: _date.format('DD'), group: numberToChinese(temp.goods.length), page: numberToChinese(page) } break case EXPORT_WORD_ENUM.FORM_FOR_DIGITAL: const __date = dayjs(temp.createTime) temp = { ...temp, effect: resJiLianFu(temp.effect), sonTypeName: MEDIA_TYPES.filter(media => temp.sonTypeName.split(',').includes(media.value)) .map(media => media.label) .join(','), year2: date.format('YYYY'), year: __date.format('YYYY'), month: __date.format('MM'), day: __date.format('DD') } break case EXPORT_WORD_ENUM.SUB_PUT_IN: temp = { ...temp, sonSource: resJiLianFu(temp.sonSource), sonNum2: dayjs(temp.date).format('YYYY') + temp.num, date: dayjs(temp.date).format('YYYY年MM月DD日') } break case EXPORT_WORD_ENUM.COLLECTION_RELOCATION: console.log(temp.goods) temp = { ...temp, year: date.format('YYYY'), month: date.format('MM'), day: date.format('DD'), date: dayjs(temp.date).format('YYYY年MM月DD日') } break case EXPORT_WORD_ENUM.ACCIDENT_HANDLING_CERTIFICATE: temp = { ...temp, year: date.format('YYYY'), rtf: temp.rtf ? removeHtmlTags(JSON.parse(temp.rtf).txtArr[0].txt) : '', authInfoRtf: removeHtmlTags(JSON.parse(temp.authInfoRtf).txtArr[0].txt), authResultRtf: removeHtmlTags(JSON.parse(temp.authResultRtf).txtArr[0].txt) } break case EXPORT_WORD_ENUM.COLLECTION_ARCHIVES: case EXPORT_WORD_ENUM.COLLECTION_CARD: console.log(temp) temp = { ...temp, year: date.format('YYYY'), month: date.format('MM'), day: date.format('DD'), size: myTableTransferSize(temp), quality: temp?.qualityDictScope ? resJiLianFu(temp.qualityDictScope) : '', deptName: (temp.records || []).length ? temp.records[0].deptName : '', recordDate: (temp.records || []).length ? temp.records[0].createTime : '', records: (temp.records || []).map( (item: any) => `[${temp.dictLevel}],[${item.createTime}][${item.deptName}][${item.creatorName}]意见。` ) } if (type === EXPORT_WORD_ENUM.COLLECTION_ARCHIVES) { temp.imagePages = await arrangeImages(temp.imagePages) } break case EXPORT_WORD_ENUM.OUTSIDER_FORM: const memberss = JSON.parse(temp.memberIds) temp = { ...temp, time: dayjs(temp.date).format('HH:mm:ss'), date: dayjs(temp.date).format('YYYY-MM-DD'), members: memberss.map((i: any) => i.name), companys: memberss.map((i: any) => i.remark || '空'), idCards: memberss.map((i: any) => i.papers || '空'), phones: memberss.map((i: any) => i.phone || '空') } break case EXPORT_WORD_ENUM.RELIC_REPAIR_LIST: case EXPORT_WORD_ENUM.COLLECTION_CURRENT_STATUS: const ___date = dayjs(temp.date) temp = { ...temp, year: ___date.format('YYYY'), page, rtf: removeHtmlTags(JSON.parse(temp.rtf).txtArr[0].txt) } break case EXPORT_WORD_ENUM.COLLECTION_LIST: temp.goods.push({ index: '合计', name: temp.goods.length, dictAgeFirst: '合计', offer: temp.goods.reduce((sum: number, cur: any) => sum + Number(cur.offer), 0) }) excelHandler = worksheet => { worksheet.insertRow(1, ['拟征集藏品清单']) worksheet.mergeCells('A1:F1') const mergedCell = worksheet.getCell('A1') mergedCell.style = { fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'cce8cf' } }, font: { name: '黑体', size: 18 } } const borderStyle: ExcelJS.Border = { style: 'thin', color: { argb: 'FF000000' } } for (let row = 2; row <= temp.goods.length + 2; row++) { for (let col = 1; col <= 6; col++) { const cell = worksheet.getCell(row, col) cell.border = { top: borderStyle, left: borderStyle, bottom: borderStyle, right: borderStyle } } } worksheet.eachRow(row => { row.eachCell(cell => { cell.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true } }) }) } break case EXPORT_WORD_ENUM.CERTIFICATE: const resultText = Object.entries( // @ts-ignore temp.goods.reduce((acc, { dictLevel }) => { acc[dictLevel] = (acc[dictLevel] || 0) + 1 return acc }, {}) ) // @ts-ignore .filter(([_, count]) => count > 0) .map( ([level, count]) => `${level === '一般' ? level + '珍贵文物' : level + '文物'}${count}件/组;` ) .join('\n') temp.goods.push({ index: '鉴\n定\n人\n员', num: temp.authUser, thumb: '鉴\n定\n单\n位', pcs: temp.authUnit, dictAge: '核\n准\n单\n位', dictTorn: '说\n\n明', size: temp.confirmUnit, dictLevel: `鉴定日期:${temp.date}\n鉴定总数${temp.goods.length}件/组,其中:\n${resultText}` }) excelHandler = worksheet => { const lastIndex = temp.goods.length + 2 worksheet.insertRow(1, ['单位:义乌市博物馆']) worksheet.mergeCells('A1:H1') worksheet.mergeCells('I1:L1') worksheet.mergeCells(`B${lastIndex}:D${lastIndex}`) worksheet.mergeCells(`F${lastIndex}:G${lastIndex}`) worksheet.mergeCells(`K${lastIndex}:L${lastIndex}`) worksheet.eachRow(row => { const col5 = row.getCell(5) if (isNumber(col5.value)) { worksheet.addImage(col5.value, `${col5.address}:${col5.address}`) } row.eachCell(cell => { cell.style = { font: { name: '宋体', size: 10 } } cell.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true } }) }) const titleCell = worksheet.getCell('A1') const dateCell = worksheet.getCell('I1') const lastCell = worksheet.getRow(lastIndex) const borderStyle: ExcelJS.Border = { style: 'thin', color: { argb: 'FF000000' } } lastCell.height = 80 titleCell.style = { fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'cce8cf' } }, font: { size: 16 }, alignment: { horizontal: 'left', vertical: 'middle' } } dateCell.value = '日期:' + temp.createTime.split(' ')[0] dateCell.style = { fill: { type: 'pattern', pattern: 'solid', fgColor: { argb: 'cce8cf' } }, font: { size: 16 }, alignment: { horizontal: 'right', vertical: 'middle' } } for (let row = 1; row <= lastIndex; row++) { for (let col = 1; col <= 12; col++) { const cell = worksheet.getCell(row, col) cell.border = { top: borderStyle, left: borderStyle, bottom: borderStyle, right: borderStyle } } } } break case EXPORT_WORD_ENUM.CANCEL_VOUCHER: temp.goods.push({ num: '法定代表人:', dictAge: '保管部负责人:', torn: '保管员:', txt1: '珍贵文物注销审批文号:' }) excelHandler = worksheet => { const lastIndex = temp.goods.length + 4 const borderStyle: ExcelJS.Border = { style: 'thin', color: { argb: 'FF000000' } } worksheet.eachRow(row => { row.eachCell(cell => { cell.style = { font: { name: '宋体', size: 10 } } cell.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true } }) }) worksheet.insertRow(1, []) worksheet.mergeCells('A1:K1') worksheet.getCell('A1').value = { richText: [ { font: { size: 20, name: '黑体' }, text: '馆藏品注销凭证 ' }, { font: { size: 11 }, text: '(编号: ) ' } ] } worksheet.getRow(1).height = 60 worksheet.getCell('A1').style = { alignment: { horizontal: 'center', vertical: 'middle' } } worksheet.insertRow(2, [date.format('YYYY年MM月DD日')]) worksheet.mergeCells('A2:K2') worksheet.getRow(2).height = 30 worksheet.getCell('A2').style = { font: { size: 11, name: '仿宋_GB2312' }, alignment: { horizontal: 'right', vertical: 'middle' } } worksheet.insertRow(3, [ `现将藏品_${temp.goods.length}_件注销,清单开列如下,本凭证连同附页全份共______页(含附件)` ]) worksheet.mergeCells('A3:K3') worksheet.getRow(3).height = 30 worksheet.getCell('A3').style = { font: { size: 11, name: '仿宋_GB2312' }, alignment: { horizontal: 'center', vertical: 'middle' } } worksheet.mergeCells(`A${lastIndex}:C${lastIndex}`) worksheet.mergeCells(`D${lastIndex}:F${lastIndex}`) worksheet.mergeCells(`G${lastIndex}:H${lastIndex}`) worksheet.mergeCells(`I${lastIndex}:K${lastIndex}`) for (let row = 1; row <= lastIndex; row++) { for (let col = 1; col <= 11; col++) { const cell = worksheet.getCell(row, col) cell.border = { top: borderStyle, left: borderStyle, bottom: borderStyle, right: borderStyle } } } } break case EXPORT_WORD_ENUM.REGISTER_LEDGER: const totalPcs = temp.goods.reduce((sum: number, i: any) => sum + (i._pcs || 0), 0) temp.goods.forEach((i: any) => { i.year = date.format('YYYY') + '年度' i.sonUnit = temp.sonUnit i.typeName = temp.typeName i.lendDate = dayjs(i.cusForm[`${i.id}-lendDate`]).format('YYYY年MM月DD日') i.lenderA = i.cusForm[`${i.id}-lenderA`] i.lenderb = i.cusForm[`${i.id}-lenderb`] i.sonNum = temp.sonNum i.sonNum2 = temp.sonNum2 i.handlerA = i.cusForm[`${i.id}-handlerA`] i.handlerB = i.cusForm[`${i.id}-handlerB`] i.recorder = i.cusForm[`${i.id}-recorder`] i.remark = i.cusForm[`${i.id}-remark`] i.pcs = `${i.pcs},计${totalPcs}件` const expectedReturnDate = i.cusForm[`${i.id}-expectedReturnDate`] expectedReturnDate && (i.expectedReturnDate = dayjs(expectedReturnDate).format('YYYY年MM月DD日')) const returnDate = i.cusForm[`${i.id}-returnDate`] returnDate && (i.returnDate = dayjs(returnDate).format('YYYY年MM月DD日')) }) excelHandler = worksheet => { const borderStyle: ExcelJS.Border = { style: 'thin', color: { argb: 'FF000000' } } for (let row = 1; row <= temp.goods.length + 2; row++) { for (let col = 1; col <= 18; col++) { const cell = worksheet.getCell(row, col) cell.border = { top: borderStyle, left: borderStyle, bottom: borderStyle, right: borderStyle } } } worksheet.eachRow(row => { row.eachCell(cell => { cell.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true } }) }) } break case EXPORT_WORD_ENUM.COLLECTION_LOG: excelHandler = worksheet => { const borderStyle: ExcelJS.Border = { style: 'thin', color: { argb: 'FF000000' } } for (let row = 1; row <= temp.goods.length + 2; row++) { for (let col = 1; col <= 14; col++) { const cell = worksheet.getCell(row, col) cell.border = { top: borderStyle, left: borderStyle, bottom: borderStyle, right: borderStyle } } } worksheet.eachRow(row => { row.eachCell(cell => { cell.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true } }) }) } break case EXPORT_WORD_ENUM.COLLECTION_LEDGER: temp.goods.forEach((i: any) => { const createTime = dayjs(i.createTime) const inHouseTime = dayjs(i.createTime) i.year = createTime.format('YYYY') i.month = createTime.format('MM') i.day = createTime.format('DD') i.year2 = inHouseTime.format('YYYY') i.month2 = inHouseTime.format('MM') i.day2 = inHouseTime.format('DD') }) excelHandler = worksheet => { const borderStyle: ExcelJS.Border = { style: 'thin', color: { argb: 'FF000000' } } for (let row = 1; row <= temp.goods.length + 2; row++) { for (let col = 1; col <= 21; col++) { const cell = worksheet.getCell(row, col) cell.border = { top: borderStyle, left: borderStyle, bottom: borderStyle, right: borderStyle } } } worksheet.eachRow(row => { row.eachCell(cell => { cell.alignment = { vertical: 'middle', horizontal: 'center', wrapText: true } }) }) } break } if (!item.templateName) { // 没有templateName则输出 excel exportTempExcel(item.fileName, (worksheet, workbook) => { let mergeHeadNum = 0 let headTemp: string[] = [] let fatherHeadTemp: { title: string position: string[] }[] = [] // 表头需要占据的行数 const headRow = Math.max( ...item.options?.sheetHeader.map((head: string | string[]) => (Array.isArray(head) ? 2 : 1)) ) item.options?.sheetHeader.forEach((head: string | string[], index: number) => { if (Array.isArray(head)) { fatherHeadTemp.push({ title: head.shift() || '', position: [ `${getExcelColumnLetter(index + mergeHeadNum)}1`, `${getExcelColumnLetter(index + head.length - 1 + mergeHeadNum)}1` ] }) headTemp.push(...head) mergeHeadNum += head.length - 1 } else { headTemp.push(head) } }) worksheet.addRow(headTemp) if (fatherHeadTemp.length) { // 存在需要合并的父级表头 worksheet.insertRow(1, []) fatherHeadTemp.forEach(head => { const cell = worksheet.getCell(head.position[0]) cell.value = head.title worksheet.mergeCells(`${head.position[0]}:${head.position[1]}`) }) } if (headRow > 1) { // 合并表头列 headTemp.forEach((head, index) => { const pos = `${getExcelColumnLetter(index)}1:${getExcelColumnLetter(index)}${headRow}` const cell = worksheet.getCell(`${getExcelColumnLetter(index)}1`) if (!cell.isMerged) { worksheet.mergeCells(pos) cell.value = head } }) } temp.goods.forEach((good: Record, goodIndex: number) => { const _temp: string[] = [] item.options?.sheetFilter.forEach((key: string, index: number) => { if (key === 'thumb' && Boolean(good[key])) { const extension = getImageBase64Extension(good[key]) if (extension) { // 插入图片 const imageId = workbook.addImage({ base64: good[key], extension }) good[key] = imageId } } _temp.push(good[key]) }) worksheet.addRow(_temp) }) // 设置宽度 item.options?.columnWidths.forEach((width: number, index: number) => { worksheet.getColumn(index + 1).width = width }) excelHandler(worksheet) }) } else { // 输出 word exportWordDocx(`./templates/${item.templateName}`, temp, item.fileName) } }