Lebar kolom ukuran otomatis PHPExcel

100

Saya mencoba mengubah ukuran kolom lembar saya secara otomatis. Saya sedang menulis file dan pada akhirnya saya mencoba mengubah ukuran semua kolom saya.

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

Kode di atas tidak berfungsi. Tidak mengubah ukuran kolom agar pas dengan teks

UPDATE Penulis yang saya gunakan$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

Alkis Kalogeris
sumber

Jawaban:

195

Jika kolom diatur ke Ukuran Otomatis, PHPExcel mencoba menghitung lebar kolom berdasarkan nilai kolom yang dihitung (jadi pada hasil rumus apa pun), dan karakter tambahan apa pun yang ditambahkan oleh masker format seperti seribu pemisah.

Secara default, ini adalah estimatedlebar: metode penghitungan yang lebih akurat tersedia, berdasarkan penggunaan GD, yang juga dapat menangani fitur gaya font seperti tebal dan miring; tapi ini adalah overhead yang jauh lebih besar, jadi ini dimatikan secara default. Anda dapat mengaktifkan penghitungan yang lebih akurat menggunakan

PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

Namun, ukuran otomatis tidak berlaku untuk semua format Penulis ... misalnya CSV. Anda tidak menyebutkan penulis apa yang Anda gunakan.

Tetapi Anda juga perlu mengidentifikasi kolom untuk mengatur dimensi:

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

$objPHPExcel->getActiveSheet()->getColumnDimension() mengharapkan ID kolom.

$objPHPExcel->getActiveSheet()->getColumnDimensions()akan mengembalikan larik dari semua catatan dimensi kolom yang ditentukan; tetapi kecuali catatan dimensi kolom telah dibuat secara eksplisit (mungkin dengan memuat template, atau dengan memanggil secara manual getColumnDimension()) maka itu tidak akan ada (penghematan memori).

Mark Baker
sumber
Terima kasih banyak. Berhasil. Itu tidak menghitung jarak ekstra yang dibuat dari font tebal, meskipun itu diharapkan (saya telah membacanya di suatu tempat). Bisakah Anda memperbarui jawaban Anda untuk memasukkan itu juga?
Alkis Kalogeris
1
Jika Anda membutuhkan tingkat presisi dengan gaya jenis huruf seperti tebal atau miring, maka Anda perlu menggunakan PHPExcel_Shared_Font :: AUTOSIZE_METHOD_EXACT, tetapi ini jauh lebih lambat
Mark Baker
Tidak apa-apa, saya tidak peduli. Meskipun saya tidak tahu bagaimana melakukannya. Saya menggunakan 01simple-download-xls.php dari folder Test. Di mana saya menambahkan baris itu? Maaf atas noobness saya yang lengkap. Saya baru saja mulai bermain dengannya.
Alkis Kalogeris
2
Selain itu, Jika Anda tidak ingin mengulang melalui huruf kolom tetapi indeks, Anda dapat menggunakan metode statis PHPExcel_Cell :: stringFromColumnIndex ($ columnIndex) untuk mendapatkan huruf kolom
MeatPopsicle
@MarkBaker Apakah ada metode yang tersedia untuk dilakukan dengan satu pernyataan sehingga kita dapat mengatur lebar kolom yang diberikan dalam daftar. Saat ini saya menggunakan $ activeSheetObj-> getColumnDimension ('G') -> setWidth (35); kolom dalam daftar dapat berurutan apa saja.
Rosa Mystica
55

Jika Anda perlu melakukannya di beberapa lembar, dan beberapa kolom di setiap lembar, berikut adalah cara Anda dapat mengulang semuanya:

// 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);
    }
}
MrUpsidown
sumber
7
Ini adalah solusi yang lebih baik, karena tidak memerlukan pertimbangan khusus untuk kolom setelah Z.
Anthony
2
Saya dapat mengonfirmasi bahwa jawaban ini juga berfungsi dengan sempurna di PhpSpreadSheet. Terima kasih banyak!
Hissvard
23

Berikut varian yang lebih fleksibel berdasarkan postingan @Mark Baker:

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

Semoga ini membantu ;)

Todor Todorov
sumber
14
Ini hanya berfungsi sampai Z, karena range('A', 'AB')hanya akan mengembalikan satu item bernama 'A'. Jadi menggunakan range()dalam kasus ini BUKAN ide yang bagus!
Michael
7
Ini berfungsi: untuk ($ 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);
}
Nathan
sumber
2
jawaban yang bagus tetapi harus $i <= $objPHPExcel->getActiveSheet()->getHighestColumn()sebaliknya, kolom terakhir tidak berukuran
billynoah
10

Ini adalah contoh bagaimana menggunakan semua kolom dari lembar kerja:

$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 );
}
dmi3x.dll
sumber
3
Harap tambahkan beberapa konteks di sekitar jawaban Anda untuk menjelaskan bagaimana ini memecahkan masalah
Andrew Stubbs
6

Potongan kode ini akan secara otomatis mengukur semua kolom yang berisi data di semua lembar. Tidak perlu menggunakan pengambil dan penyetel 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);
    }
}
Ronnie
sumber
6

untuk 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);
}
beck kuo
sumber
foreach (range('A', $sheet->getHighestDataColumn()) as $column) {$sheet->getColumnDimension($column)->setAutoSize(true);}
Wesley Abbenhuis
1
@WesleyAbbenhuis, komentar Anda hanya akan berfungsi jika tidak ada lebih dari 26 kolom. Ketika kolom tertinggi misalnya: 'AH' fungsi range tidak akan bekerja dengan baik.
Sander Van Keer
3
foreach(range('B','G') as $columnID)
{
    $objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setAutoSize(true);
}
Sadikhasan
sumber
3

Seandainya seseorang mencari ini.

Resolusi di bawah ini juga berfungsi PHPSpreadsheet, versi baru PHPExcel mereka.

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

Catatan: getHighestColumn()dapat diganti dengan getHighestDataColumn()atau kolom aktual terakhir.

Apa yang dilakukan metode ini:

getHighestColumn($row = null) - Dapatkan kolom lembar kerja tertinggi.

getHighestDataColumn($row = null) - Dapatkan kolom lembar kerja tertinggi yang berisi data.

getHighestRow($column = null) - Dapatkan baris lembar kerja tertinggi

getHighestDataRow($column = null) - Dapatkan baris lembar kerja tertinggi yang berisi data.

Gabi Dj
sumber
2

Jika Anda mencoba untuk mengulang dengan for ($col = 2; $col <= 'AC'; ++ $col){...}, atau dengan foreach(range('A','AC') as $col) {...}itu akan bekerja untuk kolom dari A ke Z, tetapi gagal melewati Z (Mis. Iterasi antara 'A' ke 'AC').

Untuk mengulang pass 'Z', Anda perlu mengonversi kolom menjadi integer, increment, bandingkan, dan dapatkan lagi sebagai string:

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

Dengan ini, Anda dapat dengan mudah mengulangi kolom 'Z' dan mengatur ukuran otomatis ke setiap kolom.

Alejandro Silva
sumber
1

Datang terlambat, tetapi setelah mencari di mana-mana, saya telah membuat solusi yang tampaknya "satu-satunya".

Diketahui bahwa ada iterator kolom pada versi API terakhir, tetapi tidak tahu bagaimana cara menyesuaikan objek kolom itu sendiri, pada dasarnya saya telah membuat loop untuk beralih dari kolom yang pertama digunakan yang sebenarnya ke yang terakhir digunakan yang sebenarnya.

Ini dia:

//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');
Lightworker
sumber
1

Anda juga perlu mengidentifikasi kolom untuk mengatur dimensi:

foreach (range('A', $phpExcelObject->getActiveSheet()->getHighestDataColumn()) as $col) {
$phpExcelObject
        ->getActiveSheet()
        ->getColumnDimension($col)
        ->setAutoSize(true);
}
Bhavik Hirani
sumber
1
$col = 'A';
while(true){
    $tempCol = $col++;
    $objPHPExcel->getActiveSheet()->getColumnDimension($tempCol)->setAutoSize(true);
    if($tempCol == $objPHPExcel->getActiveSheet()->getHighestDataColumn()){
        break;
    }
}
Prashant Khanderia
sumber
5
Harap format ulang jawaban Anda dan pikirkan tentang ini: Jawaban yang baik akan selalu memiliki penjelasan tentang apa yang telah dilakukan dan mengapa dilakukan sedemikian rupa, tidak hanya untuk OP tetapi untuk pengunjung SO di masa mendatang.
B001 ᛦ
1

Untuk spreedsheet + PHP 7, Anda harus menulis bukan PHPExcel_Cell::columnIndexFromString, \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString. Dan di loop adalah kesalahan, di sana Anda <tidak boleh bekerja dengannya <=. Jika tidak, dia mengambil kolom terlalu banyak ke dalam loop.

GSI One
sumber
1
// Auto-size columns for all worksheets
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
    foreach ($worksheet->getColumnIterator() as $column) {
        $worksheet
            ->getColumnDimension($column->getColumnIndex())
            ->setAutoSize(true);
    } 
}
Gyrocode.com
sumber