Ширина столбца автоматического размера PHPExcel


101

Я пытаюсь автоматически изменить размер столбцов на моем листе. Я пишу файл и, в конце концов, пытаюсь изменить размер всех своих столбцов.

// 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();

Приведенный выше код не работает. Не меняет размер столбца под текст

ОБНОВЛЕНИЕ Автор, который я использую$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

Ответы:


195

Если для столбца задано значение AutoSize, PHPExcel пытается вычислить ширину столбца на основе вычисленного значения столбца (то есть результата любых формул) и любых дополнительных символов, добавленных масками формата, такими как разделители тысяч.

По умолчанию это estimatedширина: доступен более точный метод расчета, основанный на использовании GD, который также может обрабатывать такие особенности стиля шрифта, как полужирный и курсив; но это гораздо большие накладные расходы, поэтому по умолчанию он отключен. Вы можете включить более точный расчет, используя

PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

Однако автоматическое изменение размера применяется не ко всем форматам Writer ... например, CSV. Вы не упоминаете, какой писатель вы используете.

Но вам также необходимо определить столбцы для установки размеров:

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

$objPHPExcel->getActiveSheet()->getColumnDimension() ожидает идентификатор столбца.

$objPHPExcel->getActiveSheet()->getColumnDimensions()вернет массив всех определенных записей измерений столбца; но если запись измерения столбца не была явно создана (возможно, путем загрузки шаблона или ручного вызова getColumnDimension()), она не будет существовать (экономия памяти).


Огромное спасибо. Оно работает. Он не вычисляет дополнительный интервал, созданный жирным шрифтом, хотя это и ожидается (я где-то читал). Не могли бы вы обновить свой ответ, включив и это?
Алкис Калогерис

1
Если вам нужна такая степень точности со стилем шрифта, например полужирным или курсивом, тогда вам нужно использовать PHPExcel_Shared_Font :: AUTOSIZE_METHOD_EXACT, но он намного медленнее,
Марк Бейкер

Все нормально, мне все равно. Хотя не знаю, как это сделать. Я использую 01simple-download-xls.php из папки Test. Где мне добавить эту строку? Извините за мою полную глупость. Я только начал с этим играть.
Алкис Калогерис

2
Кроме того, если вы не хотите выполнять итерацию по буквам столбца, а по индексам, вы можете использовать статический метод PHPExcel_Cell :: stringFromColumnIndex ($ columnIndex) для получения буквы столбца
MeatPopsicle

@MarkBaker Есть ли какой-либо метод, который можно использовать с одним оператором, чтобы мы могли установить ширину столбцов, указанных в списке. В настоящее время я использую $ activeSheetObj-> getColumnDimension ('G') -> setWidth (35); столбцы в списке могут иметь любой порядок.
Rosa Mystica

55

Если вам нужно сделать это на нескольких листах и ​​в нескольких столбцах на каждом листе, вот как вы можете перебирать все из них:

// 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
Это лучшее решение, поскольку оно не требует особого внимания к столбцам после Z.
Энтони

2
Я могу подтвердить, что этот ответ безупречно работает и в PhpSpreadSheet. Благодаря тонну!
Hissvard 03

Используйте здесь $worksheet->getColumnIterator()для упрощения. Обратитесь к моему ответу
BARNZ

23

Вот более гибкий вариант, основанный на публикации @Mark Baker:

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

Надеюсь это поможет ;)


14
Это работает только до Z, потому что range('A', 'AB')вернет только один элемент с именем «A». Так что использование range()в этом случае НЕ является хорошей идеей!
Майкл

7
Однако это работает: for ($ i = 'A'; $ i! = $ PhpExcelObject-> getActiveSheet () -> getHighestColumn (); $ i ++) {$ worksheet-> getColumnDimension ($ i) -> setAutoSize (TRUE); }
Натан

Не используйте это. Пожалуйста, посмотрите мой ответ, в котором используется$sheet->getColumnIterator()
BARNZ

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

3
хороший ответ, но должен быть $i <= $objPHPExcel->getActiveSheet()->getHighestColumn()иначе размер последней колонки не
увеличивается

10

Это пример использования всех столбцов на листе:

$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
Пожалуйста, добавьте контекст вокруг своего ответа, чтобы объяснить, как он решает проблему
Эндрю Стаббс

6

Этот фрагмент кода автоматически изменит размер всех столбцов, содержащих данные, на всех листах. Нет необходимости использовать геттер и сеттер 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

для 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, ваш комментарий будет работать, только если в нем не более 26 столбцов. Когда самый высокий столбец, например: «AH», функция диапазона не будет работать должным образом.
Сандер Ван Кир,

3

На случай, если кто-то это искал.

Приведенное ниже разрешение также работает с PHPSpreadsheetих новой версией PHPExcel.

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

Примечание: getHighestColumn()можно заменить getHighestDataColumn()на последний фактический столбец или.

Что делают эти методы:

getHighestColumn($row = null) - Получите самый высокий столбец рабочего листа.

getHighestDataColumn($row = null) - Получите самый высокий столбец рабочего листа, содержащий данные.

getHighestRow($column = null) - Получить самую высокую строку рабочего листа

getHighestDataRow($column = null) - Получить самую высокую строку рабочего листа, содержащую данные.



2

Если вы попытаетесь выполнить итерацию с for ($col = 2; $col <= 'AC'; ++ $col){...}или с foreach(range('A','AC') as $col) {...}ним, он будет работать для столбцов от A до Z, но он не сможет передать Z (например, итерация между «A» и «AC»).

Чтобы повторить проход Z, вам нужно преобразовать столбец в целое число, увеличить, сравнить и снова получить его как строку:

$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);
}

Благодаря этому вы легко перебираете столбец «Z» и устанавливаете автоматический размер для каждого столбца.


1

Приходите поздно, но после поисков я нашел решение, которое кажется "единственным".

Зная, что в последних версиях API есть итератор столбца, но не зная, как самостоятельно настроить объект столбца, я создал цикл для перехода от реального первого использованного столбца к действительно последнему использованному.

Вот оно:

//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
// Auto-size columns for all worksheets
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
    foreach ($worksheet->getColumnIterator() as $column) {
        $worksheet
            ->getColumnDimension($column->getColumnIndex())
            ->setAutoSize(true);
    } 
}

0

вам также необходимо указать столбцы для установки размеров:

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

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

5
Пожалуйста, переформатируйте свой ответ и подумайте над этим: в хорошем ответе всегда будет объяснение того, что было сделано и почему это было сделано таким образом, не только для OP, но и для будущих посетителей SO.
B001 ᛦ

0

Для Spreedsheet + PHP 7, вы должны написать вместо PHPExcel_Cell::columnIndexFromString, \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString. А в шлейфе ошибка, там <работать не надо <=. В противном случае он слишком увлечет столбик в петлю.


0

Все эти ответы отстой ... не используйте range (), он не будет работать за пределами столбца Z.

Просто используйте:

$sheet = $spreadsheet->getActiveSheet();
foreach ($sheet->getColumnIterator() as $column) {
    $sheet->getColumnDimension($column->getColumnIndex())->setAutoSize(true);
}

Сделайте это после того, как вы записали свои данные, чтобы итератор столбцов знал, сколько столбцов нужно перебирать.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.