Largeur de colonne de taille automatique PHPExcel


101

J'essaye de dimensionner automatiquement les colonnes de ma feuille. J'écris le fichier et à la fin j'essaye de redimensionner toutes mes colonnes.

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

Le code ci-dessus ne fonctionne pas. Ne modifie pas la taille de la colonne pour l'adapter au texte

MISE À JOUR L'écrivain que j'utilise$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

Réponses:


195

Si une colonne est définie sur Taille automatique, PHPExcel tente de calculer la largeur de la colonne en fonction de la valeur calculée de la colonne (donc du résultat de toutes les formules) et de tout caractère supplémentaire ajouté par des masques de format tels que mille séparateurs.

Par défaut, il s'agit d'une estimatedlargeur: une méthode de calcul plus précise est disponible, basée sur l'utilisation de GD, qui peut également gérer les fonctionnalités de style de police telles que le gras et l'italique; mais il s'agit d'une surcharge beaucoup plus importante, elle est donc désactivée par défaut. Vous pouvez activer le calcul plus précis en utilisant

PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

Cependant, la taille automatique ne s'applique pas à tous les formats Writer ... par exemple CSV. Vous ne mentionnez pas quel écrivain vous utilisez.

Mais vous devez également identifier les colonnes pour définir les dimensions:

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

$objPHPExcel->getActiveSheet()->getColumnDimension() attend un ID de colonne.

$objPHPExcel->getActiveSheet()->getColumnDimensions()renverra un tableau de tous les enregistrements de dimension de colonne définis; mais à moins qu'un enregistrement de dimension de colonne n'ait été explicitement créé (peut-être en chargeant un modèle ou en appelant manuellement getColumnDimension()), il n'existera pas (économie de mémoire).


Merci beaucoup. Ça marche. Il ne calcule pas l'espacement supplémentaire créé à partir de la police en gras, bien que cela soit attendu (je l'ai lu quelque part). Pourriez-vous mettre à jour votre réponse pour inclure cela aussi?
Alkis Kalogeris

1
Si vous avez besoin de ce degré de précision avec un style de police tel que gras ou italique, vous devez utiliser PHPExcel_Shared_Font :: AUTOSIZE_METHOD_EXACT, mais c'est beaucoup plus lent
Mark Baker

C'est bon, je m'en fiche. Bien que je ne sache pas comment faire. J'utilise le 01simple-download-xls.php du dossier Test. Où ajouter cette ligne? Désolé pour ma noobness complète. Je viens de commencer à jouer avec.
Alkis Kalogeris

2
De plus, si vous ne voulez pas itérer via des lettres de colonne mais des index à la place, vous pouvez utiliser la méthode statique PHPExcel_Cell :: stringFromColumnIndex ($ columnIndex) pour obtenir la lettre de la colonne
MeatPopsicle

@MarkBaker Existe-t-il une méthode disponible à faire avec une seule instruction afin que nous puissions définir la largeur des colonnes données dans une liste. Actuellement, j'utilise $ activeSheetObj-> getColumnDimension ('G') -> setWidth (35); les colonnes de la liste peuvent être de n'importe quel ordre.
Rosa Mystica

55

Si vous devez le faire sur plusieurs feuilles et plusieurs colonnes dans chaque feuille, voici comment vous pouvez les parcourir toutes:

// 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
C'est la meilleure solution, car elle ne nécessite pas de considération particulière pour les colonnes au-delà de Z.
Anthony

2
Je peux confirmer que cette réponse fonctionne parfaitement dans PhpSpreadSheet également. Merci beaucoup!
Hissvard

Utilisez $worksheet->getColumnIterator()pour simplifier les choses ici. Reportez-vous à ma réponse
BARNZ

23

Voici une variante plus flexible basée sur le post de @Mark Baker:

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

J'espère que cela t'aides ;)


14
Cela ne fonctionne que jusqu'à Z, car range('A', 'AB')ne retournera qu'un seul élément nommé 'A'. Donc utiliser range()dans ce cas n'est PAS une bonne idée!
Michael

7
Cela fonctionne cependant: for ($ i = 'A'; $ i! = $ PhpExcelObject-> getActiveSheet () -> getHighestColumn (); $ i ++) {$ worksheet-> getColumnDimension ($ i) -> setAutoSize (TRUE); }
Nathan

Ne l'utilisez pas. S'il vous plaît voir ma réponse qui utilise le$sheet->getColumnIterator()
BARNZ

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

3
bonne réponse mais devrait être $i <= $objPHPExcel->getActiveSheet()->getHighestColumn()sinon la dernière colonne ne prend pas la taille
billynoah

10

Voici un exemple comment utiliser toutes les colonnes de la feuille de calcul:

$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
Veuillez ajouter un peu de contexte autour de votre réponse pour expliquer comment cela résout le problème
Andrew Stubbs

6

Cet extrait de code dimensionnera automatiquement toutes les colonnes contenant des données dans toutes les feuilles. Il n'est pas nécessaire d'utiliser le getter et le 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

pour 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 votre commentaire ne fonctionnera que s'il n'y a pas plus de 26 colonnes. Lorsque la colonne la plus élevée est par exemple: «AH», la fonction de plage ne fonctionnera pas correctement.
Sander Van Keer

3

Au cas où quelqu'un chercherait ça.

La résolution ci-dessous fonctionne également sur PHPSpreadsheetleur nouvelle version de 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);
}

Remarque: getHighestColumn()peut être remplacé par getHighestDataColumn()ou la dernière colonne réelle.

Que font ces méthodes:

getHighestColumn($row = null) - Obtenez la colonne de feuille de calcul la plus élevée.

getHighestDataColumn($row = null) - Obtenez la colonne de feuille de calcul la plus élevée contenant des données.

getHighestRow($column = null) - Obtenez la ligne de feuille de calcul la plus élevée

getHighestDataRow($column = null) - Obtenez la ligne de feuille de calcul la plus élevée contenant des données.


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

2

Si vous essayez d'itérer avec for ($col = 2; $col <= 'AC'; ++ $col){...}, ou avec foreach(range('A','AC') as $col) {...}cela fonctionnera pour les colonnes de A à Z, mais cela échoue, passez le Z (ex. Itérer entre 'A' et 'AC').

Pour parcourir la passe 'Z', vous devez convertir la colonne en entier, incrémenter, comparer et la récupérer sous forme de chaîne:

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

Avec cela, vous pouvez facilement parcourir la colonne «Z» et définir la taille automatique pour chaque colonne.


1

Arrivez tard, mais après avoir cherché partout, j'ai créé une solution qui semble être "la bonne".

Sachant qu'il existe un itérateur de colonne sur les dernières versions de l'API, mais ne sachant pas comment ajuster l'objet colonne lui-même, j'ai essentiellement créé une boucle pour passer de la première colonne utilisée à la dernière colonne utilisée.

Voilà:

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

vous devez également identifier les colonnes pour définir les dimensions:

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
Veuillez reformater votre réponse et réfléchir à ceci: Une bonne réponse aura toujours une explication de ce qui a été fait et pourquoi cela a été fait de cette manière, non seulement pour le PO mais pour les futurs visiteurs de SO.
B001 ᛦ

0

Pour Spreedsheet + PHP 7, vous devez écrire au lieu de PHPExcel_Cell::columnIndexFromString, \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString. Et à la boucle est une erreur, là, vous <ne devez pas travailler avec <=. Sinon, il prend trop une colonne dans la boucle.


0

Toutes ces réponses sont un peu nulles ... n'utilisez pas range () cela ne fonctionnera pas au-delà de la colonne Z.

Utilisez simplement:

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

Faites cela après avoir écrit vos données afin que l'itérateur de colonne sache combien de colonnes il doit parcourir.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.