Apache POI Excel - จะกำหนดค่าคอลัมน์ที่จะขยายได้อย่างไร?


102

ฉันใช้Apache POI APIสร้างexcel spreadsheetเพื่อส่งออกข้อมูลบางอย่าง

ปัญหาที่ฉันพบคือเมื่อสร้างและเปิดสเปรดชีตคอลัมน์จะไม่ขยายทำให้ข้อความยาว ๆ เช่นข้อความที่จัดรูปแบบวันที่ไม่ปรากฏขึ้นในครั้งแรก

ฉันสามารถดับเบิลคลิกที่ขอบคอลัมน์ใน excel เพื่อขยายหรือลากเส้นขอบเพื่อปรับความกว้างของคอลัมน์ แต่อาจมีมากกว่า 20 คอลัมน์และไม่มีวิธีใดที่ฉันต้องการทำด้วยตนเองทุกครั้งที่เปิดสเปรดชีต :(

ฉันพบ (แม้ว่าอาจจะผิดวิธี) groupRow()และsetColumnGroupCollapsed()อาจสามารถทำเคล็ดลับได้ แต่ไม่มีโชค บางทีฉันใช้มันในทางที่ผิด

ตัวอย่างข้อมูลโค้ด

        Workbook wb = new HSSFWorkbook();
        CreationHelper createHelper = wb.getCreationHelper();
        //create sheet
        Sheet sheet = wb.createSheet("masatoSheet");

        //not really working yet.... :(
        //set group for expand/collapse
        //sheet.groupRow(0, 10); //just random fromRow toRow argument values...
        //sheet.setColumnGroupCollapsed(0, true);

        //create row
        Row row = sheet.createRow((short)0);
        //put a cell in the row and store long text data
        row.createCell(0).setCellValue("Loooooooong text not to show up first");

เมื่อสร้างสเปรดชีตนี้สตริง "Looooooong text not to show up first" จะอยู่ในเซลล์ แต่เนื่องจากคอลัมน์ไม่ได้ถูกขยายเพียง แต่ "Loooooooo" เท่านั้นที่จะปรากฏขึ้น

ฉันจะกำหนดค่าได้อย่างไรเมื่อฉันเปิดสเปรดชีตคอลัมน์จะขยายแล้ว ???



ดูเหมือนคุณกำลังมองหาวิธีใช้ POI เพื่อทำสิ่งนี้ให้สำเร็จ แต่ทำได้ง่ายๆใน Excel ให้เลือกทั้งแผ่นและดับเบิลคลิกที่ขอบเขตส่วนหัวคอลัมน์ AB หากคุณจำเป็นต้องทำเช่นนี้กับหลาย ๆ แผ่นโซลูชันที่เข้ารหัสอาจให้บริการคุณได้ดีกว่า
เฉลี่ย

คำตอบ:


178

หลังจากที่คุณเพิ่มข้อมูลทั้งหมดของคุณลงในแผ่นงานแล้วคุณสามารถเรียกautoSizeColumn(int column)ใช้แผ่นงานของคุณเพื่อปรับคอลัมน์ให้มีขนาดที่เหมาะสมโดยอัตโนมัติ

นี่คือการเชื่อมโยงไปAPI

ดูโพสต์นี้สำหรับข้อมูลอ้างอิงเพิ่มเติม ปัญหาในการปรับขนาดเซลล์ excel ให้พอดีกับขนาดของเนื้อหาเมื่อใช้ apache poi


8
แค่อยากจะชี้ให้เห็นว่าautoSizeColumnไม่ได้ระดับดีและจะเป็นซุปเปอร์ช้าหากคุณมีจำนวนมากแถว ฉันต้องแฮ็คเล็กน้อยและทำสิ่งที่คล้ายกับที่แนะนำในคำถามนี้
lbstr

9
คำเตือนเกี่ยวกับ autoSizeColumnต้องใช้แบบอักษร java นี่ไม่ใช่ส่วนหนึ่งของ java jre headless ที่ใช้บนเซิร์ฟเวอร์และจะส่ง NullPointerException
Stephen Dillon

@StephenDillon มีความคิดอย่างไรในการแก้ไขตัวชี้ค่าว่างสำหรับการกำหนดค่าแบบอักษร?
Veeshal

วิธีที่ดีที่สุดที่เราพบคือการวนซ้ำแต่ละแถวใน col ค้นหาความยาวถ่านที่ยาวที่สุดแล้วคูณด้วย x + เพิ่มบัฟเฟอร์ X ใช้การลองผิดลองถูกเพื่อดูว่าอะไรเหมาะสม แต่ควรมีความกว้างเฉลี่ยของถ่าน หากไม่มีแบบอักษรฉันไม่เชื่อว่าคุณจะทำให้ถูกต้องได้จริง แต่เราก็เข้าใกล้ได้ดี มิฉะนั้นคุณสามารถเพิ่มมาโครลงใน excel เพื่อแก้ไขได้ในครั้งแรกที่ผู้ใช้เปิดขึ้นมานั่นเป็นวิธีที่ดีที่สุด แต่ต้องเปิดใช้งานมาโคร
Stephen Dillon

47

เคล็ดลับ:ในการทำให้ขนาดอัตโนมัติทำงานsheet.autoSizeColumn(columnNumber)ควรทำการโทรหลังจากเติมข้อมูลลงใน excel

การเรียกใช้เมธอดก่อนเติมข้อมูลจะไม่มีผล


stackoverflow.com/questions/37069820/…บางครั้งก็ไม่ทำงาน
user7856586

คำตอบที่ให้ไว้ที่นี่เกี่ยวข้องกับ Java ในขณะที่ลิงก์ที่ให้ไว้ในความคิดเห็นนั้นเกี่ยวข้องกับ Android คำตอบยังคงใช้ได้กับ Java ทุกกรณี (ยกเว้น java JRE ที่ไม่มีหัวซึ่งไม่มีแบบอักษร java)
Unni Kris

ขอบคุณฉันคำนวณ func และใช้ setColumnWidth ด้วยวิธีต่อไปนี้: (5 until row.lastCellNum).forEach { colNum -> val columnWidth = (row.getCell(colNum).toString().length * 0.44 + 2.24) * 768 reportSheet.setColumnWidth(colNum, columnWidth.toInt()) }
user7856586

@ user7856586 คุณสามารถอธิบายวิธีการนี้ให้ละเอียดมากขึ้นสำหรับฉันได้ไหม
Mehroz Mustafa

40

หากคุณต้องการปรับขนาดคอลัมน์ทั้งหมดในสมุดงานโดยอัตโนมัตินี่คือวิธีการที่อาจเป็นประโยชน์:

public void autoSizeColumns(Workbook workbook) {
    int numberOfSheets = workbook.getNumberOfSheets();
    for (int i = 0; i < numberOfSheets; i++) {
        Sheet sheet = workbook.getSheetAt(i);
        if (sheet.getPhysicalNumberOfRows() > 0) {
            Row row = sheet.getRow(sheet.getFirstRowNum());
            Iterator<Cell> cellIterator = row.cellIterator();
            while (cellIterator.hasNext()) {
                Cell cell = cellIterator.next();
                int columnIndex = cell.getColumnIndex();
                sheet.autoSizeColumn(columnIndex);
            }
        }
    }
}

ฉันได้รับNullPointerExceptionที่row.cellIterator(). เป็นเพราะฉันไม่มีค่าในเซลล์ใดเซลล์หนึ่ง?
rakeeee

10

คุณสามารถลองสิ่งนี้:

HSSFSheet summarySheet = wb.createSheet();
summarySheet.setColumnWidth(short column, short width);

พารามิเตอร์ต่อไปนี้คือ: หมายเลขคอลัมน์ในแผ่นงานและความกว้าง แต่หน่วยของความกว้างค่อนข้างเล็กคุณสามารถลอง 4000 ตัวอย่างเช่น


ขอบคุณที่รู้จัก! ฉันคิดว่าสำหรับจุดประสงค์ของฉันที่สตริงคอลัมน์อาจถูกสร้างขึ้นแบบไดนามิกวิธีการปรับขนาดอัตโนมัติจะเหมาะกับกรณีนี้
Meow


5

โค้ดตัวอย่างด้านล่าง

HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet("your sheet name");
HSSFRow row = sheet.createRow(0);

cell = row.createCell(0);
cell.setCellValue("A BIG NAME WITH AUTO SIZE FEATURE ENABLED");

// นี่สำคัญมาก

sheet.autoSizeColumn(0);

// อาร์กิวเมนต์ต้องเป็นหมายเลขเซลล์

cell = row.createCell(1);
cell.setCellValue("a big name without auto size feature enabled");

ตรวจสอบผลลัพธ์และถั่ว :)


2
sheet.setColumnWidth (columnIndex, width) ก็เป็นวิธีที่คุณอยากดูเช่นกัน
Mateen

3

หากคุณทราบจำนวนคอลัมน์ของคุณ (เท่ากับรายการคอลเล็กชัน) คุณสามารถใช้ซับนี้เพื่อปรับคอลัมน์ทั้งหมดของแผ่นงานเดียว (ถ้าคุณใช้ java 8 เป็นอย่างน้อย):

IntStream.range(0, columnCount).forEach((columnIndex) -> sheet.autoSizeColumn(columnIndex));

1

ฉันใช้วิธีง่ายๆด้านล่าง:

นี่คือสมุดงานและแผ่นงานของคุณ:

XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("YOUR Workshhet");

จากนั้นเพิ่มข้อมูลลงในแผ่นงานของคุณด้วยคอลัมน์และแถว เมื่อเพิ่มข้อมูลลงในแผ่นงานเสร็จแล้วให้เขียนโค้ดตามautoSizeColumnความกว้าง

for (int columnIndex = 0; columnIndex < 15; columnIndex++) {
                    sheet.autoSizeColumn(columnIndex);
                }

ที่นี่ 15 แทนให้คุณเพิ่มจำนวนคอลัมน์ในแผ่นงานของคุณ

หวังว่าจะมีคนช่วยเรื่องนี้




0

คุณสามารถตัดข้อความได้เช่นกัน รหัสตัวอย่าง PFB:

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