添加多选表单过滤查询并将过滤后的数据导出到excel文件

问题描述 投票:0回答:1

我正在做一个项目,使用大量的mysql数据导入到excel文件中。到目前为止,我一直在控制器中编写查询,然后将结果数据导出为 Excel 文件。但现在我必须制作一个可以自定义导出数据的过滤器。例如,单击导出按钮时,我将显示一个多选表单,其中包含通常导出到 Excel 的所有可用列,但在该选择表单的帮助下,只有用户选择的列名称才会导出为excel 文件而不是整个查询。例如,如果我通常会有列:姓名、年龄、性别 - 如果用户仅选择姓名,则只会导出姓名。这是我现在的代码:

public function exportExcelAction()
     {
         
         ini_set('memory_limit', '-1');
         ini_set('max_execution_time', 1800);
         ini_set('max_input_time', 1800);
         $this->view->disable();
 
         $spreadsheet = new Spreadsheet();
         $Excel_writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
 
         $sheetName = 'reportHistory';
         $spreadsheet->setActiveSheetIndex(0);
         $activeSheet = $spreadsheet->getActiveSheet()->setTitle($sheetName);
 
         $activeSheet->setCellValue('A1', 'name');
         $activeSheet->setCellValue('B1', 'age');
         $activeSheet->setCellValue('C1', 'gender');
 
         $activeSheet->getStyle('A1:C1')->getFont()->setBold(true);
 
         $builder = $this->modelsManager->createBuilder()
         ->columns([
            'name' => 'a.name',
            'age' => 'a.age',
            'gender => 'a.gender'
        ])
         ->addFrom(Admins::class, 'a');

 
         $result = $builder->getQuery()->execute();
 
         if (!empty($result)) {
             $i = 2;
             foreach ($result as $value) {
                 $activeSheet->setCellValue('A' . $i, $value->name);
                 $activeSheet->setCellValue('B' . $i, $value->age);
                 $activeSheet->setCellValue('C' . $i, $value->gender);
                 $i++;
             }
         }
 
         foreach (range('A', 'C') as $columnID) {
             $activeSheet->getColumnDimension($columnID)
                 ->setAutoSize(true);
         }
 
         $filename = 'reportHistory_' . date('Y-m-d_H-i-s') . '.xlsx';
 
         header('Content-Type: application/vnd.ms-excel');
         header('Content-Disposition: attachment;filename=' . $filename);
         header('Cache-Control: max-age=0');
         $Excel_writer->save('php://output');
     }

我正在考虑从选择表单中获取值作为单元格值,例如 A 或 B,所以如果用户仅选择“名称”,我会给它一个值 A 并基于此以某种方式过滤显示的列,但是我很难想出主意。我很感激任何关于如何解决这个问题的提示,谢谢!!

php mysql phalcon
1个回答
1
投票

此代码根据所选列动态构建 Excel 标题和数据。根据表单实现调整检索所选列的方式。

$columnIndex
用于计算相应的列字母(A、B、C、...)。生成的 Excel 文件将仅包含用户选择的列。

public function exportExcelAction()
{
    ini_set('memory_limit', '-1');
    ini_set('max_execution_time', 1800);
    ini_set('max_input_time', 1800);
    $this->view->disable();

    
    $selectedColumns = ['name', 'age', 'gender']; // Default columns
    // For example, if you have a multi-select form element named 'selectedColumns', you can get it like this:
    // $selectedColumns = $this->request->getPost('selectedColumns');

    $spreadsheet = new Spreadsheet();
    $Excel_writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);

    $sheetName = 'reportHistory';
    $spreadsheet->setActiveSheetIndex(0);
    $activeSheet = $spreadsheet->getActiveSheet()->setTitle($sheetName);

    $columnIndex = 0;
    foreach ($selectedColumns as $columnName) {
        $columnLetter = chr(65 + $columnIndex); // A, B, C, ...
        $activeSheet->setCellValue($columnLetter . '1', $columnName);
        $columnIndex++;
    }

    $builder = $this->modelsManager->createBuilder()
        ->columns($selectedColumns)
        ->addFrom(Admins::class, 'a');

    $result = $builder->getQuery()->execute();

    if (!empty($result)) {
        $rowIndex = 2;
        foreach ($result as $value) {
            $columnIndex = 0;
            foreach ($selectedColumns as $columnName) {
                $columnLetter = chr(65 + $columnIndex); // A, B, C, ...
                $activeSheet->setCellValue($columnLetter . $rowIndex, $value->{$columnName});
                $columnIndex++;
            }
            $rowIndex++;
        }
    }

    foreach (range('A', chr(65 + $columnIndex - 1)) as $columnID) {
        $activeSheet->getColumnDimension($columnID)->setAutoSize(true);
    }

    $filename = 'reportHistory_' . date('Y-m-d_H-i-s') . '.xlsx';

    header('Content-Type: application/vnd.ms-excel');
    header('Content-Disposition: attachment;filename=' . $filename);
    header('Cache-Control: max-age=0');
    $Excel_writer->save('php://output');
}

更新

既然您要求解释如何更改代码,如果您有多个表连接,我为您准备了一个示例解决方案。

如果您有多个表连接并希望从这些连接表中选择列,则需要调整

selectedColumns
数组中的列名称,并相应地修改查询。

public function exportExcelAction()
{
    ini_set('memory_limit', '-1');
    ini_set('max_execution_time', 1800);
    ini_set('max_input_time', 1800);
    $this->view->disable();

    // Get selected columns from the form (you need to adapt this part based on your form implementation)
    $selectedColumns = ['a.name', 'a.age', 'a.gender', 's.somethingColumn']; // Adjust column names based on your tables
    // For example, if you have a multi-select form element named 'selectedColumns', you can get it like this:
    // $selectedColumns = $this->request->getPost('selectedColumns');

    $spreadsheet = new Spreadsheet();
    $Excel_writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);

    $sheetName = 'reportHistory';
    $spreadsheet->setActiveSheetIndex(0);
    $activeSheet = $spreadsheet->getActiveSheet()->setTitle($sheetName);

    // Set header based on selected columns
    $columnIndex = 0;
    foreach ($selectedColumns as $columnName) {
        $columnLetter = chr(65 + $columnIndex); // A, B, C, ...
        // Extract column alias or name from the selected column (e.g., 'a.name' or 'name')
        $columnNameParts = explode('.', $columnName);
        $activeSheet->setCellValue($columnLetter . '1', end($columnNameParts));
        $columnIndex++;
    }

    // Fetch data based on selected columns
    $builder = $this->modelsManager->createBuilder()
        ->columns($selectedColumns)
        ->addFrom(Admins::class, 'a')
        ->innerJoin(Something::class, 's.id = a.somethingID', 's');

    $result = $builder->getQuery()->execute();

    if (!empty($result)) {
        $rowIndex = 2;
        foreach ($result as $value) {
            $columnIndex = 0;
            foreach ($selectedColumns as $columnName) {
                $columnLetter = chr(65 + $columnIndex); // A, B, C, ...
                // Extract column alias or name from the selected column (e.g., 'a.name' or 'name')
                $columnNameParts = explode('.', $columnName);
                $activeSheet->setCellValue($columnLetter . $rowIndex, $value->{$columnNameParts[1]});
                $columnIndex++;
            }
            $rowIndex++;
        }
    }

    // Set column width
    foreach (range('A', chr(65 + $columnIndex - 1)) as $columnID) {
        $activeSheet->getColumnDimension($columnID)->setAutoSize(true);
    }

    $filename = 'reportHistory_' . date('Y-m-d_H-i-s') . '.xlsx';

    header('Content-Type: application/vnd.ms-excel');
    header('Content-Disposition: attachment;filename=' . $filename);
    header('Cache-Control: max-age=0');
    $Excel_writer->save('php://output');
}

确保调整

selectedColumns
数组中的列名称以匹配表中的实际列名称。
explode('.', $columnName)
用于从所选列中提取列别名或名称,考虑到它可能采用“table.column”格式。

© www.soinside.com 2019 - 2024. All rights reserved.