我正在做一个项目,使用大量的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 并基于此以某种方式过滤显示的列,但是我很难想出主意。我很感激任何关于如何解决这个问题的提示,谢谢!!
此代码根据所选列动态构建 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”格式。