You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP Excel按SO NUMBER与Item Code分组实现Sales Order扣减Delivery Order数量

实现SO数量按分组扣减的PHP解决方案

你原先使用的双层嵌套循环时间复杂度为O(n²),数据量大时性能损耗严重,且存在数组下标越界的风险,更推荐使用单次遍历预聚合的方案,时间复杂度仅为O(n),实现逻辑如下:

方案1:输出分组汇总行(每个SO号+ITEM编码组合仅保留一行)

该方案和你目标格式的汇总逻辑匹配,先统计每个组合的总SO数量、总DO数量,再统一扣减计算剩余量:

// 第一步:预聚合统计每个分组的总数量
$groupStats = [];
foreach ($data as $item) {
    // 拼接分组唯一key,分隔符可按需替换为不会出现在SO号/ITEM编码里的字符
    $groupKey = $item['SONUMBER'] . '|' . $item['ITEMCODE'];
    if (!isset($groupStats[$groupKey])) {
        $groupStats[$groupKey] = [
            'SONUMBER' => $item['SONUMBER'],
            'ITEMCODE' => $item['ITEMCODE'],
            'totalSO' => 0,
            'totalDO' => 0
        ];
    }
    $groupStats[$groupKey]['totalSO'] += $item['SOQTY'];
    $groupStats[$groupKey]['totalDO'] += $item['DOQTY'];
}

// 第二步:写入Excel
$rowCount = 2;
$activeSheet = $spreadsheet->setActiveSheetIndex(0);
foreach ($groupStats as $stat) {
    // 计算剩余可发量,负数统一取0,可按需调整规则
    $remainingQty = max(0, $stat['totalSO'] - $stat['totalDO']);
    $activeSheet
        ->setCellValue('A' . $rowCount, $stat['SONUMBER'])
        ->setCellValue('B' . $rowCount, $stat['ITEMCODE'])
        ->setCellValue('C' . $rowCount, $stat['totalSO'])
        ->setCellValue('D' . $rowCount, $stat['totalDO'])
        ->setCellValue('E' . $rowCount, $remainingQty);
    $rowCount++;
}

方案2:保留原始明细行

如果需要保留所有原始明细,仅在每行追加对应分组的剩余量,可使用以下写法:

// 第一步:预统计每个分组的总DO数量
$groupDoTotal = [];
foreach ($data as $item) {
    $groupKey = $item['SONUMBER'] . '|' . $item['ITEMCODE'];
    $groupDoTotal[$groupKey] = ($groupDoTotal[$groupKey] ?? 0) + $item['DOQTY'];
}

// 第二步:遍历明细写入Excel
$rowCount = 2;
$activeSheet = $spreadsheet->setActiveSheetIndex(0);
foreach ($data as $item) {
    $groupKey = $item['SONUMBER'] . '|' . $item['ITEMCODE'];
    $remainingQty = max(0, $item['SOQTY'] - $groupDoTotal[$groupKey]);
    $activeSheet
        ->setCellValue('A' . $rowCount, $item['SONUMBER'])
        ->setCellValue('B' . $rowCount, $item['ITEMCODE'])
        ->setCellValue('C' . $rowCount, $item['SOQTY'])
        ->setCellValue('D' . $rowCount, $item['DOQTY'])
        ->setCellValue('E' . $rowCount, $remainingQty);
    $rowCount++;
}

内容的提问来源于stack exchange,提问作者Erix Syaiful Rohman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 01:54:05