PHPExcel otomatik boyut sütun genişliği


104

Sayfamın sütunlarını otomatik olarak boyutlandırmaya çalışıyorum. Dosyayı yazıyorum ve sonunda tüm sütunlarımı yeniden boyutlandırmaya çalışıyorum.

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

Yukarıdaki kod çalışmıyor. Metne sığması için sütun boyutunu değiştirmez

GÜNCELLEME Kullandığım yazar$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

Yanıtlar:


199

Bir sütun Otomatik Boyutlandır'a ayarlanmışsa, PHPExcel, sütunun hesaplanan değerine (yani herhangi bir formülün sonucuna göre) ve bin ayırıcı gibi biçim maskeleri tarafından eklenen tüm ek karakterlere göre sütun genişliğini hesaplamaya çalışır.

Varsayılan olarak, bu bir estimatedgenişliktir: GD'yi temel alan, kalın ve italik gibi yazı tipi stili özelliklerini de işleyebilen daha doğru bir hesaplama yöntemi mevcuttur; ancak bu çok daha büyük bir ek yüktür, bu nedenle varsayılan olarak kapalıdır. Daha doğru hesaplamayı kullanarak etkinleştirebilirsiniz.

PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

Ancak, otomatik boyutlandırma tüm Writer biçimleri için geçerli değildir ... örneğin CSV. Hangi yazarı kullandığından bahsetmiyorsun.

Ancak boyutları ayarlamak için sütunları da tanımlamanız gerekir:

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

$objPHPExcel->getActiveSheet()->getColumnDimension() bir sütun kimliği bekler.

$objPHPExcel->getActiveSheet()->getColumnDimensions()tanımlanmış tüm sütun boyut kayıtlarının bir dizisini döndürür; ancak bir sütun boyutu kaydı açıkça yaratılmadıkça (belki bir şablon yükleyerek veya manuel olarak çağırarak getColumnDimension()) mevcut olmayacaktır (bellek tasarrufu).


Çok teşekkür ederim. İşe yarıyor. Beklendiği halde (bir yerde okudum) kalın yazı tipinden oluşturulan ekstra aralığı hesaplamaz. Cevabınızı bunu da içerecek şekilde güncelleyebilir misiniz?
Alkis Kalogeris

1
Kalın veya italik gibi yazı tipi stilinde bu hassasiyet derecesine ihtiyacınız varsa, PHPExcel_Shared_Font :: AUTOSIZE_METHOD_EXACT kullanmanız gerekir, ancak bu çok daha yavaştır
Mark Baker

Tamam, umrumda değil. Nasıl yapılacağını bilmesem de. Test klasöründeki 01simple-download-xls.php dosyasını kullanıyorum. Bu satırı nereye eklerim? Hiç suskunluğum için özür dilerim. Onunla oynamaya yeni başladım.
Alkis Kalogeris

2
Ayrıca, sütun harfleri yerine dizinlerle yineleme yapmak istemiyorsanız, sütun harfini almak için PHPExcel_Cell :: stringFromColumnIndex ($ columnIndex) statik yöntemini kullanabilirsiniz
MeatPopsicle

@MarkBaker Bir listede verilen sütunların genişliğini ayarlayabilmemiz için tek bir ifadeyle yapılabilecek herhangi bir yöntem var mı? Şu anda $ activeSheetObj-> getColumnDimension ('G') -> setWidth (35); listedeki sütunlar herhangi bir sırada olabilir.
Rosa Mystica

55

Bunu birden çok sayfada ve her sayfada birden çok sütunda yapmanız gerekiyorsa, bunların hepsini nasıl yineleyebileceğiniz aşağıda açıklanmıştır:

// 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'yi geçen sütunlar için özel bir değerlendirme gerektirmediğinden bu daha iyi bir çözüm.
Anthony

2
Bu cevabın PhpSpreadSheet'te de kusursuz çalıştığını doğrulayabilirim. Çok teşekkürler!
Hissvard

$worksheet->getColumnIterator()Burada işleri basitleştirmek için kullanın .
Cevabıma

25

İşte @Mark Baker gönderisine dayanan daha esnek bir varyant:

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

Bu yardımcı olur umarım ;)


14
Bu yalnızca Z'ye kadar çalışır, çünkü range('A', 'AB')yalnızca 'A' adlı bir öğe döndürür. range()Bu durumda kullanmak iyi bir fikir DEĞİLDİR!
Michael

7
Yine de bu çalışır: for ($ i = 'A'; $ i! = $ PhpExcelObject-> getActiveSheet () -> getHighestColumn (); $ i ++) {$ çalışma sayfası-> getColumnDimension ($ i) -> setAutoSize (TRUE); }
Nathan

Bunu kullanmayın. Lütfen $sheet->getColumnIterator()
BARNZ'ı

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

3
iyi cevap, ancak $i <= $objPHPExcel->getActiveSheet()->getHighestColumn()aksi takdirde son sütun boyutlandırılmamalıdır
billynoah

10

Bu, çalışma sayfasındaki tüm sütunların nasıl kullanılacağı örneğidir:

$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
Sorunu nasıl çözdüğünü açıklamak için lütfen cevabınıza biraz bağlam ekleyin
Andrew Stubbs

7

phpspreadsheet için:

$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 yorumunuz yalnızca 26'dan fazla sütun olmadığında çalışacaktır. En yüksek sütun örneğin: 'AH' olduğunda, aralık işlevi düzgün çalışmayacaktır.
Sander Van Keer

6

Bu kod parçacığı, tüm sayfalardaki verileri içeren tüm sütunları otomatik olarak boyutlandıracaktır. ActiveSheet alıcı ve ayarlayıcı kullanmaya gerek yoktur.

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

3

Birinin bunu araması durumunda.

Aşağıdaki çözüm PHPSpreadsheet, yeni PHPExcel sürümünde de çalışıyor.

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

Not: veya son gerçek sütun getHighestColumn()ile değiştirilebilir getHighestDataColumn().

Bu yöntemler ne işe yarar:

getHighestColumn($row = null) - En yüksek çalışma sayfası sütununu alın.

getHighestDataColumn($row = null) - Verileri içeren en yüksek çalışma sayfası sütununu alın.

getHighestRow($column = null) - En yüksek çalışma sayfası satırını alın

getHighestDataRow($column = null) - Veri içeren en yüksek çalışma sayfası satırını alın.


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

2

İle for ($col = 2; $col <= 'AC'; ++ $col){...}veya onunla yinelemeye çalışırsanız , foreach(range('A','AC') as $col) {...}A'dan Z'ye sütunlar için çalışacaktır, ancak Z'yi geçemeyecektir (Örn. 'A'dan' AC'ye kadar yineleme).

'Z' geçişini yinelemek için, sütunu tam sayıya dönüştürmeniz, artırmanız, karşılaştırmanız ve tekrar dize olarak almanız gerekir:

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

Bununla, kolay yineleme 'Z' sütununu geçirir ve her sütuna otomatik boyutlandırmayı ayarlarsınız.


1

Geç gelin, ancak her yerde aradıktan sonra, "tek" gibi görünen bir çözüm yarattım.

Son API sürümlerinde bir sütun yineleyici olduğu biliniyor, ancak sütun nesnesini kendi kendine nasıl ayarlayacağını bilmediğim için, temelde gerçek ilk kullanılan sütundan gerçek son kullanılan sütuna gitmek için bir döngü oluşturdum.

İşte gidiyor:

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

1

Tüm bu cevaplar berbat ... range () kullanmayın, Z sütununun ötesinde çalışmaz.

Basitçe şunu kullanın:

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

Bunu, verilerinizi yazdıktan sonra yapın, böylece sütun yineleyici kaç sütun üzerinde yineleme yapacağını bilir.


0

ayrıca boyutları ayarlamak için sütunları tanımlamanız gerekir:

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
Lütfen cevabınızı yeniden biçimlendirin ve şunu düşünün: İyi bir cevap her zaman ne yapıldığı ve neden bu şekilde yapıldığına dair bir açıklamaya sahip olacaktır, sadece OP için değil, aynı zamanda SO'ya gelecek ziyaretçiler için de.
B001 ᛦ

0

E-tabloda + PHP 7 için, yerine yazmalıdır PHPExcel_Cell::columnIndexFromString, \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString. Ve döngüde bir hata var, orada <çalışmamalısın <=. Aksi takdirde, bir sütunu döngü içine çok fazla alır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.