Spaltenbreite für die automatische Größe von PHPExcel


99

Ich versuche, die Spalten meines Blattes automatisch zu dimensionieren. Ich schreibe die Datei und versuche am Ende, die Größe aller meiner Spalten zu ändern.

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

Der obige Code funktioniert nicht. Ändert die Spaltengröße nicht an den Text

UPDATE Der Autor, den ich benutze$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

Antworten:


193

Wenn eine Spalte auf AutoSize eingestellt ist, versucht PHPExcel, die Spaltenbreite basierend auf dem berechneten Wert der Spalte (also auf dem Ergebnis von Formeln) und zusätzlichen Zeichen zu berechnen, die durch Formatmasken wie z. B. tausend Trennzeichen hinzugefügt werden.

Standardmäßig ist dies eine estimatedBreite: Basierend auf der Verwendung von GD steht eine genauere Berechnungsmethode zur Verfügung, die auch Schriftstilfunktionen wie Fett und Kursiv verarbeiten kann. Dies ist jedoch ein viel größerer Aufwand, daher ist er standardmäßig deaktiviert. Sie können die genauere Berechnung mit aktivieren

PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

Die automatische Größe gilt jedoch nicht für alle Writer-Formate, z. B. CSV. Sie erwähnen nicht, welchen Schriftsteller Sie verwenden.

Sie müssen jedoch auch die Spalten identifizieren, um die Abmessungen festzulegen:

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

$objPHPExcel->getActiveSheet()->getColumnDimension() erwartet eine Spalten-ID.

$objPHPExcel->getActiveSheet()->getColumnDimensions()gibt ein Array aller definierten Spaltendimensionsdatensätze zurück; Aber wenn ein Spaltendimensionsdatensatz nicht explizit erstellt wurde (möglicherweise durch Laden einer Vorlage oder durch manuelles Aufrufen getColumnDimension()), ist er nicht vorhanden (Speicherplatzersparnis).


Ich danke dir sehr. Es klappt. Es berechnet nicht den zusätzlichen Abstand, der aus der fetten Schrift erzeugt wird, obwohl dies erwartet wird (ich habe es irgendwo gelesen). Könnten Sie Ihre Antwort aktualisieren, um dies auch aufzunehmen?
Alkis Kalogeris

1
Wenn Sie diesen Grad an Präzision bei Schriftstilen wie Fett oder Kursiv benötigen, müssen Sie PHPExcel_Shared_Font :: AUTOSIZE_METHOD_EXACT verwenden, aber es ist viel langsamer
Mark Baker

Es ist in Ordnung, es ist mir egal. Obwohl ich nicht weiß, wie es geht. Ich verwende die 01simple-download-xls.php aus dem Testordner. Wo füge ich diese Zeile hinzu? Entschuldigung für meine völlige Noobness. Ich habe gerade angefangen damit zu spielen.
Alkis Kalogeris

2
Wenn Sie nicht über Spaltenbuchstaben, sondern über Indizes iterieren möchten, können Sie die statische Methode PHPExcel_Cell :: stringFromColumnIndex ($ columnIndex) verwenden, um den Spaltenbuchstaben
MeatPopsicle

@MarkBaker Gibt es eine Methode, die mit einer einzelnen Anweisung zu tun hat, damit wir die Breite der in einer Liste angegebenen Spalten festlegen können? Derzeit verwende ich $ activeSheetObj-> getColumnDimension ('G') -> setWidth (35); Die Spalten in der Liste können von beliebiger Reihenfolge sein.
Rosa Mystica

55

Wenn Sie dies für mehrere Blätter und mehrere Spalten in jedem Blatt tun müssen, können Sie alle folgenden Schritte durchlaufen:

// 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
Dies ist die bessere Lösung, da für Spalten nach Z keine besondere Berücksichtigung erforderlich ist.
Anthony

2
Ich kann bestätigen, dass diese Antwort auch in PhpSpreadSheet einwandfrei funktioniert. Danke vielmals!
Hissvard

22

Hier eine flexiblere Variante basierend auf @ Mark Baker Post:

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

Hoffe das hilft ;)


14
Dies funktioniert nur bis Z, da range('A', 'AB')nur ein Element mit dem Namen 'A' zurückgegeben wird. So verwendet range()in diesem Fall ist keine gute Idee!
Michael

7
Dies funktioniert jedoch: für ($ 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);
}

2
gute Antwort, sollte aber $i <= $objPHPExcel->getActiveSheet()->getHighestColumn()sonst sein letzte Spalte wird nicht dimensioniert
billynoah

10

Dies ist ein Beispiel für die Verwendung aller Spalten aus dem Arbeitsblatt:

$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
Bitte fügen Sie einen Kontext um Ihre Antwort hinzu, um zu erklären, wie das Problem gelöst wird
Andrew Stubbs

6

Dieses Code-Snippet passt automatisch alle Spalten an, die Daten in allen Blättern enthalten. Es ist nicht erforderlich, den ActiveSheet-Getter und -Setter zu verwenden.

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

für 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 Ihr Kommentar funktioniert nur, wenn nicht mehr als 26 Spalten vorhanden sind. Wenn die höchste Spalte beispielsweise "AH" lautet, funktioniert die Bereichsfunktion nicht ordnungsgemäß.
Sander Van Keer

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

3

Für den Fall, dass jemand danach suchte.

Die folgende Auflösung funktioniert auch mit PHPSpreadsheetder neuen Version von 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);
}

Hinweis: getHighestColumn()Kann durch getHighestDataColumn()oder die letzte tatsächliche Spalte ersetzt werden.

Was diese Methoden tun:

getHighestColumn($row = null) - Holen Sie sich die höchste Arbeitsblattspalte.

getHighestDataColumn($row = null) - Holen Sie sich die höchste Arbeitsblattspalte, die Daten enthält.

getHighestRow($column = null) - Holen Sie sich die höchste Arbeitsblattzeile

getHighestDataRow($column = null) - Holen Sie sich die höchste Arbeitsblattzeile, die Daten enthält.


2

Wenn Sie versuchen, mit for ($col = 2; $col <= 'AC'; ++ $col){...}oder mit zu iterieren , foreach(range('A','AC') as $col) {...}funktioniert dies für Spalten von A bis Z, aber es schlägt fehl, das Z zu übergeben (z. B. zwischen 'A' und 'AC' iterieren).

Um den Durchgang 'Z' zu wiederholen, müssen Sie die Spalte in eine Ganzzahl konvertieren, inkrementieren, vergleichen und erneut als Zeichenfolge abrufen:

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

Mit dieser Funktion können Sie die 'Z'-Spalte einfach iterieren und die automatische Größe für jede Spalte festlegen.


1

Kommen Sie spät, aber nachdem ich überall gesucht habe, habe ich eine Lösung geschaffen, die "die eine" zu sein scheint.

Da bekannt ist, dass es in den letzten API-Versionen einen Spalteniterator gibt, aber nicht weiß, wie das Spaltenobjekt selbst angepasst werden kann, habe ich im Grunde eine Schleife erstellt, um von der zuerst verwendeten Spalte zu der zuletzt verwendeten Spalte zu wechseln.

Hier kommt's:

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

Sie müssen auch die Spalten identifizieren, um die Abmessungen festzulegen:

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
Bitte formatieren Sie Ihre Antwort neu und denken Sie darüber nach: Eine gute Antwort enthält immer eine Erklärung darüber, was getan wurde und warum dies so getan wurde, nicht nur für das OP, sondern auch für zukünftige Besucher von SO.
B001

1

Für Spreedsheet + PHP 7 müssen Sie anstelle von PHPExcel_Cell::columnIndexFromString, \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString. Und an der Schleife liegt ein Fehler, mit dem man <nicht arbeiten darf <=. Andernfalls nimmt er eine Spalte zu viel in die Schleife.


1
// Auto-size columns for all worksheets
foreach ($objPHPExcel->getWorksheetIterator() as $worksheet) {
    foreach ($worksheet->getColumnIterator() as $column) {
        $worksheet
            ->getColumnDimension($column->getColumnIndex())
            ->setAutoSize(true);
    } 
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.