ความกว้างของคอลัมน์ขนาดอัตโนมัติ PHPExcel


104

ฉันกำลังพยายามปรับขนาดคอลัมน์ของแผ่นงานโดยอัตโนมัติ ฉันกำลังเขียนไฟล์และในที่สุดฉันก็พยายามปรับขนาดคอลัมน์ทั้งหมดของฉัน

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

โค้ดด้านบนใช้ไม่ได้ ไม่เปลี่ยนขนาดคอลัมน์ให้พอดีกับข้อความ

UPDATE นักเขียนที่ฉันใช้$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');

คำตอบ:


199

หากคอลัมน์ถูกตั้งค่าเป็น AutoSize PHPExcel จะพยายามคำนวณความกว้างของคอลัมน์ตามค่าที่คำนวณได้ของคอลัมน์ (ตามผลลัพธ์ของสูตรใด ๆ ) และอักขระเพิ่มเติมใด ๆ ที่เพิ่มโดยมาสก์รูปแบบเช่นตัวคั่นพัน

ตามค่าเริ่มต้นนี่คือestimatedความกว้าง: มีวิธีการคำนวณที่แม่นยำยิ่งขึ้นโดยใช้ GD ซึ่งสามารถจัดการคุณลักษณะรูปแบบตัวอักษรเช่นตัวหนาและตัวเอียงได้ แต่นี่เป็นค่าใช้จ่ายที่ใหญ่กว่ามากดังนั้นจึงถูกปิดโดยค่าเริ่มต้น คุณสามารถเปิดใช้งานการคำนวณที่แม่นยำยิ่งขึ้นโดยใช้

PHPExcel_Shared_Font::setAutoSizeMethod(PHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT);

อย่างไรก็ตามการปรับขนาดอัตโนมัติใช้ไม่ได้กับรูปแบบ Writer ทั้งหมด ... ตัวอย่างเช่น CSV คุณไม่ได้ระบุว่าคุณใช้นักเขียนคนไหน

แต่คุณต้องระบุคอลัมน์เพื่อตั้งค่ามิติด้วย:

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

$objPHPExcel->getActiveSheet()->getColumnDimension() ต้องการรหัสคอลัมน์

$objPHPExcel->getActiveSheet()->getColumnDimensions()จะส่งคืนอาร์เรย์ของระเบียนมิติคอลัมน์ที่กำหนดไว้ทั้งหมด แต่ถ้าไม่มีการสร้างเร็กคอร์ดมิติข้อมูลอย่างชัดเจน (อาจโดยการโหลดเทมเพลตหรือเรียกด้วยตนเองgetColumnDimension()) จะไม่มีอยู่ (การบันทึกหน่วยความจำ)


ขอบคุณมาก. มันได้ผล. มันไม่คำนวณระยะห่างพิเศษที่สร้างขึ้นจากแบบอักษรตัวหนาแม้ว่าจะคาดหวังไว้ก็ตาม (ฉันเคยอ่านมาแล้ว) คุณช่วยอัปเดตคำตอบเพื่อรวมคำตอบนั้นด้วยได้ไหม
Alkis Kalogeris

1
หากคุณต้องการความแม่นยำระดับนั้นด้วยรูปแบบตัวอักษรเช่นตัวหนาหรือตัวเอียงคุณต้องใช้ PHPExcel_Shared_Font :: AUTOSIZE_METHOD_EXACT แต่ช้ากว่ามาก
Mark Baker

ไม่เป็นไรฉันไม่สนใจ แม้ว่าฉันจะไม่รู้ว่าต้องทำอย่างไร ฉันใช้ 01simple-download-xls.php จากโฟลเดอร์ Test ฉันจะเพิ่มบรรทัดนั้นได้ที่ไหน? ขออภัยสำหรับความไม่สมบูรณ์ของฉัน ฉันเพิ่งเริ่มเล่นกับมัน
Alkis Kalogeris

2
นอกจากนี้หากคุณไม่ต้องการวนซ้ำด้วยตัวอักษรคอลัมน์ แต่สร้างดัชนีแทนคุณสามารถใช้วิธีการแบบคงที่ PHPExcel_Cell :: stringFromColumnIndex ($ columnIndex) เพื่อรับตัวอักษรคอลัมน์
MeatPopsicle

@MarkBaker มีวิธีการใดที่สามารถทำได้กับคำสั่งเดียวเพื่อให้เราสามารถกำหนดความกว้างของคอลัมน์ที่ระบุในรายการ ตอนนี้ฉันใช้ $ activeSheetObj-> getColumnDimension ('G') -> setWidth (35); คอลัมน์ในรายการอาจเป็นลำดับใดก็ได้
Rosa Mystica

55

หากคุณต้องการทำเช่นนั้นในหลายแผ่นงานและหลายคอลัมน์ในแต่ละแผ่นงานต่อไปนี้เป็นวิธีที่คุณจะวนซ้ำได้ทั้งหมด:

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

2
ฉันสามารถยืนยันได้ว่าคำตอบนี้ใช้งานได้อย่างไม่มีที่ติใน PhpSpreadSheet เช่นกัน ขอบคุณมาก!
Hissvard

ใช้$worksheet->getColumnIterator()เพื่อลดความซับซ้อนของสิ่งต่างๆที่นี่ อ้างถึงคำตอบของฉัน
BARNZ

25

นี่คือตัวแปรที่ยืดหยุ่นมากขึ้นตามโพสต์ของ @Mark Baker:

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

หวังว่านี่จะช่วยได้;)


14
สิ่งนี้ใช้ได้จนถึง Z เท่านั้นเพราะrange('A', 'AB')จะส่งคืนรายการชื่อ 'A' เพียงรายการเดียว ดังนั้นการใช้range()ในกรณีนี้จึงไม่ใช่ความคิดที่ดี!
Michael

7
วิธีนี้ใช้ได้ผล: for ($ i = 'A'; $ i! = $ phpExcelObject-> getActiveSheet () -> getHighestColumn (); $ i ++) {$ worksheet-> getColumnDimension ($ i) -> setAutoSize (TRUE); }
นาธาน

อย่าใช้สิ่งนี้ โปรดดูคำตอบของฉันที่ใช้$sheet->getColumnIterator()
BARNZ

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

3
คำตอบที่ดี แต่ควรเป็น$i <= $objPHPExcel->getActiveSheet()->getHighestColumn()คอลัมน์สุดท้ายไม่ได้ขนาด
billynoah

10

นี่คือตัวอย่างวิธีใช้คอลัมน์ทั้งหมดจากแผ่นงาน:

$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
โปรดเพิ่มบริบทรอบ ๆ คำตอบของคุณเพื่ออธิบายวิธีแก้ปัญหา
Andrew Stubbs

7

สำหรับ phps Spreadsheet:

$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
@WesleyAbbenhu ความคิดเห็นของคุณจะใช้ได้ก็ต่อเมื่อมีคอลัมน์ไม่เกิน 26 คอลัมน์ เมื่อคอลัมน์สูงสุดเป็นตัวอย่าง: "AH" ฟังก์ชัน range จะทำงานไม่ถูกต้อง
Sander Van Keer

6

ข้อมูลโค้ดนี้จะปรับขนาดคอลัมน์ทั้งหมดที่มีข้อมูลในแผ่นงานทั้งหมดโดยอัตโนมัติ ไม่จำเป็นต้องใช้ getter และ 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);
    }
}

3

เผื่อว่ามีใครกำลังมองหาอยู่

ความละเอียดด้านล่างยังใช้งานได้กับPHPSpreadsheetPHPExcel เวอร์ชันใหม่

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

หมายเหตุ: getHighestColumn()สามารถแทนที่ด้วยgetHighestDataColumn()หรือคอลัมน์สุดท้ายจริง

วิธีการเหล่านี้ใช้ทำอะไร:

getHighestColumn($row = null) - รับคอลัมน์แผ่นงานสูงสุด

getHighestDataColumn($row = null) - รับคอลัมน์แผ่นงานสูงสุดที่มีข้อมูล

getHighestRow($column = null) - รับแถวแผ่นงานสูงสุด

getHighestDataRow($column = null) - รับแถวแผ่นงานสูงสุดที่มีข้อมูล



2

หากคุณพยายามที่จะวนซ้ำfor ($col = 2; $col <= 'AC'; ++ $col){...}หรือด้วยforeach(range('A','AC') as $col) {...}มันจะใช้ได้กับคอลัมน์จาก A ถึง Z แต่ไม่สามารถส่งผ่าน Z (เช่นวนซ้ำระหว่าง 'A' ถึง 'AC')

ในการวนซ้ำ 'Z' คุณต้องแปลงคอลัมน์เป็นจำนวนเต็มเพิ่มขึ้นเปรียบเทียบและทำให้เป็นสตริงอีกครั้ง:

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

ด้วยวิธีนี้คุณจะวนซ้ำได้อย่างง่ายดายผ่านคอลัมน์ 'Z' และตั้งค่าอัตโนมัติให้กับทุกคอลัมน์


1

มาช้า แต่หลังจากค้นหาทุกที่ฉันได้สร้างโซลูชันที่ดูเหมือนจะเป็น "หนึ่งเดียว"

เป็นที่ทราบกันดีว่ามีตัววนซ้ำคอลัมน์ใน API เวอร์ชันล่าสุด แต่ไม่รู้วิธีการปรับอ็อบเจ็กต์คอลัมน์ด้วยตัวเองโดยพื้นฐานแล้วฉันได้สร้างลูปเพื่อเปลี่ยนจากคอลัมน์ที่ใช้ครั้งแรกจริงไปจนถึงคอลัมน์ที่ใช้จริงล่าสุด

นี่คือ:

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

คำตอบทั้งหมดนี้ค่อนข้างห่วย ... อย่าใช้ range () มันจะไม่ทำงานเกินคอลัมน์ Z

เพียงใช้:

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

ทำสิ่งนี้หลังจากที่คุณเขียนข้อมูลแล้วเพื่อให้ตัววนซ้ำคอลัมน์รู้จำนวนคอลัมน์ที่ต้องวนซ้ำ


0

คุณต้องระบุคอลัมน์เพื่อตั้งค่ามิติ:

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
โปรดจัดรูปแบบคำตอบของคุณใหม่และคิดเกี่ยวกับสิ่งนี้: คำตอบที่ดีจะมีคำอธิบายเกี่ยวกับสิ่งที่ทำและสาเหตุที่ทำในลักษณะดังกล่าวไม่ใช่เฉพาะสำหรับ OP เท่านั้น แต่สำหรับผู้เยี่ยมชม SO ในอนาคต
B001 ᛦ

0

สำหรับ Spreedsheet + PHP 7 คุณต้องเขียนแทนไฟล์ PHPExcel_Cell::columnIndexFromString , \PhpOffice\PhpSpreadsheet\Cell::columnIndexFromString. และในวงที่เป็นความผิดพลาดนั้นคุณจะต้องไม่ทำงานกับ< <=มิฉะนั้นเขาใช้คอลัมน์มากเกินไปในลูป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.