This commit is contained in:
2026-05-29 16:27:28 +08:00
10 changed files with 263 additions and 2 deletions

View File

@@ -29,6 +29,7 @@ import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Excel相关处理
@@ -149,6 +150,33 @@ public class ExcelUtil {
builder.doWrite(list);
}
/**
* 导出excel仅导出指定列
*
* @param list 导出数据集合
* @param sheetName 工作表的名称
* @param clazz 实体类
* @param includeColumnFieldNames 需要导出的字段名集合Java字段名非Excel列名
* @param response 响应体
*/
public static <T> void exportExcel(List<T> list, String sheetName, Class<T> clazz,
Set<String> includeColumnFieldNames,
HttpServletResponse response) {
try {
resetResponse(sheetName, response);
ServletOutputStream os = response.getOutputStream();
EasyExcel.write(os, clazz)
.autoCloseStream(false)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerConverter(new ExcelBigNumberConvert())
.includeColumnFieldNames(includeColumnFieldNames)
.sheet(sheetName)
.doWrite(list);
} catch (IOException e) {
throw new RuntimeException("导出Excel异常");
}
}
/**
* 单表多数据模板导出 模板格式为 {.属性}
*

View File

@@ -94,6 +94,10 @@ public class QcInspectionTask extends BaseEntity {
* 附件路径(多个用英文逗号分隔)
*/
private String attachmentFiles;
/**
* 厂家卷号集合,多个使用英文逗号分隔
*/
private String supplierCoilNos;
/**
* 删除标志0=正常1=已删除)

View File

@@ -108,4 +108,9 @@ public class QcInspectionTaskBo extends BaseEntity {
* 附件路径(多个用英文逗号分隔)
*/
private String attachmentFiles;
/**
* 厂家卷号集合,多个使用英文逗号分隔
*/
private String supplierCoilNos;
}

View File

@@ -134,6 +134,11 @@ public class QcInspectionTaskVo {
*/
private String attachmentFiles;
/**
* 厂家卷号集合,多个使用英文逗号分隔
*/
private String supplierCoilNos;
private List<WmsMaterialCoilVo> coilList;

View File

@@ -136,6 +136,7 @@ public class QcInspectionTaskServiceImpl implements IQcInspectionTaskService {
lqw.eq(StringUtils.isNotBlank(bo.getResult()), QcInspectionTask::getResult, bo.getResult());
lqw.like(StringUtils.isNotBlank(bo.getCoilIds()), QcInspectionTask::getCoilIds, bo.getCoilIds());
lqw.like(StringUtils.isNotBlank(bo.getEnterCoilNos()), QcInspectionTask::getEnterCoilNos, bo.getEnterCoilNos());
lqw.like(StringUtils.isNotBlank(bo.getSupplierCoilNos()), QcInspectionTask::getSupplierCoilNos, bo.getSupplierCoilNos());
return lqw;
}

View File

@@ -23,6 +23,7 @@
<result property="attachmentFiles" column="attachment_files"/>
<result property="coilIds" column="coil_ids"/>
<result property="enterCoilNos" column="enter_coil_nos"/>
<result property="supplierCoilNos" column="supplier_coil_nos"/>
<result property="delFlag" column="del_flag"/>
<result property="createTime" column="create_time"/>
<result property="createBy" column="create_by"/>

View File

@@ -488,4 +488,12 @@ export function listLightCoil(data) {
timeout: 600000,
data: data
})
}
// 获取可导出的列元数据
export function getExportColumns() {
return request({
url: '/wms/materialCoil/exportColumns',
method: 'get',
})
}

View File

@@ -56,6 +56,7 @@
<el-form-item prop="endTime">
<el-button type="primary" @click="getList">查询</el-button>
<el-button type="primary" @click="exportData">导出</el-button>
<el-button type="primary" @click="openCustomExport">自定义导出</el-button>
<el-button type="primary" @click="settingVisible = true">列设置</el-button>
<el-button type="primary" @click="saveReport">保存报表</el-button>
</el-form-item>
@@ -84,11 +85,45 @@
</el-radio-group>
<columns-setting :reportType="activeColumnConfig"></columns-setting>
</el-dialog>
<!-- 自定义导出列选择弹窗 -->
<el-dialog title="自定义导出 - 选择导出列" :visible.sync="customExportVisible" width="750px">
<div class="custom-export-toolbar">
<el-input v-model="columnSearch" placeholder="搜索列名" prefix-icon="el-icon-search" clearable size="small" style="width: 220px" />
<div class="custom-export-actions">
<el-button size="small" @click="selectAllColumns">全选</el-button>
<el-button size="small" @click="invertColumns">反选</el-button>
<el-button size="small" @click="selectedColumns = []">清空</el-button>
</div>
</div>
<div class="custom-export-body">
<el-checkbox-group v-model="selectedColumns">
<div v-for="(group, gName) in groupedColumns" :key="gName" class="column-group">
<div class="column-group-title">{{ gName }}</div>
<div class="column-group-items">
<el-checkbox
v-for="field in group"
:key="field.key"
:label="field.key"
:style="{ display: columnSearch && !filterMatch(field) ? 'none' : '' }"
>{{ field.label }}</el-checkbox>
</div>
</div>
</el-checkbox-group>
</div>
<div slot="footer" class="custom-export-footer">
<span class="selected-tip">已选 <b>{{ selectedColumns.length }}</b> / {{ flatColumns.length }} </span>
<el-button @click="customExportVisible = false">取消</el-button>
<el-button type="primary" @click="doCustomExport" :disabled="selectedColumns.length === 0">
导出选中列
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listCoilWithIds } from "@/api/wms/coil";
import { listCoilWithIds, getExportColumns } from "@/api/wms/coil";
import {
listPendingAction,
} from '@/api/wms/pendingAction';
@@ -146,6 +181,20 @@ export default {
return {
activeColumnConfig: 'coil-report-receive',
settingVisible: false,
customExportVisible: false,
exportColumns: {},
selectedColumns: [],
columnSearch: '',
columnGroups: {
'基本信息': ['itemTypeDesc', 'warehouseName', 'actualWarehouseName', 'dataTypeText'],
'钢卷号': ['enterCoilNo', 'supplierCoilNo', 'currentCoilNo'],
'时间': ['createTime', 'exportTime', 'exportBy'],
'物理属性': ['netWeight', 'length', 'specification', 'actualThickness'],
'材质属性': ['material', 'manufacturer', 'surfaceTreatmentDesc', 'zincLayer', 'packingStatus', 'temperGrade', 'coatingType'],
'用途': ['purpose', 'businessPurpose'],
'状态': ['qualityStatus', 'statusDesc', 'isRelatedToOrderText'],
'其他': ['itemName', 'itemId', 'packagingRequirement', 'trimmingRequirement', 'transferType', 'saleName', 'remark', 'team'],
},
list: [],
defaultStartTime: startTime,
defaultEndTime: endTime,
@@ -221,6 +270,21 @@ export default {
coilIds() {
return this.list.map(item => item.coilId).join(',')
},
groupedColumns() {
const result = {}
Object.entries(this.columnGroups).forEach(([groupName, fieldKeys]) => {
const items = fieldKeys
.filter(key => this.exportColumns[key])
.map(key => ({ key, label: this.exportColumns[key] }))
if (items.length) {
result[groupName] = items
}
})
return result
},
flatColumns() {
return Object.values(this.groupedColumns).flat()
},
},
methods: {
@@ -282,6 +346,33 @@ export default {
coilIds: this.coilIds,
}, `materialCoil_${new Date().getTime()}.xlsx`)
},
// 打开自定义导出弹窗
openCustomExport() {
getExportColumns().then(res => {
this.exportColumns = res.data
this.selectedColumns = []
this.customExportVisible = true
})
},
// 执行自定义导出
doCustomExport() {
this.customExportVisible = false
this.download('wms/materialCoil/exportCustom', {
coilIds: this.coilIds,
columns: this.selectedColumns.join(','),
}, `materialCoil_${new Date().getTime()}.xlsx`)
},
filterMatch(field) {
const keyword = this.columnSearch.toLowerCase()
return !keyword || field.label.toLowerCase().includes(keyword) || field.key.toLowerCase().includes(keyword)
},
selectAllColumns() {
this.selectedColumns = this.flatColumns.map(f => f.key)
},
invertColumns() {
const allKeys = this.flatColumns.map(f => f.key)
this.selectedColumns = allKeys.filter(k => !this.selectedColumns.includes(k))
},
saveReport() {
this.loading = true
saveReportFile(this.coilIds, {
@@ -310,4 +401,53 @@ export default {
}
</script>
<style scoped></style>
<style scoped>
.custom-export-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid #ebeef5;
}
.custom-export-actions {
display: flex;
gap: 8px;
}
.custom-export-body {
max-height: 420px;
overflow-y: auto;
}
.column-group {
margin-bottom: 14px;
}
.column-group-title {
font-size: 13px;
font-weight: 600;
color: #606266;
margin-bottom: 8px;
padding-left: 2px;
border-left: 3px solid #409eff;
padding-left: 8px;
}
.column-group-items {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 4px 12px;
}
.column-group-items .el-checkbox {
margin-right: 0;
}
.custom-export-footer {
display: flex;
align-items: center;
justify-content: space-between;
}
.selected-tip {
font-size: 13px;
color: #909399;
}
.selected-tip b {
color: #409eff;
}
</style>

View File

@@ -5,6 +5,9 @@ import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.stream.Collectors;
import java.util.HashMap;
@@ -30,6 +33,7 @@ import com.klp.common.core.validate.AddGroup;
import com.klp.common.core.validate.EditGroup;
import com.klp.common.enums.BusinessType;
import com.klp.common.utils.poi.ExcelUtil;
import com.klp.common.utils.StringUtils;
import com.klp.domain.bo.WmsMaterialCoilBo;
import com.klp.domain.bo.WmsMaterialCoilReportSummaryBo;
import com.klp.domain.vo.dashboard.CoilTrimStatisticsVo;
@@ -130,6 +134,70 @@ public class WmsMaterialCoilController extends BaseController {
List<WmsMaterialCoilExportVo> list = iWmsMaterialCoilService.queryExportList(bo);
ExcelUtil.exportExcel(list, "钢卷物料表", WmsMaterialCoilExportVo.class, response);
}
/**
* 个性化导出:前端传入要导出的字段名,仅导出选中列
* columns 参数为逗号分隔的 Java 字段名,如 "itemTypeDesc,enterCoilNo,netWeight"
* 不传 columns 时等同于 /exportAll 导出全部字段
*/
@Log(title = "钢卷物料表", businessType = BusinessType.EXPORT)
@PostMapping("/exportCustom")
public void exportCustom(WmsMaterialCoilBo bo,
@RequestParam(required = false) String columns,
HttpServletResponse response) {
List<WmsMaterialCoilAllExportVo> list = iWmsMaterialCoilService.queryExportListAll(bo);
if (StringUtils.isNotBlank(columns)) {
Set<String> includeFields = new HashSet<>(Arrays.asList(columns.split(",")));
ExcelUtil.exportExcel(list, "钢卷物料表", WmsMaterialCoilAllExportVo.class, includeFields, response);
} else {
ExcelUtil.exportExcel(list, "钢卷物料表", WmsMaterialCoilAllExportVo.class, response);
}
}
/**
* 获取可导出的列元数据(供前端列选择器使用)
* 返回 { "fieldName": "中文列名" } 的映射,基于完整导出字段
*/
@GetMapping("/exportColumns")
public R<Map<String, String>> getExportColumns() {
Map<String, String> columns = new LinkedHashMap<>();
columns.put("itemTypeDesc", "类型");
columns.put("warehouseName", "逻辑库区");
columns.put("actualWarehouseName", "实际库区");
columns.put("enterCoilNo", "入场卷号");
columns.put("supplierCoilNo", "厂家卷号");
columns.put("currentCoilNo", "成品卷号");
columns.put("createTime", "日期");
columns.put("exportTime", "发货时间");
columns.put("exportBy", "发货人");
columns.put("netWeight", "重量");
columns.put("purpose", "用途");
columns.put("trimmingRequirement", "切边要求");
columns.put("packagingRequirement", "包装种类");
columns.put("qualityStatus", "产品质量");
columns.put("packingStatus", "原料材质");
columns.put("statusDesc", "库存状态");
columns.put("remark", "备注");
columns.put("itemName", "名称");
columns.put("length", "长度");
columns.put("specification", "规格");
columns.put("material", "材质");
columns.put("manufacturer", "厂家");
columns.put("surfaceTreatmentDesc", "表面处理");
columns.put("zincLayer", "锌层");
columns.put("itemId", "物品ID");
columns.put("dataTypeText", "数据类型");
columns.put("temperGrade", "调制度");
columns.put("coatingType", "镀层种类");
columns.put("businessPurpose", "业务用途");
columns.put("isRelatedToOrderText", "是否与订单相关");
columns.put("saleName", "销售人员");
columns.put("actualThickness", "实测厚度");
columns.put("transferType", "调拨类型");
columns.put("team", "班组");
return R.ok(columns);
}
/**
* 导出钢卷物料表列表(完整字段版本)
* 导出全部字段

View File

@@ -78,6 +78,7 @@ public class WmsMaterialCoilAllExportVo {
private BigDecimal netWeight;
// 班组
@ExcelProperty(value = "班组")
private String team;
/**