Larghezza colonna dimensione automatica PHPExcel


100

Sto cercando di ridimensionare automaticamente le colonne del mio foglio. Sto scrivendo il file e alla fine provo a ridimensionare tutte le mie colonne.

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

Il codice sopra non funziona. Non modifica la dimensione della colonna per adattarla al testo

AGGIORNAMENTO Lo scrittore che sto utilizzando$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

Risposte:


195

Se una colonna è impostata su AutoSize, PHPExcel tenta di calcolare la larghezza della colonna in base al valore calcolato della colonna (quindi sul risultato di qualsiasi formula) e qualsiasi carattere aggiuntivo aggiunto da maschere di formato come mille separatori.

Per impostazione predefinita, questa è una estimatedlarghezza: è disponibile un metodo di calcolo più accurato, basato sull'utilizzo di GD, che può anche gestire caratteristiche di stile dei caratteri come grassetto e corsivo; ma questo è un sovraccarico molto più grande, quindi è disattivato per impostazione predefinita. È possibile abilitare il calcolo più accurato utilizzando

PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

Tuttavia, la dimensione automatica non si applica a tutti i formati di Writer ... ad esempio CSV. Non dici quale scrittore stai usando.

Ma devi anche identificare le colonne per impostare le dimensioni:

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

$objPHPExcel->getActiveSheet()->getColumnDimension() si aspetta un ID colonna.

$objPHPExcel->getActiveSheet()->getColumnDimensions()restituirà un array di tutti i record di dimensione di colonna definiti; ma a meno che un record di dimensione di colonna non sia stato creato esplicitamente (magari caricando un modello o chiamando manualmente getColumnDimension()), allora non esisterà (risparmio di memoria).


Grazie mille. Funziona. Non calcola la spaziatura aggiuntiva creata dal carattere in grassetto, sebbene sia previsto (l'ho letto da qualche parte). Potresti aggiornare la tua risposta per includere anche quella?
Alkis Kalogeris

1
Se hai bisogno di quel grado di precisione con lo stile del carattere come grassetto o corsivo, devi usare PHPExcel_Shared_Font :: AUTOSIZE_METHOD_EXACT, ma è molto più lento
Mark Baker

Va bene, non mi interessa. Anche se non so come farlo. Sto usando 01simple-download-xls.php dalla cartella Test. Dove aggiungo quella riga? Mi dispiace per la mia totale noia. Ho appena iniziato a giocarci.
Alkis Kalogeris

2
Inoltre, se non si desidera iterare tramite lettere di colonna ma indici, è possibile utilizzare il metodo statico PHPExcel_Cell :: stringFromColumnIndex ($ columnIndex) per ottenere la lettera della colonna
MeatPopsicle

@MarkBaker Esiste un metodo disponibile per eseguire una singola istruzione in modo da poter impostare la larghezza delle colonne fornite in un elenco. Attualmente sto usando $ activeSheetObj-> getColumnDimension ('G') -> setWidth (35); le colonne nell'elenco possono essere di qualsiasi ordine.
Rosa Mystica

55

Se hai bisogno di farlo su più fogli e più colonne in ogni foglio, ecco come puoi scorrere tutti loro:

// 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
Questa è la soluzione migliore, poiché non richiede una considerazione speciale per le colonne oltre Z.
Anthony

2
Posso confermare che questa risposta funziona perfettamente anche in PhpSpreadSheet. Grazie mille!
Hissvard

23

Ecco una variante più flessibile basata sul post di @Mark Baker:

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

Spero che questo ti aiuti ;)


14
Questo funziona solo fino a Z, perché range('A', 'AB')restituirà solo un elemento denominato "A". Quindi l'utilizzo range()in questo caso NON è una buona idea!
Michael

7
Funziona però: for ($ i = 'A'; $ i! = $ PhpExcelObject-> getActiveSheet () -> getHighestColumn (); $ i ++) {$ foglio di lavoro-> getColumnDimension ($ i) -> setAutoSize (TRUE); }
Nathan

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

2
buona risposta ma dovrebbe essere $i <= $objPHPExcel->getActiveSheet()->getHighestColumn()altrimenti l'ultima colonna non viene dimensionata
billynoah

10

Questo è un esempio di come utilizzare tutte le colonne dal foglio di lavoro:

$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
Aggiungi un contesto alla tua risposta per spiegare come risolve il problema
Andrew Stubbs

6

Questo frammento di codice ridimensionerà automaticamente tutte le colonne che contengono dati in tutti i fogli. Non è necessario utilizzare getter e setter 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

per 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 il tuo commento funzionerà solo quando non ci sono più di 26 colonne. Quando la colonna più alta è ad esempio: "AH", la funzione di intervallo non funzionerà correttamente.
Sander Van Keer,

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

3

Nel caso qualcuno lo stesse cercando.

La risoluzione seguente funziona anche sulla PHPSpreadsheetloro nuova versione di 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);
}

Nota: getHighestColumn()può essere sostituito con getHighestDataColumn()o con l'ultima colonna effettiva.

Cosa fanno questi metodi:

getHighestColumn($row = null) - Ottieni la colonna del foglio di lavoro più alta.

getHighestDataColumn($row = null) - Ottieni la colonna del foglio di lavoro più alta che contiene dati.

getHighestRow($column = null) - Ottieni la riga più alta del foglio di lavoro

getHighestDataRow($column = null) - Ottieni la riga più alta del foglio di lavoro che contiene dati.


2

Se provi a iterare con for ($col = 2; $col <= 'AC'; ++ $col){...}o conforeach(range('A','AC') as $col) {...} esso funzionerà per le colonne dalla A alla Z, ma non riesce a passare la Z (es. Iterare tra "A" e "AC").

Per iterare il passaggio 'Z', è necessario convertire la colonna in numero intero, incrementare, confrontare e ottenerlo di nuovo come stringa:

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

Con questo, puoi facilmente iterare, passare la colonna "Z" e impostare la dimensione automatica per ogni colonna.


1

Arriva tardi, ma dopo aver cercato ovunque, ho creato una soluzione che sembra essere "quella giusta".

Essendo noto che esiste un iteratore di colonna sulle ultime versioni dell'API, ma non sapendo come regolare l'oggetto colonna da solo, in pratica ho creato un ciclo per passare dalla colonna utilizzata per la prima volta a quella utilizzata per ultima.

Eccolo:

//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

devi anche identificare le colonne per impostare le dimensioni:

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
Per favore riformatta la tua risposta e pensa a questo: una buona risposta avrà sempre una spiegazione di cosa è stato fatto e perché è stato fatto in questo modo, non solo per l'OP ma per i futuri visitatori di SO.
B001 ᛦ

1

Per spreedsheet + PHP 7, è necessario scrivere al posto di PHPExcel_Cell::columnIndexFromString, \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString. E al loop c'è un errore, lì non devi <lavorare <=. Altrimenti, prende una colonna troppo nel ciclo.


1
// Auto-size columns for all worksheets
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
    foreach ($worksheet->getColumnIterator() as $column) {
        $worksheet
            ->getColumnDimension($column->getColumnIndex())
            ->setAutoSize(true);
    } 
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.