Feature: 为多层纸带计算添加Excel导出功能
This commit is contained in:
@ -135,7 +135,7 @@
|
||||
<tr>
|
||||
<th>{{ $t('layer') }}</th>
|
||||
<th>{{ $t('paperGrammage') }}</th>
|
||||
<th>{{ $t('cumulative Thickness') }}</th>
|
||||
<th>{{ $t('cumulativeThickness') }}</th>
|
||||
<th>{{ $t('angle') }}</th>
|
||||
<th>{{ $t('paperWidth') }}</th>
|
||||
</tr>
|
||||
@ -158,10 +158,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import * as EXCEL from 'exceljs'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { createParam, type Param } from '@/types/param'
|
||||
import { degreesToRadians, radiansToDegrees } from '@/utils/angle'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
interface LayerRecord {
|
||||
layer: number
|
||||
grammage: Param
|
||||
@ -201,9 +205,259 @@
|
||||
recordList.value = []
|
||||
}
|
||||
|
||||
const saveParams = () => {
|
||||
// TODO 计算结果导出为Excel
|
||||
console.log('SAVE')
|
||||
const saveParams = async () => {
|
||||
if (recordList.value.length === 0) {
|
||||
console.warn('No records to save.')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const filename = `${t('multiLayerPaperTapeWidthAngleCalculate')}-${new Date().toISOString().slice(0, 10)}.xlsx`.replace(/\s+/g, '')
|
||||
|
||||
// 创建工作簿和工作表
|
||||
const workbook = new EXCEL.Workbook()
|
||||
const worksheet = workbook.addWorksheet(t('results'))
|
||||
|
||||
// 创建样式
|
||||
// headerStyle: 表头样式,根据Excel内建样式Calculation设置
|
||||
const headerStyle: EXCEL.Style = {
|
||||
fill: {
|
||||
type: 'pattern',
|
||||
pattern: 'solid',
|
||||
fgColor: { argb: 'FFF2F2F2' },
|
||||
},
|
||||
font: {
|
||||
name: 'Arial',
|
||||
size: 11,
|
||||
bold: true,
|
||||
color: { argb: 'FFFA7D00' },
|
||||
},
|
||||
alignment: {
|
||||
horizontal: 'center',
|
||||
vertical: 'middle',
|
||||
},
|
||||
numFmt: 'General',
|
||||
protection: {},
|
||||
border: {
|
||||
top: { style: 'thin', color: { argb: 'FF7F7F7F' } },
|
||||
bottom: { style: 'thin', color: { argb: 'FF7F7F7F' } },
|
||||
left: { style: 'thin', color: { argb: 'FF7F7F7F' } },
|
||||
right: { style: 'thin', color: { argb: 'FF7F7F7F' } },
|
||||
},
|
||||
}
|
||||
// parameterStyle: 参数样式,使用默认样式
|
||||
const parameterStyle: EXCEL.Style = {
|
||||
font: {
|
||||
name: 'Arial',
|
||||
size: 12,
|
||||
color: { argb: 'FF000000' },
|
||||
},
|
||||
alignment: {
|
||||
horizontal: 'center',
|
||||
vertical: 'middle',
|
||||
},
|
||||
numFmt: 'General',
|
||||
protection: {},
|
||||
border: {},
|
||||
fill: {
|
||||
type: 'pattern',
|
||||
pattern: 'none',
|
||||
},
|
||||
}
|
||||
|
||||
// valueStyle: 数值样式,使用默认样式,保留2位小数
|
||||
const valueStyle: EXCEL.Style = {
|
||||
font: {
|
||||
name: 'Arial',
|
||||
size: 12,
|
||||
color: { argb: 'FF000000' },
|
||||
},
|
||||
alignment: {
|
||||
horizontal: 'center',
|
||||
vertical: 'middle',
|
||||
},
|
||||
numFmt: '0.00',
|
||||
protection: {},
|
||||
border: {},
|
||||
fill: {
|
||||
type: 'pattern',
|
||||
pattern: 'none',
|
||||
},
|
||||
}
|
||||
// conditionStyle: 条件样式,使用默认样式
|
||||
const conditionStyle: EXCEL.Style = {
|
||||
font: {
|
||||
name: 'Arial',
|
||||
size: 16,
|
||||
bold: true,
|
||||
color: { argb: 'FF444444' },
|
||||
},
|
||||
alignment: {
|
||||
horizontal: 'center',
|
||||
vertical: 'middle',
|
||||
},
|
||||
numFmt: 'General',
|
||||
protection: {},
|
||||
border: {
|
||||
top: { style: 'thin', color: { argb: 'FF7F7F7F' } },
|
||||
bottom: { style: 'thin', color: { argb: 'FF7F7F7F' } },
|
||||
left: { style: 'thin', color: { argb: 'FF7F7F7F' } },
|
||||
right: { style: 'thin', color: { argb: 'FF7F7F7F' } },
|
||||
},
|
||||
fill: {
|
||||
type: 'pattern',
|
||||
pattern: 'none',
|
||||
},
|
||||
}
|
||||
|
||||
// 添加Parameters表头
|
||||
worksheet.getCell('A1').value = t('parameters')
|
||||
worksheet.getCell('A1').style = headerStyle
|
||||
worksheet.mergeCells('A1:D1')
|
||||
|
||||
worksheet.getCell('A2').value = `${t('paperCoreDiameter')} (${paperCoreDiameter.value.unit})`
|
||||
worksheet.getCell('A2').style = parameterStyle
|
||||
worksheet.mergeCells('A2:B2')
|
||||
|
||||
worksheet.getCell('C2').value = `${t('bottomPaperWidth')} (${bottomPaperWidth.value.unit})`
|
||||
worksheet.getCell('C2').style = parameterStyle
|
||||
worksheet.mergeCells('C2:D2')
|
||||
|
||||
// 添加Parameters数据
|
||||
worksheet.getCell('A3').value = paperCoreDiameter.value.value
|
||||
worksheet.getCell('A3').style = valueStyle
|
||||
worksheet.mergeCells('A3:B3')
|
||||
|
||||
worksheet.getCell('C3').value = bottomPaperWidth.value.value
|
||||
worksheet.getCell('C3').style = valueStyle
|
||||
worksheet.mergeCells('C3:D3')
|
||||
|
||||
// 添加Results表头
|
||||
worksheet.getCell('A7').value = t('results')
|
||||
worksheet.getCell('A7').style = headerStyle
|
||||
worksheet.mergeCells('A7:E7')
|
||||
|
||||
// 添加Results表头列名
|
||||
worksheet.getCell('A8').value = t('layer')
|
||||
worksheet.getCell('A8').style = parameterStyle
|
||||
worksheet.getCell('B8').value = t('paperGrammage')
|
||||
worksheet.getCell('B8').style = parameterStyle
|
||||
worksheet.getCell('C8').value = t('cumulativeThickness')
|
||||
worksheet.getCell('C8').style = parameterStyle
|
||||
worksheet.getCell('D8').value = t('angle')
|
||||
worksheet.getCell('D8').style = parameterStyle
|
||||
worksheet.getCell('E8').value = t('paperWidth')
|
||||
worksheet.getCell('E8').style = parameterStyle
|
||||
|
||||
// 添加Results数据
|
||||
for (const [index, record] of recordList.value.entries()) {
|
||||
worksheet.getCell(`A${index + 9}`).value = record.layer
|
||||
worksheet.getCell(`A${index + 9}`).style = parameterStyle
|
||||
worksheet.getCell(`B${index + 9}`).value = record.grammage.value
|
||||
worksheet.getCell(`B${index + 9}`).style = valueStyle
|
||||
worksheet.getCell(`C${index + 9}`).value = record.cumulativeThickness.value
|
||||
worksheet.getCell(`C${index + 9}`).style = valueStyle
|
||||
worksheet.getCell(`D${index + 9}`).value = record.angle.value
|
||||
worksheet.getCell(`D${index + 9}`).style = valueStyle
|
||||
worksheet.getCell(`E${index + 9}`).value = record.paperWidth.value
|
||||
worksheet.getCell(`E${index + 9}`).style = valueStyle
|
||||
}
|
||||
|
||||
// 添加Reference表头
|
||||
worksheet.getCell('F1').value = t('reference')
|
||||
worksheet.getCell('F1').style = headerStyle
|
||||
worksheet.mergeCells('F1:H1')
|
||||
worksheet.getCell('F2').value = t('angle')
|
||||
worksheet.getCell('F2').style = parameterStyle
|
||||
worksheet.mergeCells('F2:F3')
|
||||
worksheet.getCell('G2').value = t('minimum')
|
||||
worksheet.getCell('G2').style = parameterStyle
|
||||
worksheet.getCell('H2').value = t('maximum')
|
||||
worksheet.getCell('H2').style = parameterStyle
|
||||
|
||||
// 添加Reference数据
|
||||
worksheet.getCell('G3').value = 10
|
||||
worksheet.getCell('G3').style = parameterStyle
|
||||
worksheet.getCell('H3').value = 45
|
||||
worksheet.getCell('H3').style = parameterStyle
|
||||
worksheet.getCell('F4').value = t('calculatedValue')
|
||||
worksheet.getCell('F4').style = parameterStyle
|
||||
// 所有记录中最小角度
|
||||
worksheet.getCell('G4').value = {
|
||||
formula: `MIN(D9: D${recordList.value.length + 8})`,
|
||||
}
|
||||
worksheet.getCell('G4').style = valueStyle
|
||||
// 所有记录中最大角度
|
||||
worksheet.getCell('H4').value = {
|
||||
formula: `MAX(D9: D${recordList.value.length + 8})`,
|
||||
}
|
||||
worksheet.getCell('H4').style = valueStyle
|
||||
|
||||
// 计算结果: 最小角度>10 且 最大角度<45
|
||||
worksheet.getCell('F5').value = {
|
||||
formula: `IF(AND(G4>10, H4<45), "${t('fit')}", "${t('notFit')}")`,
|
||||
}
|
||||
worksheet.getCell('F5').style = conditionStyle
|
||||
worksheet.addConditionalFormatting({
|
||||
ref: 'F5',
|
||||
rules: [
|
||||
{
|
||||
type: 'expression',
|
||||
formulae: ['OR(G4<=10, H4>=45)'],
|
||||
style: {
|
||||
fill: { type: 'pattern', pattern: 'solid', bgColor: { argb: 'FFFF7F7F' } }, // 红色背景
|
||||
},
|
||||
priority: 1,
|
||||
},
|
||||
{
|
||||
type: 'expression',
|
||||
formulae: ['AND(G4>10, H4<45)'],
|
||||
style: {
|
||||
fill: { type: 'pattern', pattern: 'solid', bgColor: { argb: 'FFA6E65C' } }, // 绿色背景
|
||||
},
|
||||
priority: 1,
|
||||
},
|
||||
],
|
||||
})
|
||||
worksheet.mergeCells('F5:H6')
|
||||
|
||||
// 自动调整列宽
|
||||
for (const [index, column] of worksheet.columns.entries()) {
|
||||
let maxLength = 0
|
||||
|
||||
const columnLetter = String.fromCodePoint(65 + index)
|
||||
|
||||
if (column && typeof column.eachCell === 'function') {
|
||||
column.eachCell({ includeEmpty: true }, cell => {
|
||||
const cellValue = cell.value ? String(cell.value) : ''
|
||||
if (cellValue.length > maxLength) {
|
||||
maxLength = cellValue.length
|
||||
}
|
||||
})
|
||||
|
||||
// 设置列宽
|
||||
column.width = maxLength + 4 // 增加一些额外空间
|
||||
}
|
||||
}
|
||||
|
||||
// 导出为文件
|
||||
const buffer = await workbook.xlsx.writeBuffer()
|
||||
const blob = new Blob([buffer], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
|
||||
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = filename
|
||||
document.body.append(link)
|
||||
link.click()
|
||||
link.remove()
|
||||
window.URL.revokeObjectURL(url)
|
||||
|
||||
console.log('Saved as Excel file:', filename)
|
||||
} catch (error) {
|
||||
console.error('Error saving parameters:', error)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const addLayer = () => {
|
||||
|
||||
Reference in New Issue
Block a user