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

PHP生成Allotment Request Form时日期按配额分组问题

解决Excel生成中连续相同配额日期的分组合并问题

核心思路

先对数据库返回的日期数据进行预处理:按日期升序排序后,将连续日期且total_kontenjan、dolu_kontenjan完全一致的记录合并为一个日期范围组,再将分组后的数据写入Excel,而非直接逐条输出原始数据。


步骤1:数据分组预处理代码

假设你从数据库查询到的原始数据已按tarih(日期)升序排序(务必加ORDER BY tarih ASC,否则分组逻辑失效),以下是分组处理的PHP代码:

// 示例原始数据库数据(需确保已按日期升序排序)
$data = [
    ['tarih' => '2024-05-01', 'total_kontenjan' => 10, 'dolu_kontenjan' => 3],
    ['tarih' => '2024-05-02', 'total_kontenjan' => 10, 'dolu_kontenjan' => 3],
    ['tarih' => '2024-05-03', 'total_kontenjan' => 15, 'dolu_kontenjan' => 5],
    ['tarih' => '2024-05-04', 'total_kontenjan' => 15, 'dolu_kontenjan' => 5],
    ['tarih' => '2024-05-05', 'total_kontenjan' => 10, 'dolu_kontenjan' => 4],
];

$groupedData = [];
if (!empty($data)) {
    // 初始化第一个分组
    $currentGroup = [
        'start_date' => $data[0]['tarih'],
        'end_date' => $data[0]['tarih'],
        'total' => $data[0]['total_kontenjan'],
        'used' => $data[0]['dolu_kontenjan']
    ];

    foreach (array_slice($data, 1) as $item) {
        $currentDate = new DateTime($item['tarih']);
        $prevEndDate = new DateTime($currentGroup['end_date']);
        $prevEndDate->modify('+1 day');

        // 判断:日期连续 + 两个配额值完全一致
        if ($currentDate->format('Y-m-d') === $prevEndDate->format('Y-m-d')
            && $item['total_kontenjan'] === $currentGroup['total']
            && $item['dolu_kontenjan'] === $currentGroup['used']) {
            // 合并到当前分组,更新结束日期
            $currentGroup['end_date'] = $item['tarih'];
        } else {
            // 保存当前分组,初始化新分组
            $groupedData[] = $currentGroup;
            $currentGroup = [
                'start_date' => $item['tarih'],
                'end_date' => $item['tarih'],
                'total' => $item['total_kontenjan'],
                'used' => $item['dolu_kontenjan']
            ];
        }
    }
    // 保存最后一个分组
    $groupedData[] = $currentGroup;
}

步骤2:将分组数据写入Excel

以常用的PhpSpreadsheet为例(旧版PHPExcel逻辑完全一致),直接使用分组后的$groupedData生成Excel:

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();

// 设置表头
$sheet->setCellValue('A1', '日期范围');
$sheet->setCellValue('B1', '总配额');
$sheet->setCellValue('C1', '已用配额');

// 填充分组数据
$rowNum = 2;
foreach ($groupedData as $group) {
    // 生成日期范围文本:单日期直接显示,多日期显示"起始至结束"格式
    $dateRange = $group['start_date'] === $group['end_date'] 
        ? $group['start_date'] 
        : "{$group['start_date']} 至 {$group['end_date']}";
    
    $sheet->setCellValue("A{$rowNum}", $dateRange);
    $sheet->setCellValue("B{$rowNum}", $group['total']);
    $sheet->setCellValue("C{$rowNum}", $group['used']);
    $rowNum++;
}

// 输出Excel文件
$writer = new Xlsx($spreadsheet);
$writer->save('allotment_request_form.xlsx');

关键注意事项

  1. 必须排序:数据库查询时必须添加ORDER BY tarih ASC,否则连续日期的判断会出错;
  2. 日期比较:使用DateTime类处理日期,避免字符串直接比较导致的格式兼容问题;
  3. 分组条件:必须同时满足「日期连续」「总配额相同」「已用配额相同」三个条件,才会合并为一个日期范围。

内容的提问来源于stack exchange,提问作者Laquire

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:52:43