feat(style): 新增款式详情导出Excel功能

- 实现导出款式详情为Excel格式的功能,支持HTML内容兼容Excel显示
- 等待打印区域图片加载完成后再导出,避免导出图片显示异常
- 添加导出成功和失败的提示信息反馈
- 在页面按钮区域新增导出Excel按钮,支持用户一键导出
- 更新中文国际化文案,增加导出Excel相关文本
- 调整部分界面按钮布局顺序,提高用户操作便捷性
This commit is contained in:
user 2025-09-22 16:36:48 +08:00
parent 8b4a14015f
commit cb01605bb8
4 changed files with 110 additions and 7 deletions

View File

@ -5,6 +5,7 @@ import { useAlertService } from '@/shared/alert/alert.service';
import axios from 'axios';
import QrcodeVue from 'qrcode.vue';
import printJS from 'print-js';
// @ts-ignore
import html2pdf from 'html2pdf.js';
import buildPaginationQuery from '@/shared/sort/sorts';
@ -208,7 +209,7 @@ export default defineComponent({
printable: 'stylePrintContent',
type: 'html',
css: ['/content/css/bootstrap.min.css', '/content/css/print-form.css'],
documentTitle: `${$t('jewpmsApp.style.detail.title')} - ${style.value.number}`,
documentTitle: `款式详情 - ${style.value.number}`,
style: '@page { size: A4; margin: 15mm; }',
targetStyles: ['*'],
scanStyles: true,
@ -311,6 +312,100 @@ export default defineComponent({
}
};
// 导出ExcelHTML格式
const exportExcel = async () => {
try {
// 确保数据已加载完成
if (loading.value) {
alertService.showInfo($t('global.messages.info.loading'));
return;
}
// 获取打印区域的HTML内容
const printElement = document.getElementById('stylePrintContent');
if (!printElement) {
alertService.showError('打印内容元素不存在');
return;
}
// 等待图片加载完成
await waitForImages(printElement);
// 获取完整的HTML内容
const printContent = printElement.outerHTML;
// 创建Excel兼容的HTML内容
const excelContent = `<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta charset="utf-8">
<title> - ${style.value.number}</title>
<!--[if gte mso 9]>
<xml>
<x:ExcelWorkbook>
<x:ExcelWorksheets>
<x:ExcelWorksheet>
<x:Name>Sheet1</x:Name>
<x:WorksheetOptions>
<x:DisplayGridlines/>
</x:WorksheetOptions>
</x:ExcelWorksheet>
</x:ExcelWorksheets>
</x:ExcelWorkbook>
</xml>
<![endif]-->
<style>
table { border-collapse: collapse; width: 100%; font-family: Arial, sans-serif; }
th, td { border: 1px solid #000; padding: 8px; text-align: left; vertical-align: top; }
th { background-color: #f2f2f2; font-weight: bold; }
.section-title { font-size: 16px; font-weight: bold; margin: 20px 0 10px 0; }
.info-table { margin-bottom: 20px; }
.info-table td { border: 1px solid #ccc; }
.detail-table { margin-bottom: 20px; }
img { max-width: 120px; max-height: 90px; }
</style>
</head>
<body>${printContent}</body>
</html>`;
// 创建Blob
const blob = new Blob([excelContent], {
type: 'application/vnd.ms-excel;charset=utf-8',
});
// 创建下载链接
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `款式详情-${style.value.number}.xls`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
setTimeout(() => {
window.URL.revokeObjectURL(url);
alertService.showInfo($t('entity.action.exportSuccess'));
}, 100);
} catch (error) {
console.error('Excel导出错误:', error);
alertService.showError($t('entity.action.exportError'));
}
};
// 等待图片加载完成
const waitForImages = (element: Element): Promise<void> => {
const images = element.querySelectorAll('img');
const promises = Array.from(images).map(img => {
if (img.complete) return Promise.resolve();
return new Promise(resolve => {
img.onload = img.onerror = resolve;
});
});
return Promise.all(promises).then(() => {});
};
// 加载 StyleGroup 字典项
const loadStyleGroupDicts = async () => {
try {
@ -444,6 +539,7 @@ export default defineComponent({
getSettingTypeName,
getStyleGroupTitle,
downloadPdf,
exportExcel,
styleGroupTitle,
styleGroupDicts,
getStyleGroupName,

View File

@ -6,16 +6,20 @@
<span class="d-none d-md-inline" v-text="$t('entity.action.back')"></span>
</router-link>
<div class="header-actions">
<button type="button" class="btn btn-success me-2" @click="downloadPdf">
<font-awesome-icon icon="download" />
<span class="d-none d-md-inline" v-text="$t('entity.action.download')"></span>
</button>
<button type="button" class="btn btn-warning me-2" @click="exportExcel">
<font-awesome-icon icon="file-excel" />
<span class="d-none d-md-inline" v-text="$t('entity.action.exportExcel')"></span>
</button>
<div class="form-check form-switch me-3">
<input class="form-check-input" type="checkbox" id="printDirectSwitch" v-model="printDirect" />
<label class="form-check-label" for="printDirectSwitch">
{{ $t('entity.action.directPrint') }}
</label>
</div>
<button type="button" class="btn btn-success me-2" @click="downloadPdf">
<font-awesome-icon icon="download" />
<span class="d-none d-md-inline" v-text="$t('entity.action.download')"></span>
</button>
<button type="button" class="btn btn-primary" @click="printStyle">
<font-awesome-icon icon="print" />
<span class="d-none d-md-inline" v-text="$t('entity.action.print')"></span>

View File

@ -142,6 +142,9 @@
"download": "下载",
"downloadSuccess": "下载成功",
"downloadError": "下载失败",
"exportExcel": "导出Excel",
"exportSuccess": "导出成功",
"exportError": "导出失败",
"retake": "重拍",
"retry": "重试",
"new": "新建",

View File

@ -18,8 +18,8 @@
"title": "订单详情"
},
"setting": {
"title": "BOM信息",
"process": "镶嵌信息",
"title": "镶嵌信息",
"process": "镶嵌工序",
"name": "名称",
"material": "物料",
"subgroup": "分组",