동적 열 이름으로 Excel 시트 생성

27125 단어 phpexcel

문제


PHP에서 Excel 시트를 내보낼 때 | , 또는 다른 언어에서 가장 일반적인 사용 사례는 데이터베이스에서 테이블을 내보내는 것이며 때로는 헤더에 일부 정보가 포함되어 있고 일부 합계가 있는 바닥글도 포함되어 있습니다.

결론적으로, 우리는 테이블과 몇 개의 열을 가지고 있습니다.

다음과 같이 문서의 다른 부분에 각 열 문자를 수동으로 배치하여 정상적으로 진행하는 방법입니다.
  • 헤더
  • 스타일링

  • $spreadsheet = new Spreadsheet();
    $sheet = $spreadsheet->getActiveSheet();
    $sheet->setCellValue('A1', 'Normal way of naming Excel columns');
    
    $i=3;
    
    // Header
    $sheet->setCellValue('A'.$i, 'Name');
    $sheet->setCellValue('B'.$i, 'Phone');
    $sheet->setCellValue('C'.$i, 'City');
    
    // Rows
    foreach ($rows as $row) {
      $i++;
      $sheet->setCellValue('A'.$i, $row['name']);
      $sheet->setCellValue('B'.$i, $row['phone']);
      $sheet->setCellValue('C'.$i, $row['city']);
    }
    
    // Styling
    $lastRowIndex=$i;
    
    $sheet->getStyle('A3:C'.$lastRowIndex)->applyFromArray([
        'borders' => [
            'allBorders' => [
                'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
            ],
        ],
    ]);
    
    $sheet->getStyle('A3:C3')->getFill()
        ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
        ->getStartColor()->setARGB('FFA0A0A0');
    
    $sheet->getColumnDimension('A')->setWidth(12);
    $sheet->getColumnDimension('B')->setWidth(25);
    $sheet->getColumnDimension('C')->setWidth(25);
    
    $writer = new Xlsx($spreadsheet);
    $writer->save('normal.xlsx');
    


    이 접근 방식의 문제는 새 열을 추가하려는 경우 모든 문자의 이름을 바꾸는 데 시간을 소비해야 한다는 것입니다. 또한 스타일을 적용할 때 각 열에 할당한 문자를 기억해야 합니다.

    따라서 열을 추가하려면 Company 이후 Phone , 당신은 그것을 편지에 넣어야 할 것입니다 C , 다음 열의 이름을 바꿉니다 C ~으로 D , 그리고 헤더뿐만 아니라 행과 스타일 등 모든 곳에서 이름을 바꿀 때 이 작업을 수행합니다.

    급한 일이라고 하지만..
  • 열이 10-20개 이상이라면 어떻게 하시겠습니까?
  • 내보낼 때 열을 표시하는 경우와 사용자 기본 설정에 따라 숨기고 싶은 경우가 있다면 어떻게 하시겠습니까?

  • 해결책



    좋아, 그것은 최선의 해결책이 아닐 수도 있습니다. 다른 사람들이 더 나은 방법을 생각할 수도 있다고 확신하지만 이것은 열 이름을 바꾸는 데 많은 시간을 소비하지 않는 한 가지 방법입니다.

    // Load the column names helper
    require 'ExCol.php';
    
    ExCol::reset(); // reset mapping before using
    
    $show_company_column=true;
    
    $spreadsheet = new Spreadsheet();
    $sheet = $spreadsheet->getActiveSheet();
    $sheet->setCellValue('A1', 'Dynamic way of naming Excel columns');
    
    $i=3;
    
    // Header
    $sheet->setCellValue(ExCol::get('name', $i), 'Name');
    $sheet->setCellValue(ExCol::get('phone', $i), 'Phone');
    if ($show_company_column) {
      $sheet->setCellValue(ExCol::get('company', $i), 'Company');
    }
    $sheet->setCellValue(ExCol::get('city', $i), 'City');
    
    // Rows
    foreach ($rows as $row) {
      $i++;
      $sheet->setCellValue(ExCol::get('name', $i), $row['name']);
      $sheet->setCellValue(ExCol::get('phone', $i), $row['phone']);
      if ($show_company_column) {
        $sheet->setCellValue(ExCol::get('company', $i), $row['company']);
      }
      $sheet->setCellValue(ExCol::get('city', $i), $row['city']);
    }
    
    $lastColLetter=ExCol::getLast();
    
    // Styling
    $lastRowIndex=$i;
    
    $sheet->getStyle('A3:'.$lastColLetter.$lastRowIndex)->applyFromArray([
        'borders' => [
            'allBorders' => [
                'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
            ],
        ],
    ]);
    
    $sheet->getStyle("A3:{$lastColLetter}3")->getFill()
        ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
        ->getStartColor()->setARGB('FFA0A0A0');
    
    $sheet->getColumnDimension(ExCol::get('name'))->setWidth(12);
    if ($show_company_column) {
      $sheet->getColumnDimension(ExCol::get('company'))->setWidth(35);
    }
    $sheet->getColumnDimension(ExCol::get('phone'))->setWidth(25);
    $sheet->getColumnDimension(ExCol::get('city'))->setWidth(25);
    
    $writer = new Xlsx($spreadsheet);
    $writer->save('dynamic.xlsx');
    


    어떻게 작동합니까?

    글쎄, 우리는 ExCol라는 작은 도우미 클래스를 만들었습니다. .

    나는 더 나은 이름을 찾을 수 있었지만 적어도 짧습니다.

    <?php
    
    use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
    
    class ExCol {
    
      static private $_map=array();
    
      static public function get($col, $row=null) {
        if (!in_array($col, self::$_map)) {
          self::$_map[]=$col;
        }
        $index = array_search($col, self::$_map);
        $columnLetter = Coordinate::stringFromColumnIndex($index + 1);
        return $columnLetter.($row?$row:null);
      }
    
      static public function getLast() {
        return Coordinate::stringFromColumnIndex(count(self::$_map));
      }
    
      static public function reset() {
        self::$_map=array();
      }
    
    }
    


    이 클래스를 사용하면 열에 대한 문자가 필요할 때마다 메서드를 호출하면 됩니다. ExCol::get() .

    예:

    ExCol::get('my_first_column'); // Returns A
    ExCol::get('my_second_column'); // Returns B
    ExCol::get('my_third_column'); // Returns C
    ExCol::get('my_third_column', 2); // Returns C2
    


    선택적으로 $row 번호로 돌아가지 않고 C , 우리는 얻을 것이다 C2 연결을 사용하지 않아도 됩니다.

    따라서 클래스는 요청된 순서대로 요청된 열의 인덱스를 정적으로 저장합니다. 그리고 각 열에 할당된 인덱스를 기반으로 PhpSpreadsheet를 사용하여 해당 문자를 반환합니다. 님 Coordinate::stringFromColumnIndex() 방법.

    이제 코드의 새로운 부분을 살펴보겠습니다.

    여러 Excel 파일을 생성하는 데 사용되는 스크립트에서 도우미를 사용하는 경우 reset() 이전 파일의 열이 포함되지 않도록 인덱스를 지우는 메서드입니다.

    ExCol::reset(); // reset mapping before using
    


    그런 다음 열 중 하나를 표시하거나 숨기기 위한 변수를 정의합니다.

    $show_company_column=true;
    


    헤더를 인쇄할 때 필요한 경우에만 해당 열을 포함합니다.

    // Header
    $sheet->setCellValue(ExCol::get('name', $i), 'Name');
    $sheet->setCellValue(ExCol::get('phone', $i), 'Phone');
    if ($show_company_column) {
      $sheet->setCellValue(ExCol::get('company', $i), 'Company');
    }
    $sheet->setCellValue(ExCol::get('city', $i), 'City');
    


    행을 반복하고 스타일을 지정할 때도 마찬가지입니다.

    // Rows
    foreach ($rows as $row) {
      $i++;
      $sheet->setCellValue(ExCol::get('name', $i), $row['name']);
      $sheet->setCellValue(ExCol::get('phone', $i), $row['phone']);
      if ($show_company_column) {
        $sheet->setCellValue(ExCol::get('company', $i), $row['company']);
      }
      $sheet->setCellValue(ExCol::get('city', $i), $row['city']);
    }
    


    따라서 하나의 열을 동적으로 포함하고 있음을 알 수 있습니다. 따라서 3개의 열만 넣으면 도우미가 제공할 것입니다 A , BC , 하지만 4를 넣으면 A , B , C , D .

    표시할 열을 동적으로 제어하거나 열을 더 추가하거나 일부를 제거해야 하는 경우 모두 자동으로 수행되므로 이름을 변경할 필요가 없습니다.

    전체 소스 코드는 다음과 같습니다.

    https://github.com/atrandafir/excel-dynamic-columns

    원본 게시물:

    https://atrandafir.dev/post/generating-excel-sheet-dynamic-column-names

    좋은 웹페이지 즐겨찾기