Chiều rộng cột kích thước tự động PHPExcel


100

Tôi đang cố gắng tự động kích thước các cột trong trang tính của mình. Tôi đang viết tệp và cuối cùng tôi cố gắng thay đổi kích thước tất cả các cột của mình.

// Add some data
$objPHPExcel->setActiveSheetIndex(0)
            ->setCellValue('B1', 'test1111111111111111111111')
            ->setCellValue('C1', 'test1111111111111')
            ->setCellValue('D1', 'test1111111')
            ->setCellValue('E1', 'test11111')
            ->setCellValue('F1', 'test1')
            ->setCellValue('G1', 'test1');

foreach($objPHPExcel->getActiveSheet()->getColumnDimension() as $col) {
    $col->setAutoSize(true);
}
$objPHPExcel->getActiveSheet()->calculateColumnWidths();

Đoạn mã trên không hoạt động. Không thay đổi kích thước cột để vừa với văn bản

CẬP NHẬT Người viết tôi đang sử dụng$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

Câu trả lời:


195

Nếu một cột được đặt thành Tự động kích thước, PHPExcel sẽ cố gắng tính toán chiều rộng cột dựa trên giá trị được tính toán của cột (vì vậy dựa trên kết quả của bất kỳ công thức nào) và bất kỳ ký tự bổ sung nào được thêm vào bởi mặt nạ định dạng, chẳng hạn như nghìn dấu phân cách.

Theo mặc định, đây là estimatedchiều rộng: có sẵn một phương pháp tính toán chính xác hơn, dựa trên việc sử dụng GD, phương pháp này cũng có thể xử lý các đặc điểm kiểu phông chữ như đậm và nghiêng; nhưng đây là chi phí lớn hơn nhiều, vì vậy nó bị tắt theo mặc định. Bạn có thể kích hoạt phép tính chính xác hơn bằng cách sử dụng

PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

Tuy nhiên, kích thước tự động không áp dụng cho tất cả các định dạng Writer ... ví dụ: CSV. Bạn không đề cập đến nhà văn bạn đang sử dụng.

Nhưng bạn cũng cần xác định các cột để đặt thứ nguyên:

foreach(range('B','G') as $columnID) {
    $objPHPExcel->getActiveSheet()->getColumnDimension($columnID)
        ->setAutoSize(true);
}

$objPHPExcel->getActiveSheet()->getColumnDimension() mong đợi một ID cột.

$objPHPExcel->getActiveSheet()->getColumnDimensions()sẽ trả về một mảng của tất cả các bản ghi kích thước cột đã xác định; nhưng trừ khi bản ghi kích thước cột đã được tạo rõ ràng (có thể bằng cách tải mẫu hoặc bằng cách gọi thủ công getColumnDimension()) thì nó sẽ không tồn tại (tiết kiệm bộ nhớ).


Cảm ơn bạn rất nhiều. Nó hoạt động. Nó không tính toán khoảng cách thừa được tạo ra từ phông chữ đậm, mặc dù điều đó được mong đợi (tôi đã đọc nó ở đâu đó). Bạn có thể cập nhật câu trả lời của mình để bao gồm cả điều đó không?
Alkis Kalogeris

1
Nếu bạn cần mức độ chính xác đó với kiểu chữ như in đậm hoặc nghiêng, thì bạn cần sử dụng PHPExcel_Shared_Font :: AUTOSIZE_METHOD_EXACT, nhưng nó chậm hơn rất nhiều
Mark Baker

Không sao đâu, tôi không quan tâm. Mặc dù tôi không biết phải làm như thế nào. Tôi đang sử dụng 01simple-download-xls.php từ thư mục Test. Tôi thêm dòng đó vào đâu? Xin lỗi cho sự noob hoàn toàn của tôi. Tôi chỉ mới bắt đầu chơi với nó.
Alkis Kalogeris

2
Ngoài ra, nếu bạn không muốn lặp qua thư cột nhưng chỉ thay vào đó bạn có thể sử dụng phương pháp tĩnh PHPExcel_Cell :: stringFromColumnIndex ($ columnIndex) để có được bức thư cột
MeatPopsicle

@MarkBaker. Hiện tại tôi đang sử dụng $ activeSheetObj-> getColumnDimension ('G') -> setWidth (35); các cột trong danh sách có thể có thứ tự bất kỳ.
Rosa Mystica

55

Nếu bạn cần làm điều đó trên nhiều trang tính và nhiều cột trong mỗi trang tính, đây là cách bạn có thể lặp lại qua tất cả chúng:

// Auto size columns for each worksheet
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {

    $objPHPExcel->setActiveSheetIndex($objPHPExcel->getIndex($worksheet));

    $sheet = $objPHPExcel->getActiveSheet();
    $cellIterator = $sheet->getRowIterator()->current()->getCellIterator();
    $cellIterator->setIterateOnlyExistingCells(true);
    /** @var PHPExcel_Cell $cell */
    foreach ($cellIterator as $cell) {
        $sheet->getColumnDimension($cell->getColumn())->setAutoSize(true);
    }
}

7
Đây là giải pháp tốt hơn, vì nó không đòi hỏi phải có sự xem xét đặc biệt đối với các cột Z. qua
Anthony

2
Tôi có thể xác nhận rằng câu trả lời này cũng hoạt động hoàn hảo trong PhpS SpreadSheet. Cảm ơn rất nhiều!
Hissvard

23

Đây là một biến thể linh hoạt hơn dựa trên bài đăng của @Mark Baker:

foreach (range('A', $phpExcelObject->getActiveSheet()->getHighestDataColumn()) as $col) {
        $phpExcelObject->getActiveSheet()
                ->getColumnDimension($col)
                ->setAutoSize(true);
    } 

Hi vọng điêu nay co ich ;)


14
Điều này chỉ hoạt động cho đến Z, vì range('A', 'AB')sẽ chỉ trả về một mục có tên là 'A'. Vì vậy, sử dụng range()trong trường hợp này KHÔNG phải là một ý kiến ​​hay!
Michael

7
Tuy nhiên, điều này hoạt động: for ($ i = 'A'; $ i! = $ PhpExcelObject-> getActiveSheet () -> getHighestColumn (); $ i ++) {$ worksheet-> getColumnDimension ($ i) -> setAutoSize (TRUE); }
Nathan

14
for ($i = 'A'; $i !=  $objPHPExcel->getActiveSheet()->getHighestColumn(); $i++) {
    $objPHPExcel->getActiveSheet()->getColumnDimension($i)->setAutoSize(TRUE);
}

2
câu trả lời tốt nhưng nên $i <= $objPHPExcel->getActiveSheet()->getHighestColumn()khác cột cuối cùng không được có kích thước
billynoah

10

Đây là ví dụ về cách sử dụng tất cả các cột từ trang tính:

$sheet = $PHPExcel->getActiveSheet();
$cellIterator = $sheet->getRowIterator()->current()->getCellIterator();
$cellIterator->setIterateOnlyExistingCells( true );
/** @var PHPExcel_Cell $cell */
foreach( $cellIterator as $cell ) {
        $sheet->getColumnDimension( $cell->getColumn() )->setAutoSize( true );
}

3
Vui lòng thêm một số ngữ cảnh xung quanh câu trả lời của bạn để giải thích cách nó giải quyết vấn đề
Andrew Stubbs

6

Đoạn mã này sẽ tự động định kích thước tất cả các cột chứa dữ liệu trong tất cả các trang tính. Không cần sử dụng trình nhận và thiết lập ActiveSheet.

// In my case this line didn't make much of a difference
PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);
// Iterating all the sheets
/** @var PHPExcel_Worksheet $sheet */
foreach ($objPHPExcel->getAllSheets() as $sheet) {
    // Iterating through all the columns
    // The after Z column problem is solved by using numeric columns; thanks to the columnIndexFromString method
    for ($col = 0; $col <= PHPExcel_Cell::columnIndexFromString($sheet->getHighestDataColumn()); $col++) {
        $sheet->getColumnDimensionByColumn($col)->setAutoSize(true);
    }
}

6

cho phpspreadsheet:

$sheet = $spreadsheet->getActiveSheet(); // $spreadsheet is instance of PhpOffice\PhpSpreadsheet\Spreadsheet

foreach (
    range(
         1, 
         Coordinate::columnIndexFromString($sheet->getHighestColumn(1))
    ) as $column
) {
    $sheet
          ->getColumnDimension(Coordinate::stringFromColumnIndex($column))
          ->setAutoSize(true);
}

foreach (range('A', $sheet->getHighestDataColumn()) as $column) {$sheet->getColumnDimension($column)->setAutoSize(true);}
Wesley Abbenhuis

1
@WesleyAbbenhuis bình luận của bạn sẽ chỉ hoạt động khi không có quá 26 cột. Khi cột cao nhất là ví dụ: 'AH', hàm phạm vi sẽ không hoạt động bình thường.
Sander Van Keer

3
foreach(range('B','G') as $columnID)
{
    $objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setAutoSize(true);
}

3

Trong trường hợp ai đó đang tìm kiếm điều này.

Giải pháp bên dưới cũng hoạt động trên PHPSpreadsheetphiên bản PHPExcel mới của họ.

// assuming $spreadsheet is instance of PhpOffice\PhpSpreadsheet\Spreadsheet
// assuming $worksheet = $spreadsheet->getActiveSheet();
foreach(range('A',$worksheet->getHighestColumn()) as $column) {
    $spreadsheet->getColumnDimension($column)->setAutoSize(true);
}

Lưu ý: getHighestColumn()có thể được thay thế bằng getHighestDataColumn()hoặc cột thực tế cuối cùng.

Những phương pháp này làm gì:

getHighestColumn($row = null) - Nhận cột bảng tính cao nhất.

getHighestDataColumn($row = null) - Nhận cột trang tính cao nhất có chứa dữ liệu.

getHighestRow($column = null) - Nhận hàng bảng tính cao nhất

getHighestDataRow($column = null) - Nhận hàng trang tính cao nhất có chứa dữ liệu.


2

Nếu bạn cố gắng lặp lại với for ($col = 2; $col <= 'AC'; ++ $col){...}, hoặc với foreach(range('A','AC') as $col) {...}nó sẽ hoạt động cho các cột từ A đến Z, nhưng nó không vượt qua được Z (Ví dụ: lặp giữa 'A' đến 'AC').

Để lặp lại pass 'Z', bạn cần chuyển đổi cột thành số nguyên, tăng dần, so sánh và lấy lại nó dưới dạng chuỗi:

$MAX_COL = $sheet->getHighestDataColumn();
$MAX_COL_INDEX = PHPExcel_Cell::columnIndexFromString($MAX_COL);
    for($index=0 ; $index <= $MAX_COL_INDEX ; $index++){
    $col = PHPExcel_Cell::stringFromColumnIndex($index);

    // do something, like set the column width...
    $sheet->getColumnDimension($col)->setAutoSize(TRUE);
}

Với điều này, bạn dễ dàng lặp lại chuyển cột 'Z' và đặt tự động kích thước cho mọi cột.


1

Đến muộn, nhưng sau khi tìm kiếm khắp nơi, tôi đã tạo ra một giải pháp có vẻ là "một trong những".

Được biết rằng có một trình lặp cột trên các phiên bản API mới nhất, nhưng không biết cách tự điều chỉnh đối tượng cột đó, về cơ bản tôi đã tạo một vòng lặp để đi từ cột thực được sử dụng đầu tiên đến cột được sử dụng cuối cùng thực sự.

Nó đi từ đây:

//Just before saving de Excel document, you do this:

PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

//We get the util used space on worksheet. Change getActiveSheet to setActiveSheetIndex(0) to choose the sheet you want to autosize. Iterate thorugh'em if needed.
//We remove all digits from this string, which cames in a form of "A1:G24".
//Exploding via ":" to get a 2 position array being 0 fisrt used column and 1, the last used column.
$cols = explode(":", trim(preg_replace('/\d+/u', '', $objPHPExcel->getActiveSheet()->calculateWorksheetDimension())));

$col = $cols[0]; //first util column with data
$end = ++$cols[1]; //last util column with data +1, to use it inside the WHILE loop. Else, is not going to use last util range column.
while($col != $end){
    $objPHPExcel->getActiveSheet()->getColumnDimension($col)->setAutoSize(true);

    $col++;
}

//Saving.
$objWriter->save('php://output');

1

bạn cũng cần xác định các cột để đặt thứ nguyên:

foreach (range('A', $phpExcelObject->getActiveSheet()->getHighestDataColumn()) as $col) {
$phpExcelObject
        ->getActiveSheet()
        ->getColumnDimension($col)
        ->setAutoSize(true);
}

1
$col = 'A';
while(true){
    $tempCol = $col++;
    $objPHPExcel->getActiveSheet()->getColumnDimension($tempCol)->setAutoSize(true);
    if($tempCol == $objPHPExcel->getActiveSheet()->getHighestDataColumn()){
        break;
    }
}

5
Vui lòng định dạng lại câu trả lời của bạn và suy nghĩ về điều này: Một câu trả lời hay sẽ luôn có lời giải thích về những gì đã được thực hiện và tại sao nó được thực hiện theo cách như vậy, không chỉ cho OP mà cho những khách truy cập sau này đến SO.
B001 ᛦ

1

Đối với spreedsheet + PHP 7, bạn phải viết thay vì PHPExcel_Cell::columnIndexFromString, \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString. Và tại vòng lặp là một sai lầm, ở đó bạn <không được làm việc với <=. Nếu không, anh ta lấy một cột quá nhiều vào vòng lặp.


1
// Auto-size columns for all worksheets
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
    foreach ($worksheet->getColumnIterator() as $column) {
        $worksheet
            ->getColumnDimension($column->getColumnIndex())
            ->setAutoSize(true);
    } 
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.